Actuators/actuator/angle_calc.py

82 lines
2.1 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""角度计算模块
角度定义∠M2-O-M
- O: 圆心 / 固定旋转中心(第一帧选定,全程不变)
- M: 初始尾端参考位置(第一帧选定,全程不变)
- M2: 当前帧尾端位置(每帧重新选定)
- 角度 = 向量 O→M 与 O→M2 之间的夹角0-180°
"""
import math
from typing import Tuple
def angle_between_vectors(
v1: Tuple[float, float], v2: Tuple[float, float]
) -> float:
"""计算两个向量之间的夹角(度)"""
dot = v1[0] * v2[0] + v1[1] * v2[1]
mag1 = math.hypot(v1[0], v1[1])
mag2 = math.hypot(v2[0], v2[1])
if mag1 < 1e-9 or mag2 < 1e-9:
return 0.0
cos_theta = max(-1.0, min(1.0, dot / (mag1 * mag2)))
return math.degrees(math.acos(cos_theta))
def signed_angle(
o: Tuple[float, float],
m: Tuple[float, float],
m2: Tuple[float, float],
) -> float:
"""计算带符号的 ∠M2-O-M 角度
Args:
o: 圆心(顶点)
m: 初始尾端参考位置
m2: 当前尾端位置
Returns:
带符号的角度(度),正=顺时针,负=逆时针
"""
v_ref = (m[0] - o[0], m[1] - o[1]) # O → M
v_cur = (m2[0] - o[0], m2[1] - o[1]) # O → M2
angle = angle_between_vectors(v_ref, v_cur)
# 叉积 Z 分量判断方向
cross_z = v_ref[0] * v_cur[1] - v_ref[1] * v_cur[0]
if cross_z < 0:
angle = -angle
return angle
def curvature_from_three_points(
o: Tuple[float, float],
m: Tuple[float, float],
m2: Tuple[float, float],
scale: float = 1.0,
) -> float:
"""由三点计算曲率Menger curvature
Args:
o, m, m2: 三个点
scale: 像素到物理单位的比例mm/pixel
Returns:
曲率 (1/mm)
"""
a = math.hypot(o[0] - m[0], o[1] - m[1]) * scale
b = math.hypot(m[0] - m2[0], m[1] - m2[1]) * scale
c = math.hypot(m2[0] - o[0], m2[1] - o[1]) * scale
s = (a + b + c) / 2.0
area = math.sqrt(max(0, s * (s - a) * (s - b) * (s - c)))
if area < 1e-12:
return 0.0
radius = (a * b * c) / (4.0 * area)
return 1.0 / radius if radius > 1e-12 else 0.0