# How do I draw a triangle given the lengths of the sides?

I know, of course, how to draw a triangle in the plane given the vertices:

Graphics[Polygon[{{1, 0}, {0, Sqrt[3]}, {-1, 0}}]]


But I'm not sure how to simply draw a triangle if all I care about is the length of the sides. (I'm happy to place one of the vertices at the origin and place one of the sides on the non-negative side of the x-axis, but that doesn't really matter.) Is there a straightforward way?

This raises the additional question, "how do I draw a triangle in Mathematica, given three angles?" (Say I want to it to reside somewhere in the unit circle.)

-

I'm not sure how to draw a triangle if all I care about is the length of the sides. (I'm happy to place one of the vertices at the origin and place one of the sides on the nonnegative side of the $x$-axis, but that doesn't really matter.) Is there a straightforward way?

Given a triangle with side lengths $p \leq q \leq r$ (assuming the lengths satisfy the triangle inequality, of course), with hypotenuse on the positive $x$-axis, and the origin as one endpoint, you can solve a system of equations to get the third point, apart from $(0,0)$ and $(r,0)$:

FullSimplify[{x, y} /.
Last[Solve[{x^2 + y^2 == p^2, (x - r)^2 + y^2 == q^2}, {x, y}]]]
{(p^2 - q^2 + r^2)/(2 r),
Sqrt[-(p - q - r) (p + q - r) (p - q + r) (p + q + r)]/(2 r)}


and thus, either of

Graphics[Line[{{0, 0}, {r, 0}, {(p^2 - q^2 + r^2)/(2 r),
Sqrt[-(p - q - r) (p + q - r) (p - q + r) (p + q + r)]/(2 r)}, {0, 0}}]]


or

Graphics[Polygon[{{0, 0}, {r, 0}, {(p^2 - q^2 + r^2)/(2 r),
Sqrt[-(p - q - r) (p + q - r) (p - q + r) (p + q + r)]/(2 r)}}]]


does the job.

Verify the triangle:

FullSimplify[
Norm /@ Differences[{{0, 0}, {r, 0}, {(p^2 - q^2 + r^2)/(2 r),
Sqrt[-(p - q - r) (p + q - r) (p - q + r) (p + q +
r)]/(2 r)}, {0, 0}}], 0 <= p <= q <= r && p + q >= r]
{r, q, p}


This raises the additional question, "how do I draw a triangle in Mathematica, given three angles?". (Say I want to it to reside somewhere in the unit circle.)

