在3D空间中的两个三角形之间的地图点

时间:2010-09-23 16:28:09

标签: math geometry computational-geometry

修改

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

alt text

我在3D空间中有两个三角形。鉴于我知道第一个三角形中的点(x,y,z),我知道向量V1,V2,V3。我需要找到点(x',y',z')。我应该用矢量V1,V2,V3指向(x,y,z)以获得第二个三角形中的变换点?

感谢您的帮助!!!

6 个答案:

答案 0 :(得分:3)

简短的回答是,这比最初出现时要复杂得多,而且你对这个问题的限制性质需要一些比你想象的更先进的技术。

所以,通过解释,我会稍微改变你的记法。考虑3对向量(这些向量对应于问题中两个三角形的顶点):

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'

这种配方是必需的,因为转化似乎是3-D仿射变换,而不是3-D线性变换。如果是线性变换,则包含原点的任何三角形都必须映射到包含原点的另一个三角形。扩展到4-D空间允许使用4-D线性变换来执行3-D仿射变换。

那就是说,首先要注意的是这个问题是不受约束的(9个方程有12个未知数);没有独特的解决方案。实际上有无数的。但是,你的问题比这更受限制,所以有一些希望。给定一个向量

,你有额外的约束
p = <p0, p1, p2, 1>

查找

Ap = p' = <p0', p1', p2', 1>

这样(使用你的定义向量 a b c 的)

|u - p|   |u' - p'|
------- = ---------
|u - a|   |u' - Aa|

|v - p|   |v' - p'|
------- = ---------
|v - b|   |v' - Ab|

|w - p|   |w' - p'|
------- = ---------
|w - c|   |w' - Ac|

虽然这会对您的问题产生额外的限制,但它会将其从使用线性方法轻松解决的问题更改为需要Convex Programming才能找到唯一解决方案的问题。

那就是说,这里有一些可能的方法:

  • 继续使用凸面编程来解决问题。虽然比线性问题更难以解决,但它们并不是那么难以解决。
  • 恢复到2D情况,而不是3D情况。这可以在不依赖于距离测量所施加的非线性约束的情况下完成。
  • 选择第四个点,而不是处理三角形,而是使用四面体。这再次消除了问题的非线性。

更新:我已经考虑过这个问题了,我看到了一种在不使用凸面编程的情况下生成正确的仿射变换的方法。可以通过为每个三角形生成第四个顶点来完成,称为yy'

y = u + (v-u)×(w-u)
y' = u' + (v'-u')×(w'-u')

其中×是两个向量的3-D叉积(即省略每个向量中的最后1个;但是一旦计算出它们,记得将1附加到y和y')。从那里,您可以应用从列向量创建矩阵M和M'的标准技术:

 M = <u, v, w, y>
 M' = <u', v', w', y'>

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

AM = M'
AMM-1 = M'M-1
A = M'M-1

答案 1 :(得分:3)

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

答案 2 :(得分:2)

检查和评论理论

// 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();
}

此代码的视频: http://www.youtube.com/watch?v=yOU90pBoyZY

答案 3 :(得分:1)

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

答案 4 :(得分:0)

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

答案 5 :(得分:0)

 x = αx1 + βx2 + γx3 

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

x' = α(x1+V1) + β(x2+V2) + γ(x3+V3)