Skip to content

Commit f460c60

Browse files
authored
refactor: Enhance docs, code, add tests in HeronsFormula (#6746)
* refactor: Enhance docs, code, add tests in `HeronsFormula` * Fix lint
1 parent d62b438 commit f460c60

File tree

2 files changed

+170
-23
lines changed

2 files changed

+170
-23
lines changed

src/main/java/com/thealgorithms/maths/HeronsFormula.java

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,76 @@
11
package com.thealgorithms.maths;
22

33
/**
4-
* Wikipedia for HeronsFormula => https://en.wikipedia.org/wiki/Heron%27s_formula
5-
* Find the area of a triangle using only side lengths
4+
* Heron's Formula implementation for calculating the area of a triangle given
5+
* its three side lengths.
6+
* <p>
7+
* Heron's Formula states that the area of a triangle whose sides have lengths
8+
* a, b, and c is:
9+
* Area = √(s(s - a)(s - b)(s - c))
10+
* where s is the semi-perimeter of the triangle: s = (a + b + c) / 2
11+
* </p>
12+
*
13+
* @see <a href="https://en.wikipedia.org/wiki/Heron%27s_formula">Heron's
14+
* Formula - Wikipedia</a>
15+
* @author satyabarghav
616
*/
7-
817
public final class HeronsFormula {
918

10-
/*
11-
* A function to get the Area of a Triangle using Heron's Formula
12-
* @param s1,s2,s3 => the three sides of the Triangle
13-
* @return area using the formula (√(s(s – s1)(s – s2)(s – s3)))
14-
* here s is called semi-perimeter and it is the half of the perimeter (i.e; s = (s1+s2+s3)/2)
15-
* @author satyabarghav
19+
/**
20+
* Private constructor to prevent instantiation of this utility class.
1621
*/
1722
private HeronsFormula() {
1823
}
1924

25+
/**
26+
* Checks if all three side lengths are positive.
27+
*
28+
* @param a the length of the first side
29+
* @param b the length of the second side
30+
* @param c the length of the third side
31+
* @return true if all sides are positive, false otherwise
32+
*/
2033
private static boolean areAllSidesPositive(final double a, final double b, final double c) {
2134
return a > 0 && b > 0 && c > 0;
2235
}
2336

37+
/**
38+
* Checks if the given side lengths satisfy the triangle inequality theorem.
39+
* <p>
40+
* The triangle inequality theorem states that the sum of any two sides
41+
* of a triangle must be greater than the third side.
42+
* </p>
43+
*
44+
* @param a the length of the first side
45+
* @param b the length of the second side
46+
* @param c the length of the third side
47+
* @return true if the sides can form a valid triangle, false otherwise
48+
*/
2449
private static boolean canFormTriangle(final double a, final double b, final double c) {
2550
return a + b > c && b + c > a && c + a > b;
2651
}
2752

53+
/**
54+
* Calculates the area of a triangle using Heron's Formula.
55+
* <p>
56+
* Given three side lengths a, b, and c, the area is computed as:
57+
* Area = √(s(s - a)(s - b)(s - c))
58+
* where s is the semi-perimeter: s = (a + b + c) / 2
59+
* </p>
60+
*
61+
* @param a the length of the first side (must be positive)
62+
* @param b the length of the second side (must be positive)
63+
* @param c the length of the third side (must be positive)
64+
* @return the area of the triangle
65+
* @throws IllegalArgumentException if any side length is non-positive or if the
66+
* sides cannot form a valid triangle
67+
*/
2868
public static double herons(final double a, final double b, final double c) {
29-
if (!areAllSidesPositive(a, b, c) || !canFormTriangle(a, b, c)) {
30-
throw new IllegalArgumentException("Triangle can't be formed with the given side lengths");
69+
if (!areAllSidesPositive(a, b, c)) {
70+
throw new IllegalArgumentException("All side lengths must be positive");
71+
}
72+
if (!canFormTriangle(a, b, c)) {
73+
throw new IllegalArgumentException("Triangle cannot be formed with the given side lengths (violates triangle inequality)");
3174
}
3275
final double s = (a + b + c) / 2.0;
3376
return Math.sqrt((s) * (s - a) * (s - b) * (s - c));

src/test/java/com/thealgorithms/maths/HeronsFormulaTest.java

Lines changed: 116 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,37 +3,141 @@
33
import org.junit.jupiter.api.Assertions;
44
import org.junit.jupiter.api.Test;
55

6-
public class HeronsFormulaTest {
6+
/**
7+
* Test cases for {@link HeronsFormula}.
8+
*/
9+
class HeronsFormulaTest {
10+
11+
private static final double EPSILON = 1e-10;
12+
13+
@Test
14+
void testRightTriangleThreeFourFive() {
15+
Assertions.assertEquals(6.0, HeronsFormula.herons(3, 4, 5), EPSILON);
16+
}
17+
18+
@Test
19+
void testTriangleTwentyFourThirtyEighteen() {
20+
Assertions.assertEquals(216.0, HeronsFormula.herons(24, 30, 18), EPSILON);
21+
}
22+
23+
@Test
24+
void testEquilateralTriangle() {
25+
Assertions.assertEquals(0.4330127018922193, HeronsFormula.herons(1, 1, 1), EPSILON);
26+
}
27+
28+
@Test
29+
void testScaleneTriangleFourFiveEight() {
30+
Assertions.assertEquals(8.181534085976786, HeronsFormula.herons(4, 5, 8), EPSILON);
31+
}
32+
33+
@Test
34+
void testEquilateralTriangleLargeSides() {
35+
final double side = 10.0;
36+
final double expectedArea = Math.sqrt(3) / 4 * side * side;
37+
Assertions.assertEquals(expectedArea, HeronsFormula.herons(side, side, side), EPSILON);
38+
}
739

840
@Test
9-
void test1() {
10-
Assertions.assertEquals(HeronsFormula.herons(3, 4, 5), 6.0);
41+
void testIsoscelesTriangle() {
42+
Assertions.assertEquals(12.0, HeronsFormula.herons(5, 5, 6), EPSILON);
1143
}
1244

1345
@Test
14-
void test2() {
15-
Assertions.assertEquals(HeronsFormula.herons(24, 30, 18), 216.0);
46+
void testSmallTriangle() {
47+
Assertions.assertEquals(0.4330127018922193, HeronsFormula.herons(1.0, 1.0, 1.0), EPSILON);
1648
}
1749

1850
@Test
19-
void test3() {
20-
Assertions.assertEquals(HeronsFormula.herons(1, 1, 1), 0.4330127018922193);
51+
void testLargeTriangle() {
52+
Assertions.assertEquals(600.0, HeronsFormula.herons(30, 40, 50), EPSILON);
2153
}
2254

2355
@Test
24-
void test4() {
25-
Assertions.assertEquals(HeronsFormula.herons(4, 5, 8), 8.181534085976786);
56+
void testDecimalSides() {
57+
final double area = HeronsFormula.herons(2.5, 3.5, 4.0);
58+
Assertions.assertTrue(area > 0);
59+
Assertions.assertEquals(4.330127018922194, area, EPSILON);
2660
}
2761

2862
@Test
29-
public void testCalculateAreaWithInvalidInput() {
63+
void testDegenerateTriangleEqualToSumOfOtherTwo() {
3064
Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(1, 2, 3); });
65+
}
66+
67+
@Test
68+
void testDegenerateTriangleVariant2() {
3169
Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(2, 1, 3); });
70+
}
71+
72+
@Test
73+
void testDegenerateTriangleVariant3() {
3274
Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(3, 2, 1); });
75+
}
76+
77+
@Test
78+
void testDegenerateTriangleVariant4() {
3379
Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(1, 3, 2); });
80+
}
3481

35-
Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(1, 1, 0); });
36-
Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(1, 0, 1); });
82+
@Test
83+
void testInvalidTriangleSideGreaterThanSum() {
84+
Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(1, 1, 5); });
85+
}
86+
87+
@Test
88+
void testZeroFirstSide() {
3789
Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(0, 1, 1); });
3890
}
91+
92+
@Test
93+
void testZeroSecondSide() {
94+
Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(1, 0, 1); });
95+
}
96+
97+
@Test
98+
void testZeroThirdSide() {
99+
Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(1, 1, 0); });
100+
}
101+
102+
@Test
103+
void testNegativeFirstSide() {
104+
Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(-1, 2, 2); });
105+
}
106+
107+
@Test
108+
void testNegativeSecondSide() {
109+
Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(2, -1, 2); });
110+
}
111+
112+
@Test
113+
void testNegativeThirdSide() {
114+
Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(2, 2, -1); });
115+
}
116+
117+
@Test
118+
void testAllNegativeSides() {
119+
Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(-1, -2, -3); });
120+
}
121+
122+
@Test
123+
void testAllZeroSides() {
124+
Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(0, 0, 0); });
125+
}
126+
127+
@Test
128+
void testVerySmallTriangle() {
129+
final double result = HeronsFormula.herons(0.001, 0.001, 0.001);
130+
Assertions.assertTrue(result > 0);
131+
Assertions.assertTrue(result < 0.001);
132+
}
133+
134+
@Test
135+
void testRightTriangleFiveTwelveThirteen() {
136+
Assertions.assertEquals(30.0, HeronsFormula.herons(5, 12, 13), EPSILON);
137+
}
138+
139+
@Test
140+
void testRightTriangleEightFifteenSeventeen() {
141+
Assertions.assertEquals(60.0, HeronsFormula.herons(8, 15, 17), EPSILON);
142+
}
39143
}

0 commit comments

Comments
 (0)