The law of sines saves your bacon here (the ratio of a side length and the sine of the opposite angle gives the diameter of the triangle's circumcircle). Skipping details, here's how to inscribe a triangle with specified angles into the unit circle:

parts = IntegerPartitions[180, {3}];

(* generate corresponding sides from randomly chosen angles *)
angles = parts[[RandomInteger[{1, Length[parts]}]]];
{r, q, p} = 2 Sin[angles Degree];

Graphics[{Line[{{1, 0}, {1 - p^2/2, p Sqrt[1 - p^2/4]},
{1 - q^2/2, -q Sqrt[1 - q^2/4]}, {1, 0}}],
Circle[{0, 0}, 1]}]


You can use the next two snippets to verify that the triangle generated fits the specifications:

(* check side lengths *)
Norm /@ RotateLeft[Differences[
N[{{1, 0}, {1 - p^2/2, p Sqrt[1 - p^2/4]},
{1 - q^2/2, -q Sqrt[1 - q^2/4]}, {1, 0}}]]] - {r, q, p} // Chop

(* check angles *)
(Apply[VectorAngle, Map[Function[pt, pt - First[#]], Rest[#]]]/Degree) & /@
NestList[RotateLeft, N[{{1, 0}, {1 - p^2/2, p Sqrt[1 - p^2/4]},
{1 - q^2/2, -q Sqrt[1 - q^2/4]}}], 2] - angles // Chop


Both snippets should return {0, 0, 0} if all goes well.

-
aha, we all did the same thing! :) –  rm -rf Feb 8 '12 at 1:13
Apparently so, but in defense of my slowness, I was waiting for the verification to finish... :) –  Ｊ. Ｍ. Feb 8 '12 at 1:23
Very nice. I especially liked the touch of inscribing the triangle in the unit circle. I'm still savouring reference to the law of the sines. –  David Carraher Feb 8 '12 at 2:30
@David: I have updated my code; the previous version had a very serious bug that caused it to yield the wrong inscribed triangle about half the time, due to a wrong choice of square root. Hopefully the current version is now correct. –  Ｊ. Ｍ. Feb 8 '12 at 4:46
I hadn't noticed. Good job double-checking your code. –  David Carraher Feb 8 '12 at 12:26
show 1 more comment

To answer your first question: when in doubt, fall back to basic construction geometry. Fix two points arbitrarily, and "construct" the third by finding the point of intersection of two circles with these points as centers and radii as the sides. Example:

sideAB = 4;sideBC = 5;sideCA = 6;
ptA = {0, 0};ptB = ptA + {sideAB, 0};
ptC = {x, y} /. Last@Solve[x^2 + y^2 - sideCA^2 == 0 &&
y^2 + (x - sideAB)^2 - sideBC^2 == 0, {x, y}]

Graphics[{FaceForm[], EdgeForm[{Thick, Black}], Polygon[{ptA, ptB, ptC}]}]


-
That makes perfect sense. Funny, I used this method recently playing with GeoGebra but didn't think to transfer it to Mathematica. Once the side is on the x-axis you just use your compass. –  David Carraher Feb 8 '12 at 2:15

Brute forcing it:

triangle[a_?NumericQ, b_?NumericQ, c_?NumericQ] :=
Block[{x, y, pt, sqr},
sqr = #.# &;
pt[a1_, b1_, c1_] :=
Reduce[sqr[{x, y}] == b1^2 && sqr[{x, y} - {a1, 0}] == c1^2 &&
y > 0, {x, y}];
Polygon[{{0, 0}, {a, 0}, {x, y} /. ToRules[pt[a, b, c]]}]
]

Graphics[{EdgeForm[Thick], FaceForm[None], triangle[1, 1, 1/2]}]


EDIT

Brute forcing it even more:

triangle[x_, y_, z_] := Block[{x1, y1, x2, y2, x3, y3},
With[{a = {x1, y1}, b = {x2, y2},
c = {x3, y3}}, {{x1, y1}, {x2, y2}, {x3, y3}} /.
First@FindInstance[
Norm[a - b] == x && Norm[b - c] == y && Norm[c - a] == z, {x1,
y1, x2, y2, x3, y3}, Reals]
]
]

-
Sorry, it's late at night ... –  Szabolcs Feb 8 '12 at 1:07
I follow the logic of your first solution but not of the second. The norms are the lengths of the triangle edges, correct? –  David Carraher Feb 8 '12 at 2:36
@David: yes, pretty much. The second routine essentially generates three randomly positioned points that are the corners of a triangle with specified side lengths. –  Ｊ. Ｍ. Feb 8 '12 at 2:42
Interesting approach. –  David Carraher Feb 8 '12 at 2:53

Here's a variation that labels the lengths of the sides. It is based on @Szabolcs' first solution.

triangle[a_?NumericQ,b_?NumericQ,c_?NumericQ]:=
Block[{x,y,pt,sqr},
sqr=#.#&;
pt[a1_,b1_,c1_]:=
Reduce[sqr[{x,y}]==b1^2&&sqr[{x,y}-{a1,0}]==c1^2&&y>0,{x,y}];
{(Polygon[{{0,0},{a,0},{x,y}}]),
Text[Style[Framed[a,Background-> LightYellow],11],{a/2,0}],
Text[Style[Framed[b,Background-> LightYellow],11],{x/2,y/2}],
Text[Style[Framed[c,Background-> LightYellow],11],
{(a+x)/2,y/2}]}/.ToRules[pt[a,b,c]]]

g[{s1_,s2_,s3_}]:=
Graphics[{EdgeForm[Thick],FaceForm[None],triangle[s1,s2,s3]},


Some examples:

GraphicsGrid[{
{g[{2, 1, Sqrt[5]}], g[{1, 2, Sqrt[5]}],
g[{Sqrt[5], 1, 2}, g[{Sqrt[5], 2, 1}]},
{g[{2, 2, Sqrt[8]}], g[{Sqrt[8], 2, 2}],
g[{2, Sqrt[8], 2}],
g[{Sqrt[2], Sqrt[2], 2}]}}]


-