diff --git a/src/main/java/com/thealgorithms/maths/HeronsFormula.java b/src/main/java/com/thealgorithms/maths/HeronsFormula.java index 5baee715d1ec..10438e2888b9 100644 --- a/src/main/java/com/thealgorithms/maths/HeronsFormula.java +++ b/src/main/java/com/thealgorithms/maths/HeronsFormula.java @@ -1,33 +1,76 @@ package com.thealgorithms.maths; /** - * Wikipedia for HeronsFormula => https://en.wikipedia.org/wiki/Heron%27s_formula - * Find the area of a triangle using only side lengths + * Heron's Formula implementation for calculating the area of a triangle given + * its three side lengths. + *

+ * Heron's Formula states that the area of a triangle whose sides have lengths + * a, b, and c is: + * Area = √(s(s - a)(s - b)(s - c)) + * where s is the semi-perimeter of the triangle: s = (a + b + c) / 2 + *

+ * + * @see Heron's + * Formula - Wikipedia + * @author satyabarghav */ - public final class HeronsFormula { - /* - * A function to get the Area of a Triangle using Heron's Formula - * @param s1,s2,s3 => the three sides of the Triangle - * @return area using the formula (√(s(s – s1)(s – s2)(s – s3))) - * here s is called semi-perimeter and it is the half of the perimeter (i.e; s = (s1+s2+s3)/2) - * @author satyabarghav + /** + * Private constructor to prevent instantiation of this utility class. */ private HeronsFormula() { } + /** + * Checks if all three side lengths are positive. + * + * @param a the length of the first side + * @param b the length of the second side + * @param c the length of the third side + * @return true if all sides are positive, false otherwise + */ private static boolean areAllSidesPositive(final double a, final double b, final double c) { return a > 0 && b > 0 && c > 0; } + /** + * Checks if the given side lengths satisfy the triangle inequality theorem. + *

+ * The triangle inequality theorem states that the sum of any two sides + * of a triangle must be greater than the third side. + *

+ * + * @param a the length of the first side + * @param b the length of the second side + * @param c the length of the third side + * @return true if the sides can form a valid triangle, false otherwise + */ private static boolean canFormTriangle(final double a, final double b, final double c) { return a + b > c && b + c > a && c + a > b; } + /** + * Calculates the area of a triangle using Heron's Formula. + *

+ * Given three side lengths a, b, and c, the area is computed as: + * Area = √(s(s - a)(s - b)(s - c)) + * where s is the semi-perimeter: s = (a + b + c) / 2 + *

+ * + * @param a the length of the first side (must be positive) + * @param b the length of the second side (must be positive) + * @param c the length of the third side (must be positive) + * @return the area of the triangle + * @throws IllegalArgumentException if any side length is non-positive or if the + * sides cannot form a valid triangle + */ public static double herons(final double a, final double b, final double c) { - if (!areAllSidesPositive(a, b, c) || !canFormTriangle(a, b, c)) { - throw new IllegalArgumentException("Triangle can't be formed with the given side lengths"); + if (!areAllSidesPositive(a, b, c)) { + throw new IllegalArgumentException("All side lengths must be positive"); + } + if (!canFormTriangle(a, b, c)) { + throw new IllegalArgumentException("Triangle cannot be formed with the given side lengths (violates triangle inequality)"); } final double s = (a + b + c) / 2.0; return Math.sqrt((s) * (s - a) * (s - b) * (s - c)); diff --git a/src/test/java/com/thealgorithms/maths/HeronsFormulaTest.java b/src/test/java/com/thealgorithms/maths/HeronsFormulaTest.java index 22cecf4dc960..5175c6348c9f 100644 --- a/src/test/java/com/thealgorithms/maths/HeronsFormulaTest.java +++ b/src/test/java/com/thealgorithms/maths/HeronsFormulaTest.java @@ -3,37 +3,141 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -public class HeronsFormulaTest { +/** + * Test cases for {@link HeronsFormula}. + */ +class HeronsFormulaTest { + + private static final double EPSILON = 1e-10; + + @Test + void testRightTriangleThreeFourFive() { + Assertions.assertEquals(6.0, HeronsFormula.herons(3, 4, 5), EPSILON); + } + + @Test + void testTriangleTwentyFourThirtyEighteen() { + Assertions.assertEquals(216.0, HeronsFormula.herons(24, 30, 18), EPSILON); + } + + @Test + void testEquilateralTriangle() { + Assertions.assertEquals(0.4330127018922193, HeronsFormula.herons(1, 1, 1), EPSILON); + } + + @Test + void testScaleneTriangleFourFiveEight() { + Assertions.assertEquals(8.181534085976786, HeronsFormula.herons(4, 5, 8), EPSILON); + } + + @Test + void testEquilateralTriangleLargeSides() { + final double side = 10.0; + final double expectedArea = Math.sqrt(3) / 4 * side * side; + Assertions.assertEquals(expectedArea, HeronsFormula.herons(side, side, side), EPSILON); + } @Test - void test1() { - Assertions.assertEquals(HeronsFormula.herons(3, 4, 5), 6.0); + void testIsoscelesTriangle() { + Assertions.assertEquals(12.0, HeronsFormula.herons(5, 5, 6), EPSILON); } @Test - void test2() { - Assertions.assertEquals(HeronsFormula.herons(24, 30, 18), 216.0); + void testSmallTriangle() { + Assertions.assertEquals(0.4330127018922193, HeronsFormula.herons(1.0, 1.0, 1.0), EPSILON); } @Test - void test3() { - Assertions.assertEquals(HeronsFormula.herons(1, 1, 1), 0.4330127018922193); + void testLargeTriangle() { + Assertions.assertEquals(600.0, HeronsFormula.herons(30, 40, 50), EPSILON); } @Test - void test4() { - Assertions.assertEquals(HeronsFormula.herons(4, 5, 8), 8.181534085976786); + void testDecimalSides() { + final double area = HeronsFormula.herons(2.5, 3.5, 4.0); + Assertions.assertTrue(area > 0); + Assertions.assertEquals(4.330127018922194, area, EPSILON); } @Test - public void testCalculateAreaWithInvalidInput() { + void testDegenerateTriangleEqualToSumOfOtherTwo() { Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(1, 2, 3); }); + } + + @Test + void testDegenerateTriangleVariant2() { Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(2, 1, 3); }); + } + + @Test + void testDegenerateTriangleVariant3() { Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(3, 2, 1); }); + } + + @Test + void testDegenerateTriangleVariant4() { Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(1, 3, 2); }); + } - Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(1, 1, 0); }); - Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(1, 0, 1); }); + @Test + void testInvalidTriangleSideGreaterThanSum() { + Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(1, 1, 5); }); + } + + @Test + void testZeroFirstSide() { Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(0, 1, 1); }); } + + @Test + void testZeroSecondSide() { + Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(1, 0, 1); }); + } + + @Test + void testZeroThirdSide() { + Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(1, 1, 0); }); + } + + @Test + void testNegativeFirstSide() { + Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(-1, 2, 2); }); + } + + @Test + void testNegativeSecondSide() { + Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(2, -1, 2); }); + } + + @Test + void testNegativeThirdSide() { + Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(2, 2, -1); }); + } + + @Test + void testAllNegativeSides() { + Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(-1, -2, -3); }); + } + + @Test + void testAllZeroSides() { + Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(0, 0, 0); }); + } + + @Test + void testVerySmallTriangle() { + final double result = HeronsFormula.herons(0.001, 0.001, 0.001); + Assertions.assertTrue(result > 0); + Assertions.assertTrue(result < 0.001); + } + + @Test + void testRightTriangleFiveTwelveThirteen() { + Assertions.assertEquals(30.0, HeronsFormula.herons(5, 12, 13), EPSILON); + } + + @Test + void testRightTriangleEightFifteenSeventeen() { + Assertions.assertEquals(60.0, HeronsFormula.herons(8, 15, 17), EPSILON); + } }