2013-07-24 153 views
2

我正在使用threejs,并且通过两组THREE.Vector3的4个顶点定义了2个矩形。计算来自2组点的仿射变换

如何计算将第一个矩形转换为第二个矩形的仿射变换?

我想通过.applyMatrix(matrix)将计算的仿射变换应用到第3个矩形。

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平面上? (V1,V2,V3)到(V1',V2')的变换矢量巴兹坐标中的坐标,如果它是真的,那么变换的矩形将与第二个矩形位于同一平面, ,V3')。 Let's vector A = V2-V1, B = V3-V1, A' = V2'-V1', B' = V3'-V1'。 XY平面上的每个点P(例如第三个矩形顶点)是线性组合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

我已经更新了我想要实现的草图的问题。至少在这种情况下,应该有唯一的仿射变换M.第一个矩形位于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

编辑:哎呀,我还以为这张贴作为评论。它成了一个答案。哦,好吧..