我如何在静态和动态坐标系之间转换

how do i transform between a static and a dynamic coordinate system

我有这样的设置:

2个坐标系。 (x,y) 是主坐标系,(x',y') 是位于 (x,y) 内的坐标系。系统 (x',y') 由点 x1 或 x2 定义,如果我移动这 2 个点,则 (x',y') 相应地移动。 (x',y') 的原点定义为从 x1 到 x2 的向量的中间,y' 轴是 x1->x2 上穿过原点的法向量。如果我在 (x',y') 中定义了一个点 x3 并且我移动了 x1 或 x2 中的任何一个以使原点移动到位,那么我如何相应地移动 x3 以使其在新的 (x',你')? 我如何进行转换,无论 x1 和 x2 如何设置,始终将 (x,y) 中的点转换为 (x',y') 中的点?

我在想,如果我有比我移动的点(x1 或 x2)更多的点,我想我可以尝试估计变换的 theta、tx、ty

[x2']   [cos(theta) , sin(theta), tx][x2]
[y2'] = [-sin(theta), cos(theta), ty][y2]
[ 1 ]   [    0      ,      0    , 1 ][1 ]

并将估计的变换应用于 x3,我会很好...嗯,但我认为我需要 3 个点才能估计 theta、tx 和 ty,对吧? 我的意思是我可以使用一些最小二乘法进行估计...但是 3 个未知数需要 3 个坐标集对吗?

我试着实现了这个并计算了一个例子。我希望你能理解语法。它并没有真正满足我的期望:

import math
import numpy as np

x1=[ 0,10]
x2=[10,20]

rx = x2[0] - x1[0]
ry = x2[1] - x1[1]
rlen = math.sqrt(rx*rx+ry*ry)
c = rx / rlen
s = ry / rlen


dx = - ( x1[0] + x2[0] )/2 # changing the sign to be negative seems to 
dy = - ( x1[1] + x2[1] )/2 # rectify translation. Rotation still is wrong

M = np.array([[c, -s, 0],[s, c, 0],[dx, dy, 1]])
print( np.dot(x2 + [1],M) )
# Yields -> [ 15.92031022  -8.63603897   1.        ] and should yield [5,0,1]

因为我正在尝试转换 x2 坐标,那么结果是否应该在 y 分量中不具​​有值 0,因为它位于 x 轴上?

好的,我尝试对 x3 从 dynamic1 到 dynamic2 进行实现,检查结果是 x3 在 d1 和 d2 中的坐标应该相同。我按照你的建议做了,但我在 d1 和 d2 中没有得到相同的坐标。我是不是误会了什么?

import math
import numpy as np

x1=[ 1,1]
x2=[ 7,9]

x3=[4,3]

rx = (x2[0] - x1[0])
ry = (x2[1] - x1[1])
rlen = math.sqrt( rx*rx + ry*ry )
c = rx / rlen
s = ry / rlen


dx =  ( x1[0] + x2[0] )/2
dy =  ( x1[1] + x2[1] )/2

M = np.array([[c, -s, 0],[s, c, 0],[-dx*c-dy*s, dx*s-dy*c, 1]])
Minv = np.array([[c, s, 0],[-s, c, 0],[dx, dy, 1]])


x1new=[ 1,1]
x2new=[ 17,4]

rxnew = (x2new[0] - x1new[0])
rynew = (x2new[1] - x1new[1])
rlennew = math.sqrt( rxnew*rxnew + rynew*rynew )
cnew = rxnew / rlennew
snew = rynew / rlennew


dxnew =  ( x1new[0] + x2new[0] )/2
dynew =  ( x1new[1] + x2new[1] )/2

Mnew = np.array([[cnew, -snew, 0],[snew, cnew, 0],[-dxnew*cnew-dynew*snew, dxnew*snew-dynew*cnew, 1]])
Mnewinv = np.array([[cnew, snew, 0],[-snew, cnew, 0],[dxnew, dynew, 1]])

M_dyn1_to_dyn2 = np.dot(Minv,Mnew)

print( np.dot(x3 + [1], M) )
print( np.dot(x3 + [1], M_dyn1_to_dyn2))
#yields these 2 outputs which should be the same:
[-1.6 -1.2  1. ]
[-3.53219692  8.29298408  1.        ]

编辑。矩阵校正。

要将坐标从静态系统转换为 (x1,x2) 定义的坐标,您必须应用仿射变换。 此变换的矩阵 M 由移位矩阵 S 和原点旋转 R.

组成

矩阵MSR的组合:

      c            -s          0
M =   s             c          0
      -dx*c-dy*s   dx*s-dy*c   1

这里cs是旋转角度的余弦和正弦,它们的值分别是x-y-单位(归一化)向量的分量x1x2.

rx = x2.x - x1.x
ry = x2.y - x1.y
len = Sqrt(rx*rx+ry*ry)
c = rx / Len
s = ry / Len

和移位组件:

dx = (x1.x + x2.x)/2
dy = (x1.y + x2.y)/2

要将 (xx,yy) 坐标从静态系统转换为旋转坐标,我们必须找到

xx' = xx*c+yy*s-dx*c-dy*s =   c*(xx-dx) + s*(yy-dy)
yy' = -xx*s+yy*c+dx*s-dy*c = -s*(xx-dx) + c*(yy-dy)

快速检查:

X1 = (1,1)
X2 = (7,9) 
dx = 4
dy = 5
rx = 6
ry = 8
Len = 10
c = 0.6
s = 0.8

for point (4,5):
xx-dx = 0
yy-dy = 0
xx',yy' = (0, 0) - right

for point X2 =(7,9):
xx-dx = 3
yy-dy = 4
xx' = 0.6*3 + 0.8*4 = 5   -right
yy' = -0.8*3 + 0.6*4 = 0  -right

P.S。请注意,将 dyn.coordinates 转换为静态矩阵的矩阵是 M 的逆矩阵,并且更简单:

       c   s   0
 M' =  -s  c   0
       dx  dy  1  

P.P.S。您需要三对对应点来定义一般仿射变换。看起来这里你不需要缩放和纯粹,所以你可以用你的 x1,x2 点

确定需要的变换

我认为你需要双维数组来保存并在其中设置你的值

结构会是这样

    =============|========|========|
    index number |x       |y       |
    =============|========|========|
    first point  | [0][0] | [0][1] |    
    second point | [1][0] | [1][1] |                            
    third point  | [2][0] | [2][1] |                            
    =============|========|========|

我会在回答中使用java

    //declare the double dimension array
    double matrix[][] = new double[3][2];

    //setting location first point, x
    matrix[0][0] = 1;
    //setting location first point, y
    matrix[0][1] = 1;

    //fill with your formula, i only give example
    //fill second point with first point and plus 1
    //setting location second point, x
    matrix[1][0] = matrix[0][0] + 1;
    //setting location second point, y
    matrix[1][1] = matrix[0][1] + 1;

    //fill with your formula, i only give example
    //fill third point with second point and plus 1
    //setting location third point, x
    matrix[2][0] = matrix[1][0] + 1;
    //setting location third point, y
    matrix[2][1] = matrix[1][1] + 1;