25
$\begingroup$

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

$\endgroup$

6 Answers 6

15
$\begingroup$

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.

$\endgroup$
6
  • 1
    $\begingroup$ aha, we all did the same thing! :) $\endgroup$
    – rm -rf
    Feb 8, 2012 at 1:13
  • $\begingroup$ Apparently so, but in defense of my slowness, I was waiting for the verification to finish... :) $\endgroup$ Feb 8, 2012 at 1:23
  • 1
    $\begingroup$ 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. $\endgroup$
    – DavidC
    Feb 8, 2012 at 2:30
  • 1
    $\begingroup$ @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. $\endgroup$ Feb 8, 2012 at 4:46
  • $\begingroup$ I hadn't noticed. Good job double-checking your code. $\endgroup$
    – DavidC
    Feb 8, 2012 at 12:26
22
$\begingroup$

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

$\endgroup$
2
  • 4
    $\begingroup$ Yes, that makes things so much easier. There are other triangle options too. E.g. SASTriangle $\endgroup$
    – DavidC
    Sep 6, 2014 at 16:43
  • $\begingroup$ How to show the label of side length? $\endgroup$
    – liang
    Mar 21, 2020 at 6:48
16
$\begingroup$

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

$\endgroup$
1
  • 2
    $\begingroup$ 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. $\endgroup$
    – DavidC
    Feb 8, 2012 at 2:15
10
$\begingroup$

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]
   ]
  ]
$\endgroup$
4
  • $\begingroup$ Sorry, it's late at night ... $\endgroup$
    – Szabolcs
    Feb 8, 2012 at 1:07
  • $\begingroup$ I follow the logic of your first solution but not of the second. The norms are the lengths of the triangle edges, correct? $\endgroup$
    – DavidC
    Feb 8, 2012 at 2:36
  • $\begingroup$ @David: yes, pretty much. The second routine essentially generates three randomly positioned points that are the corners of a triangle with specified side lengths. $\endgroup$ Feb 8, 2012 at 2:42
  • $\begingroup$ Interesting approach. $\endgroup$
    – DavidC
    Feb 8, 2012 at 2:53
10
$\begingroup$

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

$\endgroup$
1
$\begingroup$

I just realized that there is a another straightforward approach using circles. Let's assume that two of the vertices lie at {0,0} and {1.5, 0}, as suggested by Szabolcs' example from Jun' 28, '14.

The third vertex will lie at either of the two points given by Solve. Those points are 2 units from the origin and 1 unit from the vertex at (1.5, 0).

Solve[{x, y} \[Element] Circle[{0, 0}, 2] && {x, y} \[Element]Circle[{1.5, 0}, 1], {x, y}]

{{x -> 1.75, y -> -0.968246}, {x -> 1.75, y -> 0.968246}}

Let's take the point that lies in quadrant I as the solution:

Graphics[{{Red, PointSize[Large], Point[{0, 0}], Point[{0, 0}], Point[{3/2, 0}], Point[{1.75`, 0.9682458365518543`}]}, 
Circle[{0, 0}, 2], Circle[{3/2, 0}, 1], 
Triangle[{{0, 0}, {1.5, 0}, {1.75`, 0.9682458365518543`}}]}, 
AxesOrigin -> {0, 0}, Axes -> True, Frame -> True]

triangle

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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