{
  "schemaVersion": 1,
  "slug": "triangle-calculator",
  "category": "geometry",
  "kind": "implementation",
  "independentValidation": false,
  "implementationHash": "0b16948db0f79bbdc788eada74230cc4e668e338f837f1b1a92e70f6e96aba69",
  "provenance": "Generated from the calculation contract used by the published page. Publication is not external validation.",
  "sourceFiles": [
    "data/calculators/triangle-calculator.json",
    "src/engine.js"
  ],
  "runtimeSource": "/sources/engine.txt",
  "runtimeHash": "5c888d8898afbdee36267bb9977829e1e2ac568f6677c8ee87469c139864645c",
  "scope": "The compute function records implemented equations, constants, lookup tables and custom rules. Inputs record defaults and allowed values; outputs record precision and units. Defaults are examples, not recommendations. General background references are not evidence for this specific algorithm.",
  "publishedFormula": {
    "formula": "A = √(s(s−a)(s−b)(s−c)); α = acos((b²+c²−a²) ÷ 2bc); r = A ÷ s; R = a × b × c ÷ 4A",
    "vars": [
      [
        "a,b,c",
        "Sides"
      ],
      [
        "s",
        "Semiperimeter"
      ],
      [
        "A",
        "Area"
      ],
      [
        "α",
        "Angle opposite a"
      ],
      [
        "r",
        "Inradius"
      ],
      [
        "R",
        "Circumradius"
      ]
    ],
    "note": "Enter all sides in the same unit u. Length outputs use u and area uses u²; no unit is selected or converted. Invalid triangles suppress results."
  },
  "externalEvidence": {
    "reviewedAt": "2026-10-22",
    "sources": [
      {
        "name": "Wolfram MathWorld — Heron's Formula",
        "url": "https://mathworld.wolfram.com/HeronsFormula.html"
      }
    ],
    "implementationHash": "0b16948db0f79bbdc788eada74230cc4e668e338f837f1b1a92e70f6e96aba69",
    "basis": "Start with the semiperimeter s = (a + b + c) / 2. Heron’s formula gives the area A = √[s(s − a)(s − b)(s − c)]. Each angle comes from the cosine rule; Angle opposite a is opposite Side a, and likewise for b and c. The inradius A/s is the radius of the circle inside and tangent to all three sides. The circumradius abc/(4A) is the radius of the circle through all three vertices. Height to side a is 2A/a. Enter the sides in the same unit: centimetres give length results in centimetres and area in square centimetres. Decimal results are rounded; very small positive areas use scientific notation.",
    "limitations": "Enter three positive side lengths in the same unit. Length results use that input unit (u), and area uses its square (u²); this calculator does not choose or convert a measurement unit."
  },
  "contract": {
    "compute": "const a=sideA, b=sideB, c=sideC;\nif(![a,b,c].every(x=>Number.isFinite(x)&&x>=0.01&&x<=100000))return {area:null,perimeter:null,angleA:null,angleB:null,angleC:null,inradius:null,circumradius:null,heightA:null,__error:'inputError'};\nif (a<=0 || b<=0 || c<=0 || a+b<=c || a+c<=b || b+c<=a) return {area:null,perimeter:null,angleA:null,angleB:null,angleC:null,inradius:null,circumradius:null,heightA:null,__error:'triangle'};\nconst s=(a+b+c)/2;\nconst [x,y,z]=[a,b,c].sort((m,n)=>n-m);\nconst inside=(x+(y+z))*(z-(x-y))*(z+(x-y))*(x+(y-z))/16;\nconst area=inside>0?Math.sqrt(inside):0;\nconst ang=(x,y,z)=>{ const d=(y*y+z*z-x*x)/(2*y*z); return (y*z)>0 ? Math.acos(Math.min(1,Math.max(-1,d)))*180/Math.PI : 0; };\nreturn {\n  area,\n  perimeter: a+b+c,\n  angleA: ang(a,b,c), angleB: ang(b,a,c), angleC: ang(c,a,b),\n  inradius: s>0 ? area/s : 0,\n  circumradius: area>0 ? (a*b*c)/(4*area) : 0,\n  heightA: a>0 ? 2*area/a : 0,\n};",
    "inputs": [
      {
        "name": "sideA",
        "type": "number",
        "default": 5,
        "min": 0.01,
        "max": 100000,
        "step": 0.01,
        "requiredValue": true,
        "strictRange": true
      },
      {
        "name": "sideB",
        "type": "number",
        "default": 4,
        "min": 0.01,
        "max": 100000,
        "step": 0.01,
        "requiredValue": true,
        "strictRange": true
      },
      {
        "name": "sideC",
        "type": "number",
        "default": 3,
        "min": 0.01,
        "max": 100000,
        "step": 0.01,
        "requiredValue": true,
        "strictRange": true
      }
    ],
    "outputs": [
      {
        "name": "area",
        "precision": 3,
        "unit": "u²",
        "notation": "auto",
        "trimTrailingZeros": true
      },
      {
        "name": "perimeter",
        "precision": 3,
        "unit": "u",
        "trimTrailingZeros": true
      },
      {
        "name": "angleA",
        "precision": 2,
        "unit": "°",
        "trimTrailingZeros": true
      },
      {
        "name": "angleB",
        "precision": 2,
        "unit": "°",
        "trimTrailingZeros": true
      },
      {
        "name": "angleC",
        "precision": 2,
        "unit": "°",
        "trimTrailingZeros": true
      },
      {
        "name": "inradius",
        "precision": 4,
        "unit": "u",
        "trimTrailingZeros": true
      },
      {
        "name": "circumradius",
        "precision": 4,
        "unit": "u",
        "trimTrailingZeros": true
      },
      {
        "name": "heightA",
        "precision": 4,
        "unit": "u",
        "trimTrailingZeros": true
      }
    ],
    "interpret": null
  }
}
