python - 旋转参考系,改变角度计算比例
问题描述
我浪费了令人尴尬的时间来编写一个函数,该函数采用两个笛卡尔坐标origin
和target
,并指定箭头指向的角度,origin
其中target
零度[0,360)
是箭头笔直向上。
默认的pythonatan2()
会给我一个(-180,180]
零度箭头指向右边。
我可以将角度转换为 [0,360) 比例,但我找不到一种外观简洁的方法来将 0 度参考从指向右侧的向量更改为指向上方的向量。我做了一些例子来展示计算的演变以及它如何偏离我想要的。
def measure_angle_standard(origin, target):
x = target[0]-origin[0]
y = target[1]-origin[1]
#angle relative to X axis going clockwise-positive
angle_degrees = math.degrees(math.atan2(y,x))
return angle_degrees
def measure_angle_0_360(origin, target):
x = target[0]-origin[0]
y = target[1]-origin[1]
#angle relative to X axis going clockwise-positive
angle_degrees = math.degrees(math.atan2(y,x))
angle_degrees = (angle_degrees + 360) % 360
return angle_degrees
def measure_angle_up_is_zero(origin, target):
x = target[0]-origin[0]
y = target[1]-origin[1]
#angle relative to X axis going clockwise-positive
angle_degrees = math.degrees(math.atan2(y,x))
#angle_degrees = angle_degrees -90 # this is wrong!
angle_degrees = (angle_degrees + 360) % 360
angle_degrees = (angle_degrees - 90) % 180 # this is also wrong!
return angle_degrees
for v in [measure_angle_standard, measure_angle_0_360, measure_angle_up_is_zero ]:
print(f"\n\n {v}")
print("up slightly right", round(v( (5,5), (5.1,2)),1), " s/b tiny positive angle") #should be tiny positive angle
print("point up ", v( (5,5), (5,2)), " s/b 0" ) #should be zero
print("up slightly left ", round(v( (5,5), (4.9,2)),1), " s/b ~359 degrees") #should be almost 360
print("point right ", v( (5,5), (9,5)), " s/b 90") #should be 90
print("point left ", v( (5,5), (1,5)), " s/b 270") #should be 270
print("point down ", v( (5,5), (5,8)), " s/b 180") #should be 180
我看不出如何以非总的方式干净地获得最终轮换。
(在有人将此消息标记为重复消息之前,我已经在这里阅读了数十个类似的问题,其中大多数是用代码高尔夫片段咒语回答的半成形问题。我不感兴趣只是随机尝试黑客,直到我得到有效的东西。这些答案通常在边距 0、360 等处失败。)
<function measure_angle_standard at 0x7fecda0947b8>
up slightly right -88.1 s/b tiny positive angle
point up -90.0 s/b 0
up slightly left -91.9 s/b ~359 degrees
point right 0.0 s/b 90
point left 180.0 s/b 270
point down 90.0 s/b 180
<function measure_angle_0_360 at 0x7fecda040730>
up slightly right 271.9 s/b tiny positive angle
point up 270.0 s/b 0
up slightly left 268.1 s/b ~359 degrees
point right 0.0 s/b 90
point left 180.0 s/b 270
point down 90.0 s/b 180
<function measure_angle_up_is_zero at 0x7fecda0940d0>
up slightly right 1.9 s/b tiny positive angle
point up 0.0 s/b 0
up slightly left 178.1 s/b ~359 degrees
point right 90.0 s/b 90
point left 90.0 s/b 270
point down 0.0 s/b 180
解决方案
math.p1/2
在转换为度数之前,我用弧度移动它。
def measure_angle_up_is_zero(origin, target):
x = target[0]-origin[0]
y = target[1]-origin[1]
#angle relative to Y axis going clockwise-positive
angle_degrees = math.degrees(math.atan2(y,x)+ (math.pi/2.0))
angle_degrees = (angle_degrees + 360) % 360
return angle_degrees
这给了我想要的答案:
<function measure_angle_up_is_zero at 0x7fecda243400>
up slightly right 1.9 s/b tiny positive angle
point up 0.0 s/b 0
up slightly left 358.1 s/b ~359 degrees
slightly above right 88.56790381583534 s/b ~89
point right 90.0 s/b 90
slightly below right 91.43209618416466 s/b ~91
point left 270.0 s/b 270
point down 180.0 s/b 180
推荐阅读
- gremlin - 为什么 SELECT 然后执行类似 hasId() 的步骤会更改选择的内容?
- mysql - 通过 JOINS 从表中检索数据
- laravel - Laravel 4 - 上传大尺寸图片时出现 500 错误
- python - 根据时间戳值对对象进行排序
- javascript - 为什么 index.hmtl 文件和视图元素部分之间的 chrome 存在差异?
- jquery - 如何使用 JQuery 删除和添加新文本到 span 标签?
- sql - 当存在非零值时,更新查询仅显示零值。(使用权)
- swift - 核心数据后台线程返回插入的 NSManagedObject
- sql-server - 将数据分组为模糊的间隙和孤岛
- swift - UIView 内的自定义视图的触摸检测问题而不是 UIScrollView