代码之家  ›  专栏  ›  技术社区  ›  Agnius Vasiliauskas

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

  •  2
  • Agnius Vasiliauskas  · 技术社区  · 15 年前

    编辑

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

    alt text

    谢谢你的帮助!!!

    6 回复  |  直到 11 年前
        1
  •  1
  •   Steve Emmerson    15 年前

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

        2
  •  5
  •   andand    15 年前

    所以,作为一个解释,我要改变一下你的符号。考虑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'

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

    也就是说,首先要注意的是这个问题是欠约束的(9个方程有12个未知数);没有唯一的解。事实上有无限多个。但是,您的问题比这更受限制,因此还有一些希望。在给定向量的情况下,有额外的约束

    p = <p0, p1, p2, 1>

    找到

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

    这样(使用你的定义向量 , ,和 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

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

    • 继续用凸规划来解决这个问题。虽然比线性问题更难解决,但它们并不是真的那么难解决。

    更新: 我已经考虑过了,我看到了一种不使用凸规划生成正确仿射变换的方法。这可以通过为每个三角形生成第四个顶点来实现,称为 y y' :

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

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

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

    并使用史蒂夫·埃默森建议的方法(用4-D而不是3-D):

    AM = M'
    AMM-1 = M'M-1
    A = M'M-1
        3
  •  3
  •   tfinniga    15 年前

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

        4
  •  3
  •   chain    15 年前

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

        5
  •  0
  •   KeithS    15 年前

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

        6
  •  0
  •   Colin Fine    15 年前

     x = αx1 + βx2 + γx3 
    

    那么 x'=±x1'+x2'+x3' 所以呢

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