Первоначально я предлагал использовать закон косинусов в векторной форме: если заданы два отрезка линии векторами b и c, а угол между ними равен θ, то
b · c = | b | | c | cos θ
и так
θ = cos −1 ((b · c) / | b | | c сильный> |)
Но, как отмечает Алекс Вин в комментариях, это дает плохие результаты, когда θ близко к нулю:
>>> theta = 1e-6
>>> a = Vector(1, 0)
>>> b = Vector(cos(theta), sin(theta))
>>> acos(a.dot(b) / (a.length * b.length))
9.999334257726859e-07
>>> abs(theta - _) / theta
6.657422731408927e-05
что является относительной ошибкой при получении доли из десяти тысяч. Для очень малых углов можно получить 100% относительную погрешность:
>>> theta = 1e-9
>>> a = Vector(1, 0)
>>> b = Vector(cos(theta), sin(theta))
>>> acos(a.dot(b) / (a.length * b.length))
0.0
Альтернативная формула использует арктангенс вместо арккосинуса:
θ = tan −1 (| a × b | / (a · b strong >))
и это дает более точный результат для малых углов:
>>> atan2(abs(a.cross(b)), a.dot(b))
1e-09
>>> theta == _
True
(Альтернативная формула следует из свойства перекрестного произведения, что | a < / strong> × b | = | a | | b | sin θ. Разделите это на закон косинусов, чтобы получить результат, используемый здесь .)
person
Gareth Rees
schedule
10.10.2013