Это большая для любителей математики и 3D-геометрии. Заранее спасибо.Math Help: 3d Modeling/Three.js - динамическая динамическая динамика
Обзор
У меня есть рисунок, созданный путем выдавливания граней вокруг скручивания сплайн кривых в пространстве. Я пытаюсь поместить «цикл» (тор), ориентированный по пути сплайна в данном сегменте кривой, так что он «выровнен» с сплайном. Под этим я подразумеваю, что ширина тора параллельна траектории сплайна в данном сегменте экструзии, а высота - перпендикулярно выбранной грани (см. Ниже рисунок).
данных Я знаю:
Я дал один из граней фигуры. Из этого я также могу собрать центр тяжести (центральную точку) этого лица, вершины, которые его составляют, окружающие грани и нормальный вектор лица.
ток (Нерабочий) результат решения:
я могу правильно создать цикл тор вокруг центра тяжести лица, которое щелкнули. Однако он не вращается должным образом, чтобы «выровнять» лицо. Посмотрите, как они выглядят немного «выключены» ниже.
Вот картинка с материалом вокруг него:
и вот фотография с ней в каркасном режиме. Вы можете четко видеть сегменты экструзии.
ток (Нерабочий) методология:
Я пытаюсь сделать два расчета. Во-первых, я вычисляю угол между двумя плоскостями (выбранная грань и горизонтальная плоскость в начале координат). Во-вторых, я вычисляю угол между гранью и вертикальной плоскостью в точке начала координат. С этими двумя углами я делаю два поворота - поворот на X и Y на торе, и я надеюсь, что это будет правильная ориентация. Он вращает тор в переменной величине, но не там, где я хочу.
Формула:
При этом выше, я использую следующий для вычисления угла между двумя плоскостями, используя их нормальные векторы:
скалярного произведения вектора нормаль 1 и вектора нормали 2 = Величина вектора 1 * Величина вектора 2 * Cos (тета)
Или:
(n1) (n2) = || n1 || * || n2 || * Соз (тета)
Или:
Угол = ArcCos {(n1 * n2)/(n1 || || * || п2 ||)}
Для того, чтобы определить величину вектора , формула:
Квадратный корень из суммы компонентов в квадрате.
Или:
Sqrt {n1.x^2 + n1.y^2 + n1.z^2}
Кроме того, я использую следующие для нормальных векторов «происхождения "самолеты:
Нормальный вектор горизонтальной плоскости: (1, 0, 0)
Нормальный вектор вертикальной плоскости: (0, 1, 0)
Я продумал выше нормальных векторов пару раз ... и я думаю (?) они правы?
Текущая реализация:
Ниже приведен код, который я сейчас использую для его реализации. Любые мысли были бы очень оценены. У меня есть ощущение, что я ошибаюсь, пытаясь вычислить углы между самолетами. Любые советы/идеи/предложения будут высоко оценены. Заранее благодарю вас за любые предложения.
Функции для расчета углов:
this.toRadians = function (face, isX)
{
//Normal of the face
var n1 = face.normal;
//Normal of the vertical plane
if (isX)
var n2 = new THREE.Vector3(1, 0, 0); // Vector normal for vertical plane. Use for Y rotation.
else
var n2 = new THREE.Vector3(0, 1, 0); // Vector normal for horizontal plane. Use for X rotation.
//Equation to find the cosin of the angle. (n1)(n2) = ||n1|| * ||n2|| (cos theta)
//Find the dot product of n1 and n2.
var dotProduct = (n1.x * n2.x) + (n1.y * n2.y) + (n1.z * n2.z);
// Calculate the magnitude of each vector
var mag1 = Math.sqrt (Math.pow(n1.x, 2) + Math.pow(n1.y, 2) + Math.pow(n1.z, 2));
var mag2 = Math.sqrt (Math.pow(n2.x, 2) + Math.pow(n2.y, 2) + Math.pow(n2.z, 2));
//Calculate the angle of the two planes. Returns value in radians.
var a = (dotProduct)/(mag1 * mag2);
var result = Math.acos(a);
return result;
}
Функции для создания и повернуть петлю торы:
this.createTorus = function (tubeMeshParams)
{
var torus = new THREE.TorusGeometry(5, 1.5, segments/10, 50);
fIndex = this.calculateFaceIndex();
//run the equation twice to calculate the angles
var xRadian = this.toRadians(geometry.faces[fIndex], false);
var yRadian = this.toRadians(geometry.faces[fIndex], true);
//Rotate the Torus
torus.applyMatrix(new THREE.Matrix4().makeRotationX(xRadian));
torus.applyMatrix(new THREE.Matrix4().makeRotationY(yRadian));
torusLoop = new THREE.Mesh(torus, this.m);
torusLoop.scale.x = torusLoop.scale.y = torusLoop.scale.z = tubeMeshParams['Scale'];
//Create the torus around the centroid
posx = geometry.faces[fIndex].centroid.x;
posy = geometry.faces[fIndex].centroid.y;
posz = geometry.faces[fIndex].centroid.z;
torusLoop.geometry.applyMatrix(new THREE.Matrix4().makeTranslation(posx, posy, posz));
torusLoop.geometry.computeCentroids();
torusLoop.geometry.computeFaceNormals();
torusLoop.geometry.computeVertexNormals();
return torusLoop;
}