Math 将二维三角形上的点投影回三维?

Math 将二维三角形上的点投影回三维?,math,projection,Math,Projection,我不确定要搜索什么,所以我无法找到我需要的东西 假设我有一个带有点的三维三角形[0,1,1],[1,0.5,0.5],[0,0,0]。我放弃了Z分量,创建了一个带有点的二维三角形[0,1],[1,0.5],[0,0]。(我认为这是一个正交投影?)通过一个不重要的过程,我找到了二维三角形中的一些二维点,比如说[0.5,0.5] 我如何获取该2D点,并找到其Z值,使其位于原始3D三角形形成的平面上 通过代码而不是数学符号来描述数学的答案(或复制链接!)将非常受欢迎;我很难读懂你的答案。你可以用 因此

我不确定要搜索什么,所以我无法找到我需要的东西

假设我有一个带有点的三维三角形
[0,1,1],[1,0.5,0.5],[0,0,0]
。我放弃了Z分量,创建了一个带有点的二维三角形
[0,1],[1,0.5],[0,0]
。(我认为这是一个正交投影?)通过一个不重要的过程,我找到了二维三角形中的一些二维点,比如说
[0.5,0.5]

我如何获取该2D点,并找到其Z值,使其位于原始3D三角形形成的平面上

通过代码而不是数学符号来描述数学的答案(或复制链接!)将非常受欢迎;我很难读懂你的答案。

你可以用

因此,您得到了二维三角形
q0、q1、q2
和相应的三维三角形
p0、p1、p2
,并希望将二维点
q
转换为三维点
p

  • 计算
    q0、q1、q2内
    q
    的重心坐标
    u、v

  • 使用三角形将
    u,v
    转换为笛卡尔坐标
    p0,p1,p2

  • 因此,当把它们放在一起时:

    | u |           | (q1.x - q0.x) , (q2.x - q0.x) , q0.x |   | q.x |
    | v | = inverse | (q1.y - q0.y) , (q2.y - q0.y) , q0.y | * | q.y |
    | 1 |           |       0       ,       0       ,   1  |   |  1  |
    
    p.x = p0.x + (p1.x - p0.x) * u + (p2.x - p0.x) * v
    p.y = p0.y + (p1.y - p0.y) * u + (p2.y - p0.y) * v
    p.z = p0.z + (p1.z - p0.z) * u + (p2.z - p0.z) * v
    

    进一步介绍@Spektre的优秀答案,这就是我实现工作解决方案的方式。我和Unity一起工作,所以我用Ivan Kutskir的很棒来处理矩阵数学。可能有更快/更干净的方法可以做到这一点,但这非常简单,而且工作正常

    显然,您必须确保当您放弃Z轴时,不会以退化三角形结束

    //tri是一个具有点p0、p1和p2的3D三角形
    //点是该三角形内的二维点,假设Z轴被丢弃
    /*
    相当于@Spektre回答的这一部分:
    |u | | |(q1.x-q0.x),(q2.x-q0.x),q0.x | | q.x|
    |v |=逆|(q1.y-q0.y),(q2.y-q0.y),q0.y |*| q.y|
    | 1 |           |       0       ,       0       ,   1  |   |  1  |
    */
    矩阵m1=新矩阵(3,3);
    矩阵m2=新矩阵(3,1);
    m1[0,0]=tri.p1.x-tri.p0.x;
    m1[0,1]=tri.p2.x-tri.p0.x;
    m1[0,2]=tri.p0.x;
    m1[1,0]=tri.p1.y-tri.p0.y;
    m1[1,1]=tri.p2.y-tri.p0.y;
    m1[1,2]=tri.p0.y;
    m1[2,0]=0;
    m1[2,1]=0;
    m1[2,2]=1;
    m2[0,0]=点x;
    m2[1,0]=点y;
    m2[2,0]=1;
    矩阵mResult=m1.Invert()*m2;
    浮点u=(浮点)mResult[0,0];
    float v=(float)mResult[1,0];
    /*
    相当于@Spektre回答的这一部分:
    p、 x=p0.x+(p1.x-p0.x)*u+(p2.x-p0.x)*v
    p、 y=p0.y+(p1.y-p0.y)*u+(p2.y-p0.y)*v
    p、 z=p0.z+(p1.z-p0.z)*u+(p2.z-p0.z)*v
    */
    float newX=tri.p0.x+(tri.p1.x-tri.p0.x)*u+(tri.p2.x-tri.p0.x)*v;
    float newY=tri.p0.y+(tri.p1.y-tri.p0.y)*u+(tri.p2.y-tri.p0.y)*v;
    float newZ=tri.p0.z+(tri.p1.z-tri.p0.z)*u+(tri.p2.z-tri.p0.z)*v;
    Vector3 newPoint=新Vector3(newX,newY,newZ);
    
    或者,您可以在不使用矩阵的情况下获得相同的结果(尽管这可能是一种不太可靠的方法,我不确定)。为了计算重心坐标,我使用了,但是这个方法也可以

    //tri是一个具有点p0、p1和p2的3D三角形
    //点是该三角形内的二维点,假设Z轴被丢弃
    //找到所选2D点的重心坐标。。。
    浮点数u,v,w=0;
    重心2D(点,新矢量2(tri.p0.x,tri.p0.y),新矢量2(tri.p1.x,tri.p1.y),新矢量2(tri.p2.x,tri.p2.y),out u,out v,out w);
    //…然后找出3D中重心坐标的Z值
    float newZ=tri.p0.z*u+tri.p1.z*v+tri.p2.z*w;
    矢量3新点=新矢量3(点x、点y、新Z);
    // https://gamedev.stackexchange.com/a/63203/48697
    空心重心2D(向量2 p、向量2 a、向量2 b、向量2 c、外浮点数u、外浮点数v、外浮点数w)
    {
    矢量2 v0=b-a;
    向量2 v1=c-a;
    向量2 v2=p-a;
    浮点数=v0.x*v1.y-v1.x*v0.y;
    v=(v2.x*v1.y-v1.x*v2.y)/den;
    w=(v0.x*v2.y-v2.x*v0.y)/den;
    u=1.0f-v-w;
    }
    
    原始三角形的平面将有一个类似于
    z=a*x+b*y+c的方程。找到这个等式,然后插入
    x
    y
    @JohnColeman我不确定你的确切意思。
    a
    b
    c
    是三角形的点吗?我不确定你是不是说,这个方程不知怎么给了我Z值。二维非垂直线的方程可以写成
    y=a*x+b
    。类似地,三维非垂直平面的方程可以写成
    z=a*x+b*y+c
    。所讨论的
    a、b、c
    是标量,可以通过各种方式获得。标准方法是形成向量
    PQ
    PR
    的叉积(其中
    P,Q,R
    是原始三角形中的点)<代码>a、b、c
    可以很容易地从该叉积中获得。搜索“通过3点的平面方程”。@JohnColeman老实说,我希望自己能弄清楚的更少。如果我必须自己算出数学题,我会犯错误,浪费时间试图找出我不太懂的东西中的错误。如果我必须用谷歌搜索“方程式(无论什么)”,我就完蛋了,因为我只懂通过代码描述的数学,除非它是简单的代数。我知道这是我教育上的一个失败。当你说“二维非垂直线的方程可以写成y=a*x+b”时,我只能茫然地盯着它看。什么是y?什么是x,a和b?那怎么翻译成代码?也许会有帮助。啊,当然!取二维三角形中该点的重心坐标,并找出具有相同重心坐标的三维三角形上的点。我想用类似的方法,使用平方距离,然后插值Z,但这可能更快。塞巴斯蒂安·拉格对重心库尔有很好的解释