2013-07-24 3 views
2

Я использую threejs и имеет 2 прямоугольника, определенных двумя наборами THREE.Vector3 с четырьмя вершинами.Вычисление аффинного преобразования из 2-х наборов точек

Как вычислить аффинное преобразование, которое преобразует первый прямоугольник во второй?

Я хочу применить вычисленное аффинное преобразование к третьему прямоугольнику через .applyMatrix(matrix).

enter image description here

Решено:

/** 
* Transform a THREE.CSS3DObject object so that it aligns to a given rectangle. 
* 
* @param object: A THREE.CSS3DObject object. 
* @param v: A list of the 4 vertices of the rectangle (clockwise order) on which to align the object. 
*/ 
function alignObject(object, v) { 

    // width of DOM object wrapped via CSS3DObject 
    var width = parseInt(object.element.style.width, 10); 

    // compute rect vectors from rect vertices 
    var v10 = v[1].clone().sub(v[0]); 
    var v30 = v[3].clone().sub(v[0]); 

    // compute (uniform) scaling 
    var scale = v10.length()/width; 

    // compute translation/new mid-point 
    var position = new THREE.Vector3().addVectors(v10, v30).multiplyScalar(0.5).add(v[0]); 

    // compute rotations 
    var rotX = -v30.angleTo(new THREE.Vector3(0, -1, 0)); 
    // FIXME: rotY, rotZ 

    // apply transformation 
    object.scale.set(scale, scale, scale); 
    object.position = position; 
    object.rotateX(rotX); 
} 

ответ

0

Существует метод расчета аффинной матрицы, например, 2D-случае здесь: Affine transformation algorithm. Но для того, чтобы найти уникальное аффинное преобразование в 3D, вам нужны 4 некомпланарных точки (то же самое верно для 2d - 3 неколлинеарных точек). M для 4 копланарных точек (ваши прямоугольные вершины) является сингулярным, не имеет обратной матрицы, и вышеупомянутый метод неприменим.

Пример двусмысленности для случая 2d: точки B, C, D являются коллинеарными. Некоторая аффинная трансформация перемещает их в точки B, E, F. Но существует бесконечное число совпадающих аффинных преобразований. Два из них переводят точку на точки G или H.

enter image description here

Некоторые решение существует для ограниченного класса аффинного преобразования. Например, твой третий прямоугольник всегда находится в плоскости XY? Если это правда, то преобразованный прямоугольник будет находиться в той же плоскости, что и 2-й прямоугольник, и ваша задача станет проще - вам нужно вывести координаты в измененном векторе bazis из (V1, V2, V3) в (V1 ', V2' , V3 '). Let's vector A = V2-V1, B = V3-V1, A' = V2'-V1', B' = V3'-V1'. Каждая точка P в плоскости XY (например, третья прямоугольная вершина) представляет собой линейную комбинацию P = V1 + t * A + u * B, и она преобразуется в новую плоскость P' = V1' + t * A' + u * B '. В этом случае нетрудно найти коэффициенты t, u: t=(P.x - V1.x)/(V2.x-V1.x) u=(P.y - V1.y)/(V2.y-V1.y)

+1

Я обновил вопрос с помощью эскиза того, чего я пытаюсь достичь. По крайней мере в этой ситуации должно существовать уникальное аффинное преобразование М. Первый прямоугольник находится в плоскости XY, в середине точки в начале, оси, параллельной X/Y. Второй прямоугольник равномерно масштабируется, но произвольно переводится и поворачивается. Есть ли закрытое решение для этого случая? – oberstet

+0

@oberstet Отредактировано с некоторыми допущениями – MBo

+0

Спасибо за ваш ответ. Да, меняя векторную основу. Но мне понадобилось фактическое преобразование M для использования с тремя. Тем временем я понял это (см. Обновленный вопрос). Спасибо, в любом случае! – oberstet

1

Я ищу то же самое. Найдено: https://github.com/epistemex/transformation-matrix-js

Не пробовал, но функция fromTriangles() выглядит многообещающей.

Matrix.fromTriangles(t1, t2); // returns matrix needed to produce t2 from t1

Edit: упс, подумал я отправил это как комментарий. Это стало ответом. О хорошо ..

Смежные вопросы