Math 在三维空间中映射两个三角形之间的点

Math 在三维空间中映射两个三角形之间的点,math,geometry,computational-geometry,Math,Geometry,Computational Geometry,编辑 我不知道这是否重要,但目标三角形角度可能与源三角形角度不同。这一事实是否使变换成为非仿射的?(我不确定) 我在三维空间中有两个三角形。假设我知道第一个三角形中点的(x,y,z)和向量V1,V2,V3。我需要找到点(x',y',z')。我应该用向量V1,V2,V3对点(x,y,z)做什么变换才能得到第二个三角形中的变换点 谢谢你的帮助 只需将向量添加到每个点。点+向量==新点。这基本上与首先创建向量相反:V1==(x1'-x1,y1'-y1,z1'-z1),所以(x1',y1',z1')=

编辑

我不知道这是否重要,但目标三角形角度可能与源三角形角度不同。这一事实是否使变换成为非仿射的?(我不确定)

我在三维空间中有两个三角形。假设我知道第一个三角形中点的(x,y,z)和向量V1,V2,V3。我需要找到点(x',y',z')。我应该用向量V1,V2,V3对点(x,y,z)做什么变换才能得到第二个三角形中的变换点


谢谢你的帮助

只需将向量添加到每个点。点+向量==新点。这基本上与首先创建向量相反:V1==(x1'-x1,y1'-y1,z1'-z1),所以(x1',y1',z1')==(x1+V1x,y1+v1y,z1+V1z)。

 x = αx1 + βx2 + γx3 
然后 x'=αx1'+βx2'+γx3' 所以


简单的回答是,这比最初看起来更复杂,而且您对问题施加的约束的性质需要一些比您想象的更先进的技术

作为一种解释,我要稍微改变一下你的符号。考虑3对向量(这些对应于你的问题中的两个三角形的顶点):

并使用Steve Emmerson建议的方法(在4-D而不是3-D中):

AM=M' AMM-1=M'M-1
A=M'M-1需要矩阵变换T,使得T X=X',其中X是矩阵,其列是第一个三角形顶点的坐标,X'对于第二个三角形是相同的。每边乘以X的倒数得到T=X'X-1。

我想你可能在寻找重心坐标?

检查And的理论注释

//Qt代码

QMatrix4x4 m;
QMatrix4x4 t1;
QMatrix4x4 t2;

QVector3D v1(0,0,0);
QVector3D v2(0,1,0);
QVector3D v3(1,0,0);
QVector3D v4 = v1 + QVector3D::crossProduct(v2-v1, v3-v1);

QVector3D v1p(0,0,2);
QVector3D v2p(0,3,2);
QVector3D v3p(1,0,1);
QVector3D v4p = v1p + QVector3D::crossProduct(v2p-v1p, v3p-v1p);

t1.setColumn(0, QVector4D(v1, 1));
t1.setColumn(1, QVector4D(v2, 1));
t1.setColumn(2, QVector4D(v3, 1));
t1.setColumn(3, QVector4D(v4, 1));

t2.setColumn(0, QVector4D(v1p, 1));
t2.setColumn(1, QVector4D(v2p, 1));
t2.setColumn(2, QVector4D(v3p, 1));
t2.setColumn(3, QVector4D(v4p, 1));

m = t2 * t1.inverted();

for(float i=0.0; i<2.5; i+=0.05)
{
    QVector4D p(0.2+i,i,0,1);
    QVector4D pp( m * p );

    glBegin(GL_LINE_STRIP);
    glColor4f(1,1,1,1);
    glVertex3d(p.x(), p.y(), p.z());

    glColor4f(1,0,1,1);
    glVertex3d(pp.x(), pp.y(), pp.z());
    glEnd();
}
qmatrix4x4m;
qmatrix4x4t1;
qmatrix4x4t2;
QVector3D-v1(0,0,0);
QVector3D-v2(0,1,0);
QVector3D-v3(1,0,0);
QVector3D v4=v1+QVector3D::叉积(v2-v1,v3-v1);
QVector3D-v1p(0,0,2);
qvector3dv2p(0,3,2);
qvector3dv3p(1,0,1);
QVector3D v4p=v1p+QVector3D::叉积(v2p-v1p,v3p-v1p);
t1.设置列(0,QVector4D(v1,1));
t1.设置列(1,QVector4D(v2,1));
t1.设置列(2,QVector4D(v3,1));
t1.设置列(3,QVector4D(v4,1));
t2.设置列(0,QVector4D(v1p,1));
t2.设置列(1,QVector4D(v2p,1));
t2.设置柱(2,QVector4D(v3p,1));
t2.设置柱(3,QVector4D(v4p,1));
m=t2*t1.倒置();

对于(float i=0.0;我不认为这回答了问题。我认为OP意味着(x,y,z)是三角形中的任意点。是的,我也觉得这不是解决方案,因为点应该受到所有三个向量V1,V2,V3的影响(因为所有顶点都会改变),不仅仅是一个V1。这是我最初的想法,但当我看到它时,很明显,所提出的问题是欠约束的。我相信,一旦包含了距离约束,唯一的解决方案是可能的,但找到唯一的解决方案需要凸规划,无法使用您概述的线性方法来解决.@AND矩阵变换将所有三个顶点转换为对应的顶点。这也是一种线性变换;因此,第一个三角形内部的任何点都将以与顶点保持比例距离的方式转换为第二个三角形的内部。假设原点是三角形内部的一个点第一个三角形,但它不是第二个三角形内部的点。使用线性变换不能发生这种情况;原点始终映射到原点。如上所述的问题需要仿射(反之为线性)变换,以便域中的原点可以映射到范围中原点以外的其他对象。@and您是对的。我的答案中的X和X'应该由每个三角形的质心(COM)到顶点的向量构成。变换三角形1中的一个点,则包括1)减去第一个三角形的COM;2) 应用T;3)将位移向量从三角形1 COM添加到三角形2 COM。这是一个三维线性变换。这个问题需要三维仿射变换,我不太明白。你的意思是:x'=α(x1+V1.x)+β(x2+V2.x)+γ(x3+V3.x)??还有如何计算α,β,γ?+1是的。在源三角上找到一个点的重心坐标,然后在目标三角上找到这些重心坐标。仿射变换允许平移,因此你提出的角度问题本身并不是一个玩家。线性变换可用于更改三角形的形状、大小和方向,而不会产生任何实际问题。当生成的线性变换将对象放置在向量空间中的错误位置并且需要重新定位时,需要仿射变换。我已经更新了我的答案,允许在不应用任何先进技术的情况下找到解决方案。感谢对问题的深入分析。回答得很好。当我找到你的帖子时,我被困在了有9个等式和12个未知数的地方。我在这里有个问题:为什么y和y'用作第四点?我的意思是,它不是一个独立的,同样好的,你可以使用三角形的中心点y=mean(x,y,z)(好吧,好吧,也许你不能,但我不明白为什么叉积更好)你可以使用任何与三角形的支腿线性无关的向量。y和y'是其他支腿的叉积,满足该约束,本质上创建了一个单纯形。使用平均值会创建一个线性相关向量,因此M不会有一个逆。 u = <u0, u1, u2, 1> u' = <u0', u1', u2', 1> v = <v0, v1, v2, 1> v' = <v0', v1', v2', 1> w = <w0, w1, w2, 1> w' = <w0', w1', w2', 1> |a0,0 a0,1 a0,2 a0,3| A = |a1,0 a1,1 a1,2 a1,3| |a2,0 a2,1 a2,2 a2,3| |0 0 0 1 | Au = u' Av = v' Aw = w' p = <p0, p1, p2, 1> Ap = p' = <p0', p1', p2', 1> |u - p| |u' - p'| ------- = --------- |u - a| |u' - Aa| |v - p| |v' - p'| ------- = --------- |v - b| |v' - Ab| |w - p| |w' - p'| ------- = --------- |w - c| |w' - Ac| y = u + (v-u)×(w-u) y' = u' + (v'-u')×(w'-u') M = <u, v, w, y> M' = <u', v', w', y'> AM = M' AMM-1 = M'M-1 A = M'M-1
QMatrix4x4 m;
QMatrix4x4 t1;
QMatrix4x4 t2;

QVector3D v1(0,0,0);
QVector3D v2(0,1,0);
QVector3D v3(1,0,0);
QVector3D v4 = v1 + QVector3D::crossProduct(v2-v1, v3-v1);

QVector3D v1p(0,0,2);
QVector3D v2p(0,3,2);
QVector3D v3p(1,0,1);
QVector3D v4p = v1p + QVector3D::crossProduct(v2p-v1p, v3p-v1p);

t1.setColumn(0, QVector4D(v1, 1));
t1.setColumn(1, QVector4D(v2, 1));
t1.setColumn(2, QVector4D(v3, 1));
t1.setColumn(3, QVector4D(v4, 1));

t2.setColumn(0, QVector4D(v1p, 1));
t2.setColumn(1, QVector4D(v2p, 1));
t2.setColumn(2, QVector4D(v3p, 1));
t2.setColumn(3, QVector4D(v4p, 1));

m = t2 * t1.inverted();

for(float i=0.0; i<2.5; i+=0.05)
{
    QVector4D p(0.2+i,i,0,1);
    QVector4D pp( m * p );

    glBegin(GL_LINE_STRIP);
    glColor4f(1,1,1,1);
    glVertex3d(p.x(), p.y(), p.z());

    glColor4f(1,0,1,1);
    glVertex3d(pp.x(), pp.y(), pp.z());
    glEnd();
}