Solving Triangles with Heron's Formula and the Laws of Cosines
by Otto Wilke otto_wilke@hotmail.com
This Maple program solves triangles with angles A, B, and C; opposite sides a, b, and c; and area K, given any three of the seven variables. Enter the three knowns as equations in the procedure call. Angles must be in radians.
This program uses the following three independent forms of the Law of Cosines:
> a^2=b^2+c^2-2*b*c*cos(A); b^2=a^2+c^2-2*a*c*cos(B); c^2=b^2+a^2-2*b*a*cos(C);
and Heron's formula for area,
> K=sqrt((a+b+c)/2*((a+b+c)/2-a)*((a+b+c)/2-b)*((a+b+c)/2-c));
along with the three equations stating the known values, to form a set of seven equations in seven unknowns.
The program discards negative and complex solutions of the set of equations. The output also gives angles in degrees and draws the triangle.
> tsolve[v1]:=proc(eq1,eq2,eq3) local previous, nprevious, posreal, m, p1, p2, p3, p4, p5, p6, p7, A2, B2, C2, Arad, Brad, n, printcount, Crad, sidec, sideb, opcount, rhsvalue; #The 3 forms of the law of cosines and Heron's equation [solve({eq1,eq2,eq3,a^2=b^2+c^2-2*b*c*cos(A),b^2=a^2+c^2-2*a*c*cos(B),c^2=b^2+a^2-2*b*a*cos(C),K=sqrt((a+b+c)/2.*((a+b+c)/2.-a)*((a+b+c)/2.-b)*((a+b+c)/2.-c))},{a,b,c,A,B,C,K})]: #convert answers to list form for manipulation previous:=convert(%,list):printcount:=0: for n from 1 to nops(previous) do nprevious:=convert(op(n,previous),list): posreal:=0: for m from 1 to 7 do #get degrees equivalents of radian answers if (lhs(op(m,nprevious))=A) then Arad:=rhs(op(m,nprevious)): A2:=lhs(op(m,nprevious))=rhs(op(m,nprevious))*180./evalf(Pi)*degrees; elif (lhs(op(m,nprevious))=B) then Brad:=rhs(op(m,nprevious)): B2:=lhs(op(m,nprevious))=rhs(op(m,nprevious))*180./evalf(Pi)*degrees; elif (lhs(op(m,nprevious))=C) then Crad:=rhs(op(m,nprevious)): C2:=lhs(op(m,nprevious))=rhs(op(m,nprevious))*180./evalf(Pi)*degrees; elif (lhs(op(m,nprevious))=c) then sidec:=rhs(op(m,nprevious)): elif (lhs(op(m,nprevious))=b) then sideb:=rhs(op(m,nprevious)): fi: #eliminate negative and complex answers rhsvalue:=rhs(op(m,nprevious)): opcount:=nops(rhsvalue): if opcount=1 then if (rhsvalue <= 0 or signum(rhsvalue) <> 1) then posreal:=posreal+1:fi:else if (signum(rhsvalue) <> 1) then posreal:=posreal+1:fi:fi:od: if posreal = 0 then #eliminate solutions where sum of angles exceeds 180 degrees if ((rhs(A2)+rhs(B2)+rhs(C2))/degrees<=180+.01) then #print results print(nprevious);print(A2,B2,C2);printcount:=printcount+1: p1:=plot([[0,0],[sideb,0],[sidec*cos(Arad),sidec*sin(Arad)],[0,0]],style=line,color=blue,thickness=2,scaling=constrained): with(plots): p2:=textplot([-.05*sideb,0,`A`],align={Left},color=red): p3:=textplot([sideb+.05*sideb,0,`C`],align={Right},color=red): p4:=textplot([sidec*cos(Arad),sidec*sin(Arad)+.1*sidec,`B`],align={Above},color=red): p5:=textplot([-.05*sideb+.5*sidec*cos(Arad),.5*sidec*sin(Arad),`c`],align={Left},color=red): p6:=textplot([(sidec*cos(Arad)+sideb)*.5+.1*sideb,.55*sidec*sin(Arad),`a`],align={Above,Right},color=red): p7:=textplot([.5*sideb,-.1*sidec*sin(Arad),`b`],align={Above},color=red): print(display([p1,p2,p3,p4,p5,p6,p7],axes=none)); printf(`\n`);printf(`\n`); fi: fi:od: #if no real positive solutions,say so if printcount = 0 then printf(`No possible triangle or no side given\n`);fi: end:
> #example with 2 possible triangles tsolve[v1](A=63*evalf(Pi)/180.,b=11,a=10);
Warning, the name changecoords has been redefined
> #example with 1 triangle tsolve[v1](A=153*evalf(Pi)/180.,b=10,a=12);
> #example with side too short to form triangle tsolve[v1](A=53*evalf(Pi)/180.,b=10,a=4);
No possible triangle or no side given
> #example with area as one of 3 inputs tsolve[v1](c=15,b=12,K=54);
> #example with sum of angles > 180 degrees tsolve[v1](b=24.9,A=(255+1/3)*evalf(Pi)/180.,a=22.8);
>