heyred
heyred

Reputation: 2051

Solving a triangle using the Law of Cosines

I'm looking to solve a triangle of which I know the lengths of the 3 sides (a SSS triangle). Therefore, I want to determine if the 3 "inner" angles of a shape consisting of 3 lines = 180. If it does, then the shape must be a triangle.

I'm using the formula found on this The Law of Cosines page to solve for the angles. In my code I do the following:

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;
    }

However, I'm not getting the correct answers (even though the shape is definitely a triangle).

I'm coding my application in C# (XNA) and I'm not sure if I'm using the MathHelper.ToDegrees method correctly.

Upvotes: 2

Views: 6942

Answers (5)

JeremyP
JeremyP

Reputation: 86651

The law is

c2 = a2 + b2 - 2abcos(C)

Rearranging:

cos(C) = (a2 + b2 - c2) / 2ab

C = cos-1 [(a2 + b2 - c2) / 2ab]

So why are you using Math.Cos instead of Math.Acos?

Anyway, that's one of your bugs, as others have said, you are using floating point so comparing for equality is a bit hit and miss due to rounding errors.

Also, you don't need to convert back to degrees 180 degees == pi radians.

Also, you just have to compare the lengths of the sides. In a true triangle, the length of one side is always shorter than the sum of the lengths of the other sides (see Rawling's answer). I suspect, your formula will probably give NaN as the answer for a non triangle because you'll end up trying to take cos-1 of a number not in the range [-1 .. 1]. i.e.

(a2 + b2 - c2) / 2ab > 1 or < -1

In fact I suspect that the conditions for the above formula to be in the right range are exactly when

c <= a + b

Upvotes: 5

Rawling
Rawling

Reputation: 50104

To check if three lengths can form a triangle, you merely need to check that

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

(or equality for a degenrate triangle).

Calculating the angles formed by such a triangle is unnecessary. If the three lengths don't form a triangle, I'm not sure the angles will even make sense.

Upvotes: 3

High Performance Mark
High Performance Mark

Reputation: 78306

If you have 3 lines which intersect two-by-two you don't need trigonometry to determine that they form a triangle. By not using trig you avoid the error of comparing a floating-point value for equality (eg total==180). Since your don't specify the nature of the errors you have, only that you're not getting the correct answer, and since your code looks OK, this might be the source of your problem.

Unasked-for advice: why bother converting to degrees until you absolutely have to ? You could make things briefer (and easier to comprehend) if you worked in radians until you want to present the results in degrees.

Upvotes: 1

Michel Keijzers
Michel Keijzers

Reputation: 15347

I see that total is a float and you compare it to 180. Because this is normally not a good idea because floating point number can have accuracy rounding problems.

Therefor use a check with range checking, i.e.

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

or generally:

accuracy = 0.1;
if ((total > 180.0 - accuracy) && (total < 180.0 + accuracy))

Upvotes: 1

spender
spender

Reputation: 120380

It's highly unlikely that all that fp maths will yield exactly 180 degrees. There'll be a small amount of error that creeps in.

Upvotes: -1

Related Questions