找回密码
 欢迎注册
查看: 22237|回复: 6

[讨论] 如何不用图示描述两个三点组的走向(顺时针或逆时针)相同或相反?

[复制链接]
发表于 2019-12-14 17:50:33 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?欢迎注册

×
判断一个点是不是在一个多边形内部,可以通过以这一点为端点的射线与多边形的边的交点来判断。
判断两个点是不是在直线的同侧,可以通过连接这两点的线段与直线的相交情况来判断。
判断两条平行射线AB、CD是否同向,可以通过线段BD和线段AC的交点来确定。
对于ABC和DEF两个三点组,有没有不依赖直接图示,就能判断两个次序排列是否同向(顺时针或逆时针)的方法呢?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2019-12-14 20:58:32 | 显示全部楼层
判断一个点是不是在一个多边形内部,可以通过以这一点为端点的射线与多边形的边的交点来判断。
这个问题我没有更好的方法

判断两个点是不是在直线的同侧,可以通过连接这两点的线段与直线的相交情况来判断。
如果有直线的解析式f(x,y)=Ax+By+C=0,可以把两个点代入解析式f(x,y)看结果是否同号

判断两条平行射线AB、CD是否同向,可以通过线段BD和线段AC的交点来确定。
如果是用计算机进行判断或许会复杂很多,比如ABCD共线的情况,算交点会有问题
这个问题的解决方法应该是,计算B点坐标-A点坐标,检查结果向量的符号构成的向量,与D点坐标-C点坐标结果的符号构成的向量是否一致(有可能许多坐标的差是0,所以建议这两个符号向量相乘求和,看结果大于0(标识同号)等于0(表示不确定)还是小于0(表示异号)——当然也可以直接求向量AB跟向量CD的夹角余弦纸看看是否大于0)

对于ABC和DEF两个三点组,有没有不依赖直接图示,就能判断两个次序排列是否同向(顺时针或逆时针)的方法呢?
检查cos∠ABC与cos∠DEF是否同号

补充内容 (2019-12-15 22:41):
最后一行是检查sin∠ABC与sin∠DEF是否同号……算法是(用坐标的那种)三角形面积公式,没记错是个行列式,但长什么样子我忘了
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2019-12-14 23:09:03 | 显示全部楼层
.·.·. 发表于 2019-12-14 20:58
判断一个点是不是在一个多边形内部,可以通过以这一点为端点的射线与多边形的边的交点来判断。
这个问题我 ...

理论上∠ABC和∠CBA是一样的吧,但顺序相反,不知道该怎么利用余弦。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2019-12-15 11:09:24 | 显示全部楼层
2# 说的应该是有向角,但应该检查的是其正弦是否同号,
可用向量叉积,判断其是垂直于平面向外或向内;
也可计算其有向面积的符号(其本质原理与上述方法是一致的)。

点评

你是对的……写的时候脑子短路了  发表于 2019-12-15 22:42
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2019-12-15 15:30:27 | 显示全部楼层
又是计算几何问题,正好之前研究过。其实计算几何本身很少有直接计算交点之类来进行判断的,这样效率并不高(尤其是对于规模较大的情况下,这在游戏引擎中很常见),而且判断的情况大多是一个范围内属于某种情况,数学上这种类型只需要不等式就行了,也就是转化为判断正负符号问题。

第一个问题有更好更简单的方法——以内部点为坐标原点往各个顶点发射线,依次旋转一周(既然知道多边形,必然知道各个顶点的连结次序),射线转动角度代数和为 $2\pi$。但由于角度是无量纲量,且这个和是固定不变的,因此不需要每次都真的去计算反三角函数,而是通过判断方位即可,因此只需要判断顶点落在哪个象限上,然后设计一套取值规则(小心处理落在各个坐标轴上的情况),然后计算代数和。

第二个问题,无非就是方向向量到角的问题,或者说判断矢量积的符号问题,无需知道直线方程表达式。

第三个问题,仍然无需计算交点,同向意味着射线的方向向量共线且投影为正,也就是矢量积为零且内积为正。

第四个问题,默认为你所说的点是在平面上(因为你提到了顺时针和逆时针,空间不存在顺逆时针),这个问题更好办,同一个旋转方向意味着每组的三点所在平面的法向量的内积大于零,否则小于零。法向量怎么求,这个不用我说吧,相邻边矢量积就行。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2019-12-16 15:38:04 | 显示全部楼层
说一下第一个问题的细节。
以被测点O为原点,判断各个顶点所在的象限,依次检查相邻点象限序数增加量,如果象限增加1,那么可以理解为旋转了+pi/2,如果减1,则是-pi/2,如果增加了2或者减少了2(即相对象限),那么相当于旋转了pi,具体符号跟两个顶点矢量的矢量积符号相同(也就是如果相邻点是逆时针旋转的顺序,那么就是+pi,否则就是-pi)。然后把所有旋转角代数和求出来,等于0是在外部,不等于零的则是在边上或者内部,通过求相邻点矢量积和内积来判断原点在边上与否——只要矢量积为零,内积小于或等于零,那就是在边上。当然,具体编程实现中,上面增加和减少的角度可以用一个整数编码来表示(比如用pi/2的整数倍来编码),从而避免无理数计算。

算法时间复杂度为O(n),系数比很小,算法纯粹是乘法和加减法,非常简单。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-11-22 11:16 , Processed in 0.027857 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表