Я написал функцию для вычисления косинуса, синуса и градусов угла между тремя точками, у которых у меня есть координаты x и y - точка 1 (x1, y1), точка 2 (x2, y2) и точка 3 (x3 , у3). Я написал функцию и пытался ее протестировать, но я не совсем уверен в ее точности. Кто-нибудь знает, не ошибся ли я в своих расчетах?
def path_angle_degree(x1, y1, x2, y2, x3, y3):
u = (x2 - x1, y2 - y1)
v = (x3 - x2, y3 - y2)
norm_u = math.sqrt(u[0] * u[0] + u[1] * u[1])
norm_v = math.sqrt(v[0] * v[0] + v[1] * v[1])
# this conditional is to check there has been movement between the points
if norm_u < 0.001 or norm_v < 0.001:
return (None, None, None)
prod_n = norm_u * norm_v
dot_uv = u[0] * v[0] + u[1] * v[1]
cos_uv = dot_uv / prod_n
# fixes floating point rounding
if cos_uv > 1.0 or cos_uv < -1.0:
cos_uv = round(cos_uv)
radians = math.acos(cos_uv)
sin_uv = math.sin(radians)
degree = math.degrees(radians)
return (cos_uv, sin_uv, degree)
Примером вызова этой функции на прямом пути может быть:
print(path_angle_degree(6,6,7,6,8,6))
Большое спасибо!
path_angle_degree(6,6,7,6,8,7)
иpath_angle_degree(6,6,7,6,8,5)
давали разные результаты? (Или, что то же самое, вы хотите иметь возможность различать поворот налево и поворот на ту же величину направо?) - person Mark Dickinson   schedule 16.04.2015norm_u = math.hypot(*u)
. Возможно, вы захотите округлить значенияcos_uv
, когдаabs(cos_uv)>1-EPSILON
, гдеEPSILON
— что-то маленькое, например 5.0E-12. - person PM 2Ring   schedule 16.04.2015math.atan2
: никаких квадратных корней или других триггерных вызовов не требуется.math.atan2(u[0]*v[1]-u[1]*v[0], u[0]*v[0]+u[1]*v[1])
должен это сделать. - person Mark Dickinson   schedule 16.04.2015acos
: он даст беззнаковый угол между 0 и пи. Только если вы хотите иметь возможность отличать повороты по часовой стрелке от поворотов против часовой стрелки, вам нужно больше, чем скалярный продукт. А можно я просто скажу: математика насекомых! Прохладный! - person Mark Dickinson   schedule 16.04.2015