获取3D空间中平面多边形顶点的局部2D坐标

时间:2014-10-14 20:22:09

标签: python 3d geometry

我有几个平面多边形,由它们在3D空间中的顶点定义。这些多边形在3维中随机旋转。

现在我想在它们自己的局部2D空间中处理这些多边形顶点中的每一个。我真的不在乎这个地方空间的中心在哪里。我只需要x& y轴与多边形法线正交。

例如,如果我有一个宽度为&n的矩形的多边形。高度1,顶点可能看起来像:

v1 = [-0.558013, -0.0334937, -0.433013]
v2 = [0.308013, 0.466506, -0.433013]
v3 = [-0.308013, -0.466506, 0.433013]
v4 = [0.558013, 0.0334937, 0.433013]

但我希望他们看起来像这样:

v1 = [0, 0]
v2 = [0, 1]
v3 = [1, 1]
v4 = [1, 0]

所以我的问题是,如何将每个顶点3D坐标转换为局部2D坐标?

2 个答案:

答案 0 :(得分:7)

首先考虑多边形p0p1p2的三个非共线点,然后计算

loc0 = p0                       # local origin
locx = p1 - loc0                # local X axis
normal = cross(locx, p2 - loc0) # vector orthogonal to polygon plane
locy = cross(normal, locx)      # local Y axis

其中cross是叉积运算符:

def cross(a, b):
    return P3d(a.y*b.z - a.z*b.y,
               a.z*b.x - a.x*b.z,
               a.x*b.y - a.y*b.x)

然后规范化计算的局部轴locxlocy

locx /= locx.length()
locy /= locy.length()

最后点的本地坐标只是

local_coords = [(dot(p - loc0, locx),  # local X coordinate
                 dot(p - loc0, locy))  # local Y coordinate
                for p in points]

其中dot是标量乘积运算符:

def dot(a, b):
    return a.x*b.x + a.y*b.y + a.z*b.z

要从本地坐标(Lx, Ly)返回到3D,转换是

p = loc0 + Lx*locx + Ly*locy

答案 1 :(得分:3)

对于一个多边形,您需要在多边形平面中找到局部2D基础,并在此2D基础上投影多边形的每个顶点的3D坐标以获得2D坐标。在下文中,我还假设您正在寻找正交二维基础(多边形平面上的单位长度和正交二维基矢量)。

一步一步:

  1. 计算多边形的(单位)法线n,假设顶点确实是共面的,

  2. 获取多边形的第一条边并使用它来定义2D基础的第一个轴u(单位矢量),

  3. 使用u和n(v = n x u)

  4. 使用另一个轴v完成2D基础
  5. 在(u,v,n)3D基础上投影每个顶点,这将在多边形平面中给出其2D坐标。

  6. 例如,使用以下具有五个顶点的多边形:

       M1 +----+ M3
          |      \
          |       + M4
          |      /
       M2 +----+ M5
    

    其中M1有3D坐标v1 = (x1, y1, z1)M2有3D坐标v2 = (x2, y2, z2)等等......

    1. 与飞机垂直的单位为:n = (v2 - v1) x (v3 - v1) / |(v2 - v1) x (v3 - v1)|

    2. 2D基础的第一个轴是:u = (v2 - v1) / |(v2 - v1)|

    3. 2D基础的第二个轴是:v = n x u

    4. 获取多边形的顶点(或多边形平面中的任意点),例如M5

      然后,它的3D坐标可以(u, v, n)基础与原始v1一起编写。

        v5 = v1 + r5 * u + s5 * v + t5 * n
      
      
                  (           ) ( r5 )   (  xu  xv  xn ) ( r5 )   (     ) ( r5 ) 
        v5 - v1 = (  u  v  n  ) ( s5 ) = (  yu  yv  yn ) ( s5 ) = (  B  ) ( s5 ) 
                  (           ) ( t5 )   (  zu  zv  zn ) ( t5 )   (     ) ( t5 ) 
      

      其中t5应为0(它是沿平面法线的点的坐标,因此如果该点位于多边形的平面上,则它为0)。

      因此,求解(r5, s5, t5)会产生:

        ( r5 )                                    (  u  )
        ( s5 ) = B^-1 (v5 - v1) = B^T (v5 - v1) = (  v  ) ( v5 - v1 )
        ( t5 )                                    (  n  )
      

      因为B是正交矩阵(所以B ^ -1 = B ^ T)。

      最后,简单地说:

        r5 = u . (v5 - v1)
        s5 = v . (v5 - v1)
      

      其中.是矢量点积。