我在空间中取了一个给定的矩形(a face4)。face4 可以在空间中的任何角度/位置。
我正在它的质心处创建一个圆环。
然后,我尝试将我的环面与以下标准对齐:
1) 平面将圆环水平二等分(使平面两侧出现半圆)
2)环面垂直于平面
3)圆环与矩形面的两个(“较短”)边的中点对齐,因此圆环将矩形/面的“较长”边一分为二。
例如,它看起来像这样:
我觉得我需要为此做两个不同的轴旋转。一个使其与脸部对齐,另一个使其垂直。
现在,我只是在尝试第一部分(将它与 face4 对齐,而不是担心垂直),我正在这样做:
1)从人脸计算两组向量的两个中点
2)通过从另一个中点减去一个中点来确定结束圆环轴以获得我的轴。
3)通过做#2和起始圆环的(0,1,0)轴的叉积来找到旋转轴
4) 用 Math.cos( endAxis.dot (rotationAxis)) 求旋转角度
5) 旋转环面
6)翻译它
不幸的是,它并没有像我希望看到的图片那样“对齐”这两点)。
我正在尝试不同的方法(每次我尝试新的东西时反转 theta 等),但它仍然没有像我预期的那样表现。我的方法或想法有问题吗?
我正在使用的代码如下。(我故意把它写成很长的形式,有很多评论来帮助我思考)。
this.createTorus = function (tubeMeshParams) {
var torusRadius = 5;
var torus = new THREE.TorusGeometry( torusRadius, 1.5, segments/10, 50 );
fIndex = this.calculateFaceIndex();
//Determine midpoint of line AB on Face
var v1 = geometry.vertices[geometry.faces[fIndex].a];
var v2 = geometry.vertices[geometry.faces[fIndex].b];
var xMidAB = (v1.x + v2.x) / 2;
var yMidAB = (v1.y + v2.y) / 2;
var zMidAB = (v1.z + v2.z) / 2;
var midpointAB = new THREE.Vector3( xMidAB, yMidAB, zMidAB);
//Determine midpoint of line CD on Face
var v3 = geometry.vertices[geometry.faces[fIndex].c];
var v4 = geometry.vertices[geometry.faces[fIndex].d];
var xMidCD = (v3.x + v4.x) / 2;
var yMidCD = (v3.y + v4.y) / 2;
var zMidCD = (v3.z + v4.z) / 2;
var midpointCD = new THREE.Vector3( xMidCD, yMidCD, zMidCD);
//Determine Ending Torus axis
var endTorusAxis = new THREE.Vector3();
endTorusAxis.subVectors( midpointCD, midpointAB );
endTorusAxis.normalize();
//Direction vector of Torus (Y = 1)
var torusAxis = new THREE.Vector3( 0, 1, 0);
//Find the axis of rotation through Cross Product
var rotationAxis = new THREE.Vector3();
rotationAxis.crossVectors( endTorusAxis, torusAxis );
if ( rotationAxis.length() == 0) // Acounting for special case where the axis are aligned
{
rotationAxis.set( 1, 0, 0);
}
rotationAxis.normalize();
//Now that we have the needed data, determine angle of rotation
var theta = Math.acos( endTorusAxis.dot( rotationAxis ));
theta = -theta;
//Don't use position, rotate, scale
torus.matrixAutoUpdate = false;
//Rotate it
torus.applyMatrix(new THREE.Matrix4().makeRotationAxis( rotationAxis, theta));
// Create mesh and scale
torusLoop = new THREE.Mesh(torus, this.m);
torusLoop.scale.x = torusLoop.scale.y = torusLoop.scale.z = tubeMeshParams['Scale'];
//Determine Face centroid positions
var cenPosX = geometry.faces[fIndex].centroid.x;
var cenPosY = geometry.faces[fIndex].centroid.y;
var cenPosZ = geometry.faces[fIndex].centroid.z;
//Move the rotated torus around the centroid
torusLoop.geometry.applyMatrix(new THREE.Matrix4().makeTranslation(cenPosX, cenPosY, cenPosZ));
torusLoop.geometry.computeCentroids();
torusLoop.geometry.computeFaceNormals();
torusLoop.geometry.computeVertexNormals();
return torusLoop;
}