Math 如何在静态坐标系和动态坐标系之间进行转换

Math 如何在静态坐标系和动态坐标系之间进行转换,math,geometry,linear-algebra,coordinate-systems,coordinate-transformation,Math,Geometry,Linear Algebra,Coordinate Systems,Coordinate Transformation,我有这样的设置: 2坐标系。(x,y)是主坐标系,(x',y')是位于(x,y)内部的坐标系。系统(x',y')由点x1或x2定义,如果我移动这两个点,则(x',y')相应移动。(x',y')的原点定义为从x1到x2的向量的中间,y'轴是x1->x2上穿过原点的法向量。如果我在(x',y')中定义了一个点x3,并且我移动x1或x2中的任何一个以使原点移动,那么我如何相应地移动x3,使其保持在新的(x',y')中的位置? 无论x1和x2是如何设置的,我如何做一个总是将(x,y)中的点转换为(x'

我有这样的设置:

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

我在想,如果我有更多的点,而不仅仅是我正在移动的那个点(x1或x2),我想我可以试着估计变换的θ,tx,ty

[x2']   [cos(theta) , sin(theta), tx][x2]
[y2'] = [-sin(theta), cos(theta), ty][y2]
[ 1 ]   [    0      ,      0    , 1 ][1 ]
把这个估计的变换应用到x3,我会很好…嗯,但我想我需要3个点来估计θ,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轴上

好的,我试着从dynamic1到dynamic2实现x3,检查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
组成

矩阵
M
S
R
的组合:

      c            -s          0
M =   s             c          0
      -dx*c-dy*s   dx*s-dy*c   1
这里
c
s
是旋转角度的余弦和正弦,它们的值分别是单位(标准化)向量
x1x2
x-
y-
分量

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
注意,将动态坐标转换为静态坐标的矩阵是
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;

您可以尝试使用二维数组来保存它,但可以轻松地更改其值。您可以再详细说明一下吗?我不太明白你的意思。谢谢你的评论。正如您所解释的,我理解如何将静态系统转换为(x1,x2)定义的系统。但我不知道如何在变换矩阵中找到c和s。你能再详细说明一下吗?你写单位向量x1x2的x和y分量,那么这是向量x2-x1还是我怎么找到的?是的,这是向量x2-x1,然后你需要对它进行规范化(将分量除以向量长度)。我试着做了一个例子(我把代码放在我的原始帖子的页面顶部),它似乎并没有给出正确的结果。我做错什么了吗?好像是我的错。需要彻底检查矩阵及其乘法顺序。可能明天。嗯,是的……当我尝试设置x1=[5,0]和x2=[10,0]时,如果我尝试转换x2=[10,0],我会期望输出为[2.5,0],但我似乎得到[17.5 0]。。。有点可疑,看起来很令人担忧。这对我来说不是很有用。在这里,数组标注并不是真正的问题。问题是如何设置适当的转换。