Skip to content

Commit e727eb6

Browse files
committed
feat: add geometry triangle
1 parent 9010481 commit e727eb6

File tree

2 files changed

+138
-0
lines changed

2 files changed

+138
-0
lines changed

Geometry/Test/Triangle.test.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import Triangle from '../Triangle'
2+
3+
describe('Triangle', () => {
4+
describe('Triangle created with sides', () => {
5+
const triangle = new Triangle(3, 4, 5)
6+
7+
test('The area of a triangle with sides 3, 4, 5', () => {
8+
expect(parseFloat(triangle.area().toFixed(2))).toEqual(6.0)
9+
})
10+
11+
test('The perimeter of a triangle with sides 3, 4, 5', () => {
12+
expect(parseFloat(triangle.perimeter().toFixed(2))).toEqual(12.0)
13+
})
14+
})
15+
16+
describe('Triangle created with base and height', () => {
17+
const triangle = new Triangle(6, 4)
18+
19+
test('The area of a triangle with base 6 and height 4', () => {
20+
expect(parseFloat(triangle.area().toFixed(2))).toEqual(12.0)
21+
})
22+
23+
test('The perimeter calculation throws an error for base-height triangle', () => {
24+
expect(() => triangle.perimeter()).toThrow(
25+
'Cannot calculate perimeter: not all sides are known.'
26+
)
27+
})
28+
})
29+
30+
describe('Invalid triangle creation', () => {
31+
test('Creating a triangle with invalid sides throws an error', () => {
32+
expect(() => new Triangle(1, 1, 10)).toThrow(
33+
'Invalid triangle: The sum of any two sides must be greater than the third side.'
34+
)
35+
})
36+
37+
test('Creating a triangle with invalid number of arguments throws an error', () => {
38+
expect(() => new Triangle(1)).toThrow(
39+
'Invalid number of arguments. Use either (base, height) or (sideA, sideB, sideC).'
40+
)
41+
})
42+
})
43+
})

Geometry/Triangle.js

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/**
2+
* This class represents a Triangle and can calculate its area and perimeter with either all three sides or the base and height.
3+
* https://en.wikipedia.org/wiki/Triangle
4+
* @class
5+
*/
6+
export default class Triangle {
7+
/**
8+
* Create a triangle.
9+
* @constructor
10+
* @param {...number} args - The triangle dimensions.
11+
* @throws {Error} Will throw an error if the number of arguments is invalid or if the triangle is invalid.
12+
*/
13+
constructor(...args) {
14+
if (args.length === 2) {
15+
this.initializeFromBaseAndHeight(...args)
16+
} else if (args.length === 3) {
17+
this.initializeFromSides(...args)
18+
} else {
19+
throw new Error(
20+
'Invalid number of arguments. Use either (base, height) or (sideA, sideB, sideC).'
21+
)
22+
}
23+
}
24+
25+
/**
26+
* Initialize the triangle from base and height.
27+
* @param {number} base - The base of the triangle.
28+
* @param {number} height - The height of the triangle.
29+
* @private
30+
*/
31+
initializeFromBaseAndHeight = (base, height) => {
32+
this.base = base
33+
this.height = height
34+
this.sides = [base, null, null]
35+
}
36+
37+
/**
38+
* Initialize the triangle from three sides.
39+
* @param {number} sideA - The length of side A.
40+
* @param {number} sideB - The length of side B.
41+
* @param {number} sideC - The length of side C.
42+
* @throws {Error} Will throw an error if the triangle is invalid.
43+
* @private
44+
*/
45+
initializeFromSides = (sideA, sideB, sideC) => {
46+
if (!this.isValidTriangle(sideA, sideB, sideC)) {
47+
throw new Error(
48+
'Invalid triangle: The sum of any two sides must be greater than the third side.'
49+
)
50+
}
51+
this.sides = [sideA, sideB, sideC]
52+
this.base = sideA
53+
this.height = null
54+
}
55+
56+
/**
57+
* Check if three sides can form a valid triangle.
58+
* @param {number} a - The length of side A.
59+
* @param {number} b - The length of side B.
60+
* @param {number} c - The length of side C.
61+
* @returns {boolean} True if the triangle is valid, false otherwise.
62+
* @private
63+
*/
64+
isValidTriangle = (a, b, c) => {
65+
return a + b > c && b + c > a && c + a > b
66+
}
67+
68+
/**
69+
* Calculate the area of the triangle.
70+
* @returns {number} The area of the triangle.
71+
* @public
72+
*/
73+
area = () => {
74+
if (this.height !== null) {
75+
return 0.5 * this.base * this.height
76+
}
77+
// Using Heron's formula
78+
const [a, b, c] = this.sides
79+
const s = (a + b + c) / 2
80+
return Math.sqrt(s * (s - a) * (s - b) * (s - c))
81+
}
82+
83+
/**
84+
* Calculate the perimeter of the triangle.
85+
* @returns {number} The perimeter of the triangle.
86+
* @throws {Error} Will throw an error if not all sides are known.
87+
* @public
88+
*/
89+
perimeter = () => {
90+
if (this.sides.some((side) => side === null)) {
91+
throw new Error('Cannot calculate perimeter: not all sides are known.')
92+
}
93+
return this.sides.reduce((sum, side) => sum + side, 0)
94+
}
95+
}

0 commit comments

Comments
 (0)