我如何在静态和动态坐标系之间转换
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
.
组成
矩阵M
是S
和R
的组合:
c -s 0
M = s c 0
-dx*c-dy*s dx*s-dy*c 1
这里c
和s
是旋转角度的余弦和正弦,它们的值分别是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;
我有这样的设置:
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
.
矩阵M
是S
和R
的组合:
c -s 0
M = s c 0
-dx*c-dy*s dx*s-dy*c 1
这里c
和s
是旋转角度的余弦和正弦,它们的值分别是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;