Решение треугольника с использованием закона косинусов - PullRequest
2 голосов
/ 20 марта 2012

Я ищу решение треугольника, для которого я знаю длину трех сторон (треугольник SSS). Поэтому я хочу определить, имеют ли 3 «внутренние» углы формы, состоящей из 3 линий, = 180. Если это так, то форма должна быть треугольником.

Я использую формулу, найденную на этой странице Закон косинусов , для определения углов. В своем коде я делаю следующее:

private bool CalculateIfTriangle(float line1Length, float line2Length, float line3Length)
    {
        double angle1 = MathHelper.ToDegrees((float)Math.Cos(((line2Length * line2Length) + (line3Length * line3Length) - (line1Length * line1Length)) / (2 * line2Length * line3Length)));
        double angle2 = MathHelper.ToDegrees((float)Math.Cos(((line3Length * line3Length) + (line1Length * line1Length) - (line2Length * line2Length)) / (2 * line3Length * line1Length)));
        double angle3 = MathHelper.ToDegrees((float)Math.Cos(((line1Length * line1Length) + (line2Length * line2Length) - (line3Length * line3Length)) / (2 * line1Length * line2Length)));

        double total = angle1 + angle2 + angle3;
        if (total == 180)
            return true;
        else return false;
    }

Однако я не получаю правильных ответов (хотя форма определенно является треугольником).

Я пишу свое приложение на C # (XNA) и не уверен, правильно ли я использую метод MathHelper.ToDegrees.

Ответы [ 5 ]

5 голосов
/ 20 марта 2012

Закон:

c 2 = a 2 + b 2 - 2abcos (C)

Изменение порядка:

cos (C) = (a 2 + b 2 - c 2 ) / 2ab

C = cos -1 [(a 2 + b 2 - c 2 ) / 2ab]

Так почему вы используете Math.Cos вместо Math.Acos?

В любом случае, это одна из ваших ошибок, как говорили другие, выиспользование числа с плавающей запятой, поэтому сравнение на равенство является ошибкой из-за ошибок округления.

Кроме того, вам не нужно переводить обратно в градусы 180 градусов == пи радианы.

Кроме того, вам просто нужно сравнить длины сторон.В истинном треугольнике длина одной стороны всегда меньше суммы длин других сторон (см. Ответ Роулинга).Я подозреваю, что ваша формула, вероятно, даст NaN в качестве ответа для не треугольника, потому что вы в конечном итоге попытаетесь взять cos -1 числа, не входящего в диапазон [-1 .. 1].т.е.

(a 2 + b 2 - c 2 ) / 2ab> 1 или <-1 </p>

InЯ подозреваю, что условия для приведенной выше формулы находятся в нужном диапазоне именно тогда, когда

c <= a + b </p>

3 голосов
/ 20 марта 2012

Чтобы проверить, могут ли три длины образовывать треугольник, вам просто нужно проверить, что

A + B > C
A + C > B
B + C > A

(или равенство для вырожденного треугольника).

Расчет углов, образованных таким треугольником, не требуется. Если три длины не образуют треугольник, я не уверен, что углы будут иметь смысл.

1 голос
/ 20 марта 2012

Если у вас есть 3 линии, которые пересекаются два на два, вам не нужна тригонометрия, чтобы определить, что они образуют треугольник. Не используя trig, вы избегаете ошибки сравнения значения с плавающей точкой на равенство (например, total==180). Так как вы не указываете характер ошибок, которые у вас есть, только то, что вы не получаете правильный ответ, и поскольку ваш код выглядит нормально, это может быть источником вашей проблемы.

Незапрашиваемый совет: зачем беспокоиться о переходе в градусы, пока в этом нет необходимости? Вы могли бы сделать вещи более краткими (и более легкими для понимания), если бы вы работали в радианах, пока не захотите представить результаты в градусах.

1 голос
/ 20 марта 2012

Я вижу, что общее число - это число с плавающей точкой, а вы сравниваете его с 180. Потому что это обычно не очень хорошая идея, потому что число с плавающей запятой может иметь проблемы с точностью округления.

Для этого используйте проверку с проверкой диапазона, т.е.

if ((total > 179.9) && (total < 180.1)) 

или вообще:

accuracy = 0.1;
if ((total > 180.0 - accuracy) && (total < 180.0 + accuracy))
0 голосов
/ 20 марта 2012

Маловероятно, что все эти математические вычисления дадут ровно 180 градусов.Там будет небольшая ошибка, которая закрадывается.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...