【问题标题】:Coordinate system transformation, 3d projection to 2d plane坐标系变换,3d 投影到 2d 平面
【发布时间】:2016-07-26 11:36:20
【问题描述】:

我有一个全局坐标系(X、Y、Z)和一个带点(A、B、C 和中心)的三角形。我知道这些点的所有坐标。

  1. 我需要将全局坐标系从 (0; 0; 0) 移动到三角形中心,以便所有点:A、B、C 和中心都有 Z = 0 的新坐标。之后我需要知道这些点在与新坐标系的关系中的新坐标。新坐标系的方向并不重要。
  2. 此外,如果有可能将 3D 点(三角形点)转换为 2D 平面而不会丢失其几何形状(大小)。它不应该是二维平面的投影。

>> A=[10.63307; -7.72528; 21.26636];
B=[4.06139; -12.49988; 21.26636];
C=[-6.57172; -20.22529; 13.14344];
Centr=[-4.38113; -13.48349; 18.55872];

>> V1=(B-A)/(norm(B-A))

V1 =

   -0.8090
   -0.5878
         0

>> V2=((C-A)-(dot((C-A),V1)*V1))/(norm((C-A)-(dot((C-A),V1)*V1)))

V2 =

    0.0000
   -0.0000
   -1.0000

>> V3=cross(V1,V2)

V3 =

    0.5878
   -0.8090
    0.0000

>> M=[V1,V2,V3]

M =

   -0.8090    0.0000    0.5878
   -0.5878   -0.0000   -0.8090
         0   -1.0000    0.0000

>> Anew=inv(M)*(A-Centr)

Anew =

  -15.5313
   -2.7076
    4.1666

>> Bnew=inv(M)*(B-Centr)

Bnew =

   -7.4083
   -2.7076
    4.1666

>> Cnew=inv(M)*(C-Centr)

Cnew =

    5.7350
    5.4153
    4.1666

这是我得到的: From this

To this

【问题讨论】:

  • 这是一道数学题,与 c++ 或 matlab 几乎没有关系(除非您需要两者中的任何一个的代码,在这种情况下您应该展示您已经尝试过的内容)
  • 顺便说一句,这是非常基本的几何形状。 z 垂直于三角形,另外两个方向您只需选择位于三角形上。有什么问题?
  • Z全部设置为0,您将获得从3D到2D的转换。例如,如果要将坐标转换为位于 (2, 2) 处的新 (0,0) 系统,则需要从所有其他坐标中减去 (2,2)。那么结果就是新的 (0,0) 系统。现在可以请您显示一些minimal reproducible example 吗?
  • @FirstStep 这不一定将三角形映射到三角形(如果两点仅在 z 坐标上有所不同)。他还提到三角形的大小应该保持不变
  • 我认为这是一个非常好的问题,它对于在 C++ 或 Matlab(OpenGL,...)中以编程方式操作 3D 坐标的人很有用。

标签: c++ matlab math coordinates coordinate-systems


【解决方案1】:

问题可以表示为找到一个 3×3 矩阵 M 使得点 P 的坐标可以在旧坐标系(P_old,3 行)和新坐标之间转换系统(P_new,3 行)。这是一个仿射变换:

P_old = Center + M * P_new     (1)

M 的(矩阵-向量)乘法将其定位回旧系统,添加Center 的坐标会将其转换回旧原点。

式(1)可化为:

P_new = M^{-1} * (P_old - Center)     (2)

其中M^{-1}M 的倒数,用于根据旧坐标计算新坐标(如果该点属于三角形平面,则第三行将为 0)。

矩阵M由旧系统中新基的坐标组成,每列一个基向量。现在必须找到这样的基础。

这个基础可以取自(这都是伪代码):

  1. 重整化AB

           AB
    V1 = ______
        || AB ||
    
    • AB 这里的意思是向量AB(上面有一个箭头):

      |b_x - a_x|
      |b_y - a_y|
      |b_z - a_z|
      
    • || . || 是欧几里得范数(^2 表示正方形,而不是 xor):

      || V || = sqrt(V_x^2 + V_y^2 + V_z^2)
      
  2. AC(也是一个向量,定义如AB),但减去它在V1 上的投影以使其与V1 正交,并重新归一化(如果三角形是,这将失败,除以零不是真正的三角形):

            AC - (AC.V_1) V1
    V2 = _______________________
         || AC - (AC.V_1) V1 ||
    
    • M.N 是标量积:

      M.N = M_x * N_x + M_y * N_y + M_z * N_z
      
    • (AC.V_1) V1 只是标量 (AC.V_1) 与向量 V1 的乘积

  3. 第三个向量,可以作为叉积得到笛卡尔坐标系:

    V3 = V1 x V2
    
    • 叉积定义为:

                |V1_y*V2_z - V1_z*V2_y|
      V1 x V2 = |V1_z*V2_x - V1_x*V2_z|
                |V1_x*V2_y - V1_y*V2_x|
      

然后M可以取为|V1 V2 V3|(每个Vx在3行上),然后使用公式(2)进行逆计算。

这种变换(使用倒置的 M)应该为三角形平面上的点生成新坐标,这些点在第三轴上有 0(这使得它在该平面上成为二维坐标),并保留大小欧几里得范数。

【讨论】:

  • 其中x^2 表示Pow(x, 2) 而不是x xor 2
  • 是的,谢谢你的精确,@FirstStep。我已经编辑了答案。
  • 谢谢您,我尝试了您的解决方案并设法使所有点的“Z”坐标完全相等,但不是 0。此外,我的三角形也发生了变化。也许我做错了什么?我编辑了我的问题并添加了 Matlab 代码和一些图片。
  • ACV1=AC(1)*V1(1)+AC(2)*V1(2)+AC(3)+V1(3): 最后一个+ 应该是* :-)
  • 我在 ACV1=AC(1)*V1(1)+AC(2)*V1(2)+AC(3)*V1(3) 中将 + 改为 *,仍然是 "z"坐标不是 0,我的三角形改变了它的形状。我做错了什么?我编辑了我的代码和代表结果的图片。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-15
  • 1970-01-01
  • 2017-10-06
  • 2023-03-08
  • 1970-01-01
相关资源
最近更新 更多