/// <summary> /// Gets the name of a triangle with the given stats. /// </summary> /// <param name="stats">The stats object of the triangle.</param> /// <returns>The name of the triangle with the given stats.</returns> public static string GetTriangleName(TriangleStats stats) { var result = ""; switch (stats.Angle) { case TriangleAngle.Acute: result = "acute"; break; case TriangleAngle.Right: result = "right"; break; case TriangleAngle.Obtuse: result = "obtuse"; break; } switch (stats.Type) { case TriangleType.Equilateral: // all equilateral triangles are also acute triangles, so no need to keep it in the name result = "equilateral"; break; case TriangleType.Isosceles: result += " isosceles"; break; case TriangleType.Scalene: result += " scalene"; break; } return(result); }
/// <summary> /// Calculates the stats of a triangle with the given side lengths. /// Throws an exception if the sides do not create a valid triangle (triangles with zero area are allowed). /// </summary> /// <param name="sideA">The length of side A of the triangle.</param> /// <param name="sideB">The length of side B of the triangle.</param> /// <param name="sideC">The length of side C of the triangle.</param> /// <returns>An object containing the triangle's stats.</returns> public static TriangleStats GetTriangleStats(double sideA, double sideB, double sideC) { if (sideA < 0) { throw new ArgumentException(ERR_NEGATIVE_LENGTH, "sideA"); } if (sideB < 0) { throw new ArgumentException(ERR_NEGATIVE_LENGTH, "sideB"); } if (sideC < 0) { throw new ArgumentException(ERR_NEGATIVE_LENGTH, "sideC"); } if (sideC > sideA + sideB || sideA > sideB + sideC || sideB > sideC + sideA) { throw new InvalidTriangleException("No side's length can be greater than the sum of the other two."); } var info = new TriangleStats(); // check side lengths var AeqB = sideA == sideB; var BeqC = sideB == sideC; var CeqA = sideC == sideA; if (AeqB && BeqC) { info.Type = TriangleType.Equilateral; } else if (AeqB || BeqC || CeqA) { info.Type = TriangleType.Isosceles; } else { info.Type = TriangleType.Scalene; } // check angles // uses cosine rule to calculate angles A and B, and subtract both from 180 degrees to find C var angA = Math.Acos((Math.Pow(sideB, 2) + Math.Pow(sideC, 2) - Math.Pow(sideA, 2)) / (2 * sideB * sideC)); var angB = Math.Acos((Math.Pow(sideA, 2) + Math.Pow(sideC, 2) - Math.Pow(sideB, 2)) / (2 * sideA * sideC)); var angC = Math.PI - angA - angB; // allow a small margin of error to account for floating-point innacuracy if (Math.Abs(angA - RIGHT_ANGLE) < FP_MARGIN || Math.Abs(angB - RIGHT_ANGLE) < FP_MARGIN || Math.Abs(angC - RIGHT_ANGLE) < FP_MARGIN) { info.Angle = TriangleAngle.Right; } else if (angA > RIGHT_ANGLE || angB > RIGHT_ANGLE || angC > RIGHT_ANGLE) { info.Angle = TriangleAngle.Obtuse; } else { info.Angle = TriangleAngle.Acute; } return(info); }
protected string GetTriangleMessage(TriangleStats info) { return(string.Format(VALID_RESULT_TEXT, TriangleChecker.GetTriangleName(info))); }