我有这个看似简单但非常令人困惑的问题。
鉴于我有一组顶点(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
我无法解决这个问题。
感谢您的帮助!
答案 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
}
请注意,如果您事先不知道电弧是顺时针还是反电弧,则可以在相邻点上使用相同的叉积方法。您需要确保点的顺序一致 - 如果不是,您可以再次使用交叉产品,按(相对)角度对它们进行排序。