geometry - 确定弧是代表反射角还是锐角
问题描述
我有这个看似简单但非常令人困惑的问题。
鉴于我有一组顶点 (x1,y1), (x2,y2), (x3,y3)...... 代表一个弧。这些点可以是顺时针也可以是逆时针,但它们的顺序都是相似的。而且我知道弧的中心(xc,yc)。
如何判断圆弧是否对着锐角/钝角或反射角?
一个明显的解决方案是采用 atan2((last_pt)-(center)) 和 atan2((first_pt)-(center))) 的差异。但如果弧线经过 PI 变为 -PI 的点,这种方法就失效了。
此外,由于弧点是从相当嘈杂的像素化图片中得出的,因此顶点并不完全平滑。
我无法解决这个问题。
谢谢你的帮助!
解决方案
由于您描述的原因,使用 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
}
请注意,如果您不知道圆弧是顺时针还是逆时针,您可以在相邻点上使用相同的叉积方法。您需要确保点的顺序是一致的- 如果不是,您可以再次使用叉积,按(相对)角度对它们进行排序。
推荐阅读
- continuous-integration - Gitlab CI/CD 在计划的管道上仅触发 gitlab-ci.yml 文件中的单个阶段
- python - Geopandas如何移动情节
- php - 分页时将锚点添加到第 2 页的第 1 页上一个链接
- node.js - 更新嵌套对象数组中的名称
- forms - UI5:验证整个表单的空值/空白值的必填和可见字段
- node.js - Nodejs 云函数 - 并非所有代码路径都返回值
- list - 使用列表在购物车中创建项目列表(Flutter Web)
- python - A 返回地图中树的数量
- sql - 执行 CREATE TABLE SQL 命令时未创建 Wordpress 表
- ruby-on-rails - Mysql2::Error:Rails 5升级后字段'key'没有默认值