如何将分配到刚体的点转换为身体的一部分?

时间:2014-06-11 14:24:29

标签: c++ transformation rigid-bodies

为了描述这个问题,我在下图中给出了一个例子。

可以看出,有一条线AB及其分配点p1。 对于这一行,我有一个相应的行,即CD。我正在寻找点p2的坐标。点p2和线CD之间的关系应该与点p1和线AB之间的关系相同(相同的距离d和相同的长度m)。我有点A,B,p1,C,D的坐标,我正在寻找p2。通常,d和m可以接受线CD和点p2的比例因子,我们已经知道了。

正如您可能知道的那样,该问题在CD行的左侧还有另一个虚假解决方案,如p3,我们应该避免这种情况。

在我的实际问题中,我有10条AB线,大约500点像p1一样分配给不同的AB线。我有十条相应的行CD,我正在寻找500个相应的点p2。

使用代数和几何可以解决问题,但我正在寻找一种快速有效的C ++实现方法。

非常感谢您的意见和建议。

enter image description here

1 个答案:

答案 0 :(得分:1)

首先,您需要将AB的任何移动表示为关于单个点的旋转和平移,例如A点,以简化。然后,对于需要与AB一起旋转的任何其他点,您应该通过减去A点将该点移动到AB线的空间中,然后通过在翻译后将新点A添加回它来将其转换回世界空间和旋转。

我手边没有公式,但我试着挖掘一个例子。

修改
未经测试的代码:

void transform_points(const point2f &center, vector<point2f> &points, const point2f &offset, float angle)
{
    // transform points into a space where 'center' is the origin
    mat3f to_origin = mat3f(1, 0, -center.x,
                            0, 1, -center.y,
                            0, 0, 1);

    // rotate the points around the origin
    mat3f rot = mat3f(cos(angle), -sin(angle), 0,
                      sin(angle),  cos(angle), 0,
                      0, 0, 1);

    // move the points back into world space
    mat3f to_world = mat3f(1, 0, center.x,
                           0, 1, center.y,
                           0, 0, 1);

    // offset the points by 'offset'
    mat3f off = mat3f(1, 0, offset.x,
                      0, 1, offset.y,
                      0, 0, 1);

    // concatenate all transformations for efficiency
    mat3f xform = off * to_world * rot * to_origin;

    // this loop could be parallelized using SIMD or multiple cores
    for(auto &p : points)
        p = xform * p;
}