2013-06-27 4 views
1

Это большая для любителей математики и 3D-геометрии. Заранее спасибо.Math Help: 3d Modeling/Three.js - динамическая динамическая динамика

Обзор

У меня есть рисунок, созданный путем выдавливания граней вокруг скручивания сплайн кривых в пространстве. Я пытаюсь поместить «цикл» (тор), ориентированный по пути сплайна в данном сегменте кривой, так что он «выровнен» с сплайном. Под этим я подразумеваю, что ширина тора параллельна траектории сплайна в данном сегменте экструзии, а высота - перпендикулярно выбранной грани (см. Ниже рисунок).

данных Я знаю:

Я дал один из граней фигуры. Из этого я также могу собрать центр тяжести (центральную точку) этого лица, вершины, которые его составляют, окружающие грани и нормальный вектор лица.

ток (Нерабочий) результат решения:

я могу правильно создать цикл тор вокруг центра тяжести лица, которое щелкнули. Однако он не вращается должным образом, чтобы «выровнять» лицо. Посмотрите, как они выглядят немного «выключены» ниже.

Вот картинка с материалом вокруг него:

enter image description here

и вот фотография с ней в каркасном режиме. Вы можете четко видеть сегменты экструзии.

enter image description here

ток (Нерабочий) методология:

Я пытаюсь сделать два расчета. Во-первых, я вычисляю угол между двумя плоскостями (выбранная грань и горизонтальная плоскость в начале координат). Во-вторых, я вычисляю угол между гранью и вертикальной плоскостью в точке начала координат. С этими двумя углами я делаю два поворота - поворот на 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; 
} 

ответ

0

Я обнаружил, что я использовал неправильный подход, чтобы сделать это. Вместо того, чтобы пытаться вычислить каждый угол и сделать RotationX и RotationY, я должен был сделать поворот по оси. Определенно было над этим.

makeRotationAxis(); является функцией, встроенной в three.js.