确定弧是表示反射角还是锐角

时间:2018-06-08 12:31:11

标签: geometry angle points

我有这个看似简单但非常令人困惑的问题。

鉴于我有一组顶点(x1,y1),(x2,y2),(x3,y3)......表示弧。这些点可以是顺时针或逆时针,但都是相似的顺序。 而且我知道弧的中心(xc,yc)。

如何判断弧是否对着锐角/钝角或反射角?

一个明显的解决方案是采用atan2((last_pt) - (center))和atan2((first_pt) - (center)))的区别。但是如果弧线经过PI成为-PI的点,则该方法会崩溃。

另外,由于弧点是从相当嘈杂的像素化图像导出的,因此顶点不是完全平滑的。

Picture of a acute and reflex arc

我无法解决这个问题。

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

使用2D角度是一个痛苦的原因,所以最好使用矢量数学,这是旋转不变的。

定义2D 跨产品A ^ B = Ax * By - Ay * Bx。如果A相对于B顺时针旋转,则为正,反之亦然。

逻辑:

  • 计算C = (last_pt - center) ^ (first_pt - center)
  • 如果C = 0,则电弧关闭或180度(忘记此名称)
  • 如果C > 0,则弧必须(i)顺时针急/钝> (ii)反顺时针反射
  • 如果C < 0,则相反适用

伪代码:

int arc_type(Point first, Point last, Point center, bool clockwise)
{
    // cross-product
    float C = (last.x - center.x) * (first.y - center.y)
            - (last.y - center.y) * (first.x - center.x);

    if (Math.abs(C) < /* small epsilon */)
        return 0;                      // 180-degree

    return ((C > 0) ^ clockwise) ? 1   // reflex
                                 : -1; // acute / obtuse
}

请注意,如果您事先不知道电弧是顺时针还是反电弧,则可以在相邻点上使用相同的叉积方法。您需要确保点的顺序一致 - 如果不是,您可以再次使用交叉产品,按(相对)角度对它们进行排序。