Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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.)

share|improve this question

5 Answers 5

up vote 11 down vote accepted

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.

share|improve this answer
1  
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... :) –  J. M. Feb 8 '12 at 1:23
1  
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
1  
@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. –  J. M. Feb 8 '12 at 4:46
    
I hadn't noticed. Good job double-checking your code. –  David Carraher Feb 8 '12 at 12:26

In version 10, use SSSTriangle which stands for side-side-side triangle.

share|improve this answer
    
Yes, that makes things so much easier. There are other triangle options too. E.g. SASTriangle –  David Carraher Sep 6 at 16:43

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]},
              ImagePadding->20,ImageSize->{200,200}]

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}]}}]

labeled triangles

share|improve this answer

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]}]

Mathematica graphics

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]
   ]
  ]
share|improve this answer
    
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. –  J. M. Feb 8 '12 at 2:42
    
Interesting approach. –  David Carraher Feb 8 '12 at 2:53

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}]}]

share|improve this answer
2  
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

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.