用于小角度2D旋转中心的最佳近似公式

时间:2010-04-13 04:59:20

标签: math geometry

这不是作业。我要问看问题是经典的(微不足道的)还是非平凡的。它在表面上看起来很简单,我希望它确实是一个简单的问题。

  1. 有N个点(N> = 2) 在表面上坐标Xn,Yn 2D实体。
  2. 实体有一些小旋转(低于Pi / 180) 结合小班次(低于任何2点N之间距离的1%)。可能还有一些小的变形(<<0.001%)
  3. 相同的N个点具有名为XXn,YYn
  4. 的新坐标
  5. 以最佳近似值计算旋转中心的位置,作为C点,坐标为XXX,YYY。
  6. 谢谢

7 个答案:

答案 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作为AA^-1的转置作为A的反转。通常你会使用SVD或QR分解来计算解决方案,因为它们应该比反向更稳定,计算密集度更低。

找到x后(转换abcd的四个要素),然后是各种要素

给出了转型
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

我们从上面的等式中了解thetarotation),dxc)和dyd)。通过一点点摆弄,我们可以解决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)

首先,这个问题并不重要。

一个“简单”的解决方案。当多边形类似于圆形时,它最有效,并且点均匀分布。

  • 迭代N
  • 对于旧数据集和新数据集,找到N点的2个最远点。 所以现在你在变换之前和之后都有三角形。使用每个三角形中心的顺时针方向将其顶点编号为[0](=原始数据集中的第N个点),[1]和[2](2个最远点)。
  • 计算此三角形的旋转中心和变形(x和y)。如果变形大于0.001% - 则删除此三角形的数据,否则保存它。
  • 计算旋转中心的平均值。

正确的解决方案:定义函数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)
{
//使用点的方向形式相交两条线 //返回一个点
}