在 3D 空间中映射两个三角形之间的点

发布于 2024-09-25 03:11:47 字数 322 浏览 7 评论 0原文

编辑

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

alt text

我在 3D 空间中有两个三角形。鉴于我知道第一个三角形中点的 (x,y,z) 并且我知道向量 V1,V2,V3。我需要找到点(x',y',z')。我应该对带有向量 V1,V2,V3 的点 (x,y,z) 进行什么变换才能获得第二个三角形中的变换点?

感谢您的帮助!

EDIT

I don't know is it important, but destination triangle angles may be different than these of source. Does that fact makes transformation non-affine ? (i'm not sure)

alt text

I have two triangles in 3D space. Given that i know (x,y,z) of point in first triangle and i know vectors V1,V2,V3. I need to find point (x',y',z'). What transformation i should do to point (x,y,z) with vectors V1,V2,V3 to get that transformed point in the second triangle ?

Thanks for help !!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

春庭雪 2024-10-02 03:11:47

简而言之,这比乍一看要复杂,并且您对问题施加的约束的性质需要一些比您想象的更先进的技术。

因此,作为解释,我将稍微更改一下您的符号。考虑 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>

(使用您的定义向量 ab 和 < 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|

虽然这对您的问题提出了额外的限制,但它将它从可以使用线性方法轻松解决的问题更改为需要 凸编程寻找独特的解决方案。

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

  • 继续使用凸规划来解决问题。虽然比线性问题更难解决,但它们实际上并不是那么难解决。
  • 恢复到 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 维而不是 3 维中):

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

The short answer is that this is more complicated than it at first appears, and the nature of the constraints you are placing on the problem require some more advanced techniques than you might think.

So, by way of an explanation, I'm going to change your notation a bit. Consider 3 pairs of vectors (these correspond to your the vertices of the two triangles in your problem):

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>

Ordinarily, your problem would be solved through the identification of the linear transformation of the form:

    |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   |

such that:

Au = u'
Av = v'
Aw = w'

This formulation is needed because the transformation seems to be a 3-D affine transformation, not a 3-D linear transformation. If it were a linear transformation, any triangle containing the origin would necessarily map to another triangle containing the origin. Extending to a 4-D space allows 4-D linear transformation to be used to perform 3-D affine transformation.

That said, the first thing to notice is that this problem is underconstrained (9 equations with 12 unknowns); there is no unique solution. There are in fact infinitely many. However, your problem is somewhat more constrained than this, so there's some hope. You have the additional constraints given a vector

p = <p0, p1, p2, 1>

find

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

such that (using your definition vectors a, b, and 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|

While this presents an additional constraint on your problem, it changes it from being one that could easily solved using linear methods to one that requires Convex Programming to find a unique solution.

That said, here are some possible aproaches:

  • Go ahead and use convex programming to solve the problem. While more difficult to solve than linear problems, they are not really all that hard to solve.
  • Revert to the 2D case, rather than the 3D case. This can be done without resorting to the non-linear constraints those distance measurements impose.
  • Select a fourth point and instead of working on triangles, work on tetrahedra instead. This again removes the non-linearity from the problem.

UPDATE: I've given this some thought and I see a way to generate the correct affine transformation without using convex programming. It can be done by generating a fourth vertex for each of the triangles, called y and y':

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

where × is the 3-D cross product of the two vectors (i.e. omit the final 1 in each vector; but remember to append the 1 onto y and y' once you have them calculated). From there, you can apply the standard technique of creating matrices M and M' from column vectors:

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

and use the method Steve Emmerson suggested (in 4-D rather than 3-D):

AM = M'
AMM-1 = M'M-1
A = M'M-1
月下凄凉 2024-10-02 03:11:47

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

I think you might be looking for barycentric coordinates?

情独悲 2024-10-02 03:11:47

检查 andand 的理论评论

// 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

check andand's comments for theory

// Qt code

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

And a video of this code in action:
http://www.youtube.com/watch?v=yOU90pBoyZY

乖乖 2024-10-02 03:11:47

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

You want a matrix transformation T such that T X = X', where X is the matrix whose columns are the co-ordinates of the vertexes of the first triangle and X' is the same for the second triangle. Multiplying each side by the inverse of X yields T = X' X-1.

嗳卜坏 2024-10-02 03:11:47

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

Simply add the vectors to each point. Point + Vector == new Point. This is basically the opposite of creating the Vector in the first place: V1 == (x1'-x1, y1'-y1, z1'-z1), so (x1', y1', z1') == (x1+V1x, y1+v1y, z1+V1z).

倒带 2024-10-02 03:11:47

 x = αx1 + βx2 + γx3 

那么
x' = αx1' + βx2' + γx3'
所以

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

Let

 x = αx1 + βx2 + γx3 

Then
x' = αx1' + βx2' + γx3'
So

x' = α(x1+V1) + β(x2+V2) + γ(x3+V3)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文