Build a Triangle Calculator 📐
Geometry isn't just about drawing shapes; it's about solving unknowns. Given 3 sides, can you find the area? Given 2 sides and an angle, can you find the third side? Yes, thanks to two powerful formulas.
Step 1: The Math (Heron's Formula) 🌿
To find the Area of a triangle when you only know the 3 side lengths (a, b, c), you don't use 0.5 * base * height.
You use Heron's Formula.
- Calculate Semiperimeter (s):
(a + b + c) / 2 - Calculate Area:
Math.sqrt(s * (s - a) * (s - b) * (s - c))
Step 2: The Math (Law of Cosines) 📐
To find an Angle when you know all 3 side lengths:
cos(C) = (a² + b² - c²) / (2ab)
So, the angle C in radians is:
AngleC = Math.acos((a*a + b*b - c*c) / (2*a*b))
Step 3: The React Logic 🧠
We need a function that takes 3 sides and returns everything: Area, Type, and Angles.
/* lib/triangle-solver.ts */
export const solveTriangle = (a: number, b: number, c: number) => {
// 1. Validator: Triangle Inequality Theorem
if (a + b <= c || a + c <= b || b + c <= a) {
return { valid: false, msg: "Impossible Triangle" };
}
// 2. Area (Heron's)
const s = (a + b + c) / 2;
const area = Math.sqrt(s * (s - a) * (s - b) * (s - c));
// 3. Angles (Law of Cosines) - Returns Radians
const A_rad = Math.acos((b*b + c*c - a*a) / (2*b*c));
const B_rad = Math.acos((a*a + c*c - b*b) / (2*a*c));
const C_rad = Math.PI - A_rad - B_rad;
// 4. Convert to Degrees
const toDeg = (rad: number) => rad * (180 / Math.PI);
return {
valid: true,
area,
angles: { A: toDeg(A_rad), B: toDeg(B_rad), C: toDeg(C_rad) },
perimeter: a + b + c
};
}
Step 4: The React Component 🔺
A clean input form that instantly solves the geometry.
"use client"
import { useState } from "react"
import { Triangle } from "lucide-react"
export default function TriangleSolver() {
const [sides, setSides] = useState({ a: '', b: '', c: '' })
const [result, setResult] = useState<any>(null)
const handleSolve = () => {
const a = Number(sides.a), b = Number(sides.b), c = Number(sides.c);
// Check validity
if (a + b <= c || a + c <= b || b + c <= a) {
setResult({ valid: false });
return;
}
const s = (a + b + c) / 2;
const area = Math.sqrt(s * (s - a) * (s - b) * (s - c));
const A = Math.acos((b*b + c*c - a*a) / (2*b*c)) * (180 / Math.PI);
setResult({ valid: true, area, A });
}
return (
<div className="max-w-md mx-auto p-6 bg-white rounded-xl shadow-lg border border-emerald-100">
<div className="flex items-center gap-2 mb-6 text-emerald-700 font-bold text-xl">
<Triangle fill="#047857" /> Triangle Solver
</div>
<div className="flex gap-2 mb-4">
<Input label="Side A" val={sides.a} onChange={v => setSides({...sides, a: v})} />
<Input label="Side B" val={sides.b} onChange={v => setSides({...sides, b: v})} />
<Input label="Side C" val={sides.c} onChange={v => setSides({...sides, c: v})} />
</div>
<button
onClick={handleSolve}
className="w-full py-3 bg-emerald-600 text-white rounded-lg font-bold hover:bg-emerald-700 transition shadow-md shadow-emerald-200"
>
SOLVE
</button>
{result && (
<div className="mt-6 p-4 bg-emerald-50 rounded-lg border border-emerald-200 animate-in fade-in">
{result.valid ? (
<div className="space-y-2">
<div className="flex justify-between">
<span className="text-emerald-800 font-medium">Area</span>
<span className="font-bold text-emerald-950">{result.area.toFixed(2)}</span>
</div>
<div className="flex justify-between">
<span className="text-emerald-800 font-medium">Angle A</span>
<span className="font-bold text-emerald-950">{result.A.toFixed(1)}°</span>
</div>
</div>
) : (
<p className="text-red-500 font-bold text-center">Impossible Triangle!</p>
)}
</div>
)}
</div>
)
}
function Input({ label, val, onChange }) {
return (
<div>
<label className="text-xs font-bold text-emerald-600 uppercase">{label}</label>
<input
type="number"
value={val}
onChange={e => onChange(e.target.value)}
className="w-full p-2 border border-emerald-200 rounded-lg focus:ring-2 focus:ring-emerald-500 outline-none"
/>
</div>
)
}
Step 5: Triangle Types 🏷️
With the side lengths, you can also easily categorize the triangle:
- Equilateral:
a === b && b === c - Isosceles:
a === b || b === c || a === c - Scalene: No sides equal
- Right:
a² + b² === c²(Pythagorean Theorem)