圆上点 v1、v2 之间的连接方向,有障碍物(阻塞间隔 [s, e])
direction of connection between points v1, v2 on a circle, with obstacles (blocking interval [s, e])
我知道标题似乎不好 - 请随意指定。我想不出更好的标题。
所有点均以相对于圆心的极坐标表示。两个点 (v1, v2, s, e) 位于圆边上。如图,s & e是粉点,s = blocked_arc_start_angle, e = blocked_arc_end_angle。
问题:
我如何检查圆上的哪个方向没有被阻挡?方向我的意思是顺时针(CW,数学负)或逆时针(CCW,数学正)。
所有角度都归一化,范围为[-PI, PI]
我尝试了很多 if-else 个案例检查,但由于 atan2 的范围,我遇到了问题。有简单的方法吗?
有什么想法吗?
问候!
我还在寻找更好的解决方案!!!没有人喜欢很多 if-else 电话...*
丑答:
我考虑了所有可能发生的情况,你可以通过想象角度的范围轻松拆分 space:
1st case - obstacle/blocked arc/interval is not overlapping:
-Pi PI
|-------------S::::::::E-------------|
2nd case - obstacle/blocked arc/interval is overlapping:
-Pi PI
|::::E--------------------------S::::|
等等...
重要: 如果点位于阻塞区间内,请提前检查:
# no point is inside of a blocked arc
if m.point_inside_arc(v1.location, arc) or m.point_inside_arc(v2.location, arc):
return False
这是一些伪代码。希望这对某些人有所帮助。
if arc.start_angle < arc.end_angle:
if angle_v1 < angle_v2 < arc.start_angle or arc.end_angle < angle_v1 < angle_v2:
# |----V1---V2----S::::::::E----(V1---V2)----|
math_negative = False
elif angle_v2 < angle_v1 < arc.start_angle or arc.end_angle < angle_v2 < angle_v1:
# |----V2---V1----S::::::::E----(V2---V1)----|
math_positive = False
elif angle_v1 < arc.start_angle and arc.end_angle < angle_v2:
# |----V1---------S::::::::E---------V2----|
math_positive = False
elif angle_v2 < arc.start_angle and arc.end_angle < angle_v1:
# |----V2---------S::::::::E---------V1----|
math_negative = False
else:
# |::::E-------------------------S::::|
if angle_v1 < angle_v2:
math_negative = False
else:
math_positive = False
设c为圆心。那么如果你计算:
dot = DotProduct( p1 - c, p2 - c )
所有两个条件都为真的点 v:
DotProduct( v - c, p1 - c ) > dot
DotProduct( v - c, p2 - c ) > dot
会在封锁区
为了知道方向,您也可以使用点积。由于点积是向量之间夹角的余弦值(假设两个向量都是单一的),您可以为每个点 p1 和 p2 计算角度 alpha:
cos( alpha ) = DotProduct( vector( 1, 0 ), ( p1 - c ).normalized );
获得alpha后,必须使用(p1-c)的分量y的值。
如果为负数,则将 alpha 加 180 度。
以 2π 为模减少两个角度。那么如果e < s,则圆从0到s,从e到2π;否则,圆从 s 到 e 被揭开。
我知道标题似乎不好 - 请随意指定。我想不出更好的标题。
所有点均以相对于圆心的极坐标表示。两个点 (v1, v2, s, e) 位于圆边上。如图,s & e是粉点,s = blocked_arc_start_angle, e = blocked_arc_end_angle。
问题:
我如何检查圆上的哪个方向没有被阻挡?方向我的意思是顺时针(CW,数学负)或逆时针(CCW,数学正)。
所有角度都归一化,范围为[-PI, PI]
我尝试了很多 if-else 个案例检查,但由于 atan2 的范围,我遇到了问题。有简单的方法吗?
有什么想法吗?
问候!
我还在寻找更好的解决方案!!!没有人喜欢很多 if-else 电话...*
丑答:
我考虑了所有可能发生的情况,你可以通过想象角度的范围轻松拆分 space:
1st case - obstacle/blocked arc/interval is not overlapping:
-Pi PI
|-------------S::::::::E-------------|
2nd case - obstacle/blocked arc/interval is overlapping:
-Pi PI
|::::E--------------------------S::::|
等等...
重要: 如果点位于阻塞区间内,请提前检查:
# no point is inside of a blocked arc
if m.point_inside_arc(v1.location, arc) or m.point_inside_arc(v2.location, arc):
return False
这是一些伪代码。希望这对某些人有所帮助。
if arc.start_angle < arc.end_angle:
if angle_v1 < angle_v2 < arc.start_angle or arc.end_angle < angle_v1 < angle_v2:
# |----V1---V2----S::::::::E----(V1---V2)----|
math_negative = False
elif angle_v2 < angle_v1 < arc.start_angle or arc.end_angle < angle_v2 < angle_v1:
# |----V2---V1----S::::::::E----(V2---V1)----|
math_positive = False
elif angle_v1 < arc.start_angle and arc.end_angle < angle_v2:
# |----V1---------S::::::::E---------V2----|
math_positive = False
elif angle_v2 < arc.start_angle and arc.end_angle < angle_v1:
# |----V2---------S::::::::E---------V1----|
math_negative = False
else:
# |::::E-------------------------S::::|
if angle_v1 < angle_v2:
math_negative = False
else:
math_positive = False
设c为圆心。那么如果你计算:
dot = DotProduct( p1 - c, p2 - c )
所有两个条件都为真的点 v:
DotProduct( v - c, p1 - c ) > dot
DotProduct( v - c, p2 - c ) > dot
会在封锁区
为了知道方向,您也可以使用点积。由于点积是向量之间夹角的余弦值(假设两个向量都是单一的),您可以为每个点 p1 和 p2 计算角度 alpha:
cos( alpha ) = DotProduct( vector( 1, 0 ), ( p1 - c ).normalized );
获得alpha后,必须使用(p1-c)的分量y的值。
如果为负数,则将 alpha 加 180 度。
以 2π 为模减少两个角度。那么如果e < s,则圆从0到s,从e到2π;否则,圆从 s 到 e 被揭开。