mirror of
https://github.com/TheAlgorithms/Java.git
synced 2025-12-19 07:00:35 +08:00
refactor: Enhance docs, code, add tests in HeronsFormula (#6746)
* refactor: Enhance docs, code, add tests in `HeronsFormula` * Fix lint
This commit is contained in:
@@ -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.
|
||||
* <p>
|
||||
* 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
|
||||
* </p>
|
||||
*
|
||||
* @see <a href="https://en.wikipedia.org/wiki/Heron%27s_formula">Heron's
|
||||
* Formula - Wikipedia</a>
|
||||
* @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.
|
||||
* <p>
|
||||
* The triangle inequality theorem states that the sum of any two sides
|
||||
* of a triangle must be greater than the third side.
|
||||
* </p>
|
||||
*
|
||||
* @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.
|
||||
* <p>
|
||||
* 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
|
||||
* </p>
|
||||
*
|
||||
* @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));
|
||||
|
||||
@@ -3,37 +3,141 @@ package com.thealgorithms.maths;
|
||||
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 test1() {
|
||||
Assertions.assertEquals(HeronsFormula.herons(3, 4, 5), 6.0);
|
||||
void testRightTriangleThreeFourFive() {
|
||||
Assertions.assertEquals(6.0, HeronsFormula.herons(3, 4, 5), EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
void test2() {
|
||||
Assertions.assertEquals(HeronsFormula.herons(24, 30, 18), 216.0);
|
||||
void testTriangleTwentyFourThirtyEighteen() {
|
||||
Assertions.assertEquals(216.0, HeronsFormula.herons(24, 30, 18), EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
void test3() {
|
||||
Assertions.assertEquals(HeronsFormula.herons(1, 1, 1), 0.4330127018922193);
|
||||
void testEquilateralTriangle() {
|
||||
Assertions.assertEquals(0.4330127018922193, HeronsFormula.herons(1, 1, 1), EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
void test4() {
|
||||
Assertions.assertEquals(HeronsFormula.herons(4, 5, 8), 8.181534085976786);
|
||||
void testScaleneTriangleFourFiveEight() {
|
||||
Assertions.assertEquals(8.181534085976786, HeronsFormula.herons(4, 5, 8), EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCalculateAreaWithInvalidInput() {
|
||||
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 testIsoscelesTriangle() {
|
||||
Assertions.assertEquals(12.0, HeronsFormula.herons(5, 5, 6), EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSmallTriangle() {
|
||||
Assertions.assertEquals(0.4330127018922193, HeronsFormula.herons(1.0, 1.0, 1.0), EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLargeTriangle() {
|
||||
Assertions.assertEquals(600.0, HeronsFormula.herons(30, 40, 50), EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDecimalSides() {
|
||||
final double area = HeronsFormula.herons(2.5, 3.5, 4.0);
|
||||
Assertions.assertTrue(area > 0);
|
||||
Assertions.assertEquals(4.330127018922194, area, EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDegenerateTriangleEqualToSumOfOtherTwo() {
|
||||
Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(1, 2, 3); });
|
||||
Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(2, 1, 3); });
|
||||
Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(3, 2, 1); });
|
||||
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 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); });
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user