这不是作业。我要问看问题是经典的(微不足道的)还是非平凡的。它在表面上看起来很简单,我希望它确实是一个简单的问题。
谢谢
答案 0 :(得分:3)
如果你知道对应关系(即你知道转换前后哪些点是相同的),并且你选择允许缩放,那么问题就是一组线性方程。如果你有2个或更多点,那么你可以找到一个没有困难的最小二乘解。
对于初始点(xi,yi)和变换点(xi',yi'),你有形式的方程式
xi' = a xi + b yi + c
yi' =-b xi + a yi + d
您可以重新排列成线性系统
A x = y
,其中
A = | x1 y1 1 0 |
| y1 -x1 0 1 |
| x2 y2 1 0 |
| y2 -x2 0 1 |
| ... |
| xn yn 1 0 |
| yn -xn 0 1 |
x = | a |
| b |
| c |
| d |
y = | x1' |
| y1' |
| x2' |
| y2' |
| ... |
| xn' |
| yn' |
标准的“最小二乘”形式是
A^T A x = A^T y
并有解决方案
x = (A^T A)^-1 A^T y
A^T
作为A
和A^-1
的转置作为A
的反转。通常你会使用SVD或QR分解来计算解决方案,因为它们应该比反向更稳定,计算密集度更低。
找到x
后(转换a
,b
,c
和d
的四个要素),然后是各种要素
scale = sqrt(a*a+b*b)
rotation = atan2(b,a)
translation = (c,d)/scale
如果不包括缩放,则系统是非线性的,需要迭代解决方案(但不难解决)。如果你不知道对应,那么问题就更难了,因为像iterated closest point这样的小变换是有效的,对于大变换来说,它要困难得多。
编辑:我忘了包含旋转中心。关于任意点theta
的轮换p
是序列
translate(p) rotate(theta) translate(-p)
如果你将它全部扩展为仿射变换(基本上就是我们上面所做的那样)那么翻译术语就会出现
dx = px - cos(theta)*px + sin(theta)*py
dy = py - sin(theta)*px - cos(theta)*py
我们从上面的等式中了解theta
(rotation
),dx
(c
)和dy
(d
)。通过一点点摆弄,我们可以解决px和py
px = 0.5*(dx - sin(theta)*dy/(1-cos(theta)))
py = 0.5*(dy + sin(theta)*dx/(1-cos(theta)))
如果theta为零,你会注意到方程是不确定的,因为没有旋转时没有旋转中心。
我认为我已经完全正确了,但我现在没有时间仔细检查它。
答案 1 :(得分:2)
查找“Kabsch算法”。它是一种使用N个已知对创建旋转矩阵的通用算法。 Kabsch创建它以协助去噪立体照片。您将图片A中的要素旋转到图片B,如果它不在目标位置,则该要素是噪点。 http://en.wikipedia.org/wiki/Kabsch_algorithm
答案 2 :(得分:1)
首先,这个问题并不重要。
一个“简单”的解决方案。当多边形类似于圆形时,它最有效,并且点均匀分布。
正确的解决方案:定义函数Err(Point BEFORE [N],Point AFTER [N],double TFORM [3] [3]),其中BEFORE - 常量旧数据点,AFTER - 常量新数据点,TFORM [3] [3]仿射变换矩阵,Err(...)函数返回标量误差值,当TFORM转换为精确AFTER或某些> 0.0误差值时返回0.0。然后使用您想要找到的最小Err(TFORM)的任何数学数学:例如渐变搜索。
答案 3 :(得分:1)
有关相对简单的解决方案,请参阅On calculating the finite centre of rotation for rigid planar motion。我说“相对简单”因为它仍然使用伪相反和SVD(奇异值分解)之类的东西。这是一个wikipedia article on Instant centre of rotation。另一篇论文:ESTIMATION OF THE FINITE CENTER OF ROTATION IN PLANAR MOVEMENTS。
如果你能处理更硬的东西,试试Least Squares Estimation of Transformation Parameters Between Two Point Patterns。
答案 4 :(得分:0)
计算多边形中心O1和O2。确定O1的线公式为(X0,Y0),O2为(XX0,YY0)。找到相交的行来获得C.
答案 5 :(得分:0)
如果我理解你的问题,可以用这种方式解决:
答案 6 :(得分:0)
在旋转之前和之后选择身体上的任意2个点,P1,P2。找到这些点之前和之后的向量。使用垂直于旋转平面的矢量交叉这些矢量。这导致两个新的向量,由初始点形成的线的交点和这两个新向量是旋转的中心。
{
如果P1after = P1之前返回P1
如果P2after = P2之前返回P2
矢量V1 = P1后 - P1之前
向量V2 = P2后 - P2之前
normal = Vn //为任意三维方向创建可能很麻烦但如果你知道方向就很简单,例如,对于x,y平面中的一个对象,normal =(0,0,1))
向量VL1 = V1 x Vn //向量V1与Vn
的交叉乘积
矢量VL2 = V2×Vn
return intersectLines(P1after,VL1,P2after,VL2)//旋转中心是两条线的交点
}
intersectLines(Point P1,Vector V1,Point P2,Vector V2)
{
//使用点的方向形式相交两条线
//返回一个点
}