1

I'm making drawings of triangles inside of their inscribing circles. The drawings include the perpendicular bisectors of each side of the triangles, showing how the point where the bisectors intersect is also the radius of the circumcircle. The goal is to make a decorative pattern, so I want to repeat the image with randomly generated triangles. Here is the code for the triangles. For each iteration of the loop, I shift the center of the current circle to the right, randomly get 3 angles that I use to draw 3 vertices, a, b, and c, which all lie on a circle with radius=1 (which also gets drawn in the last line).

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc,intersections,through,backgrounds}

\begin{document}
\begin{tikzpicture}[scale=1,trim left=3cm]
\foreach \i in {0.0,1.0,...,6.0} {
  \begin{scope}
  \def\thetaA{rnd*120};
  \def\thetaB{120+rnd*120};
  \def\thetaC{240+rnd*120};
  \coordinate (center) at (4.3*\i,0.0);
  \coordinate (a) at ($(center)+ (\thetaA:1.0)$);
  \coordinate (b) at ($(center) + (\thetaB:1.0)$);
  \coordinate (c) at ($(center) + (\thetaC:1.0)$);
  \draw (a)--(b)--(c)--(a);
  \draw[name path=circumcircle] (center) circle (1);

To draw the perpendicular bisector of a side, I would like simply to extend the line segment from the center of the circle to the midpoint of the side by a factor long enough to reach just beyond the circumference of the circle. However, because I'm randomly generating triangles, there isn't a one-size-fits-all factor.

As a first step, I tried to draw a radius of the circle passing through the midpoint of one side, AB. As a scaling factor, I thought I could use the ratio of the radius of the circle to the distance from the center to the midpoint, both calculated using veclen. Here's the code for that:

  \coordinate (midpointOfAB) at ($(a)!.5!(b)$);
  \coordinate (midpointOfBC) at ($(b)!.5!(c)$);
  \coordinate (midpointOfAC) at ($(a)!.5!(c)$);
  \draw[name path=toAB,blue] let
  \p1 = ($ (midpointOfAB) - (center)$),
  \p2 = ($ (a) - (center)$),
  \n1 = {veclen(\x1,\y1)},
  \n2 = {veclen(\x2,\y2)}
  in 
  (center) -- ($(center)!\n2/\n1!(midpointOfAB)$);

The line segment from the center is getting drawn in the right direction (toward the midpoint of AB). However, the length is way off. In general, the segments are falling short of the circumference of the circle. If n1 is the distance of the center to the midpoint of AB and n2 is the radius of the circle, then n2/n1 ought to be the factor that extends the line segment to the circumference (x*n1 = n2), right? What am I missing? Any insights would be much appreciated!

3

veclen gives a length in pt, and presumably \n2/\n1 also becomes a length in pt, hence you get a "distance modifier" instead of a "partway modifier" (to use the terms in the manual). To strip the pt suffix, use scalar(veclen(..)). Then it works fine.

On the other hand, if you use \pgfmathsetmacro instead of \def to define \thetaA etc., meaning that rnd is evaluated at the time of the macro definition, you can just use e.g. \draw [blue] (center) -- ++({(\thetaA+\thetaB)/2}:1);.

(Image created with smaller spacing between circles than what is given in the code.)

enter image description here

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc,intersections,through,backgrounds}

\begin{document}
\begin{tikzpicture}[scale=1,trim left=3cm]
\foreach \i in {0.0,1.0,...,6.0} {
  \begin{scope}
  \def\thetaA{rnd*120};
  \def\thetaB{120+rnd*120};
  \def\thetaC{240+rnd*120};
  \coordinate (center) at (4.3*\i,0.0);
  \coordinate (a) at ($(center)+ (\thetaA:1.0)$);
  \coordinate (b) at ($(center) + (\thetaB:1.0)$);
  \coordinate (c) at ($(center) + (\thetaC:1.0)$);
  \draw (a)--(b)--(c)--(a);
  \draw[name path=circumcircle] (center) circle (1);

  \coordinate (midpointOfAB) at ($(a)!.5!(b)$);
  \coordinate (midpointOfBC) at ($(b)!.5!(c)$);
  \coordinate (midpointOfAC) at ($(a)!.5!(c)$);
  \draw[name path=toAB,blue] let
  \p1 = ($ (midpointOfAB) - (center)$),
  \p2 = ($ (a) - (center)$),
  \n1 = {scalar(veclen(\x1,\y1))},
  \n2 = {scalar(veclen(\x2,\y2))}
  in 
  (center) -- ($(center)!\n2/\n1!(midpointOfAB)$);
\end{scope}
}

\end{tikzpicture}
\begin{tikzpicture}[scale=1,trim left=3cm]
\foreach \i in {0.0,1.0,...,6.0} {
  \begin{scope}
  \pgfmathsetmacro\thetaA{rnd*120} % rnd evaluated here
  \pgfmathsetmacro\thetaB{120+rnd*120}
  \pgfmathsetmacro\thetaC{240+rnd*120}
  \coordinate (center) at (4.3*\i,0.0);
  \coordinate (a) at ($(center)+ (\thetaA:1.0)$);
  \coordinate (b) at ($(center) + (\thetaB:1.0)$);
  \coordinate (c) at ($(center) + (\thetaC:1.0)$);
  \draw (a)--(b)--(c)--(a);
  \draw[name path=circumcircle] (center) circle (1);

  \draw [blue] (center) -- ++({(\thetaA+\thetaB)/2}:1);
\end{scope}
}
\end{tikzpicture}
\end{document}
  • Thank you! I wasn't aware of distance modifiers. So I was assuming that by dividing a pt by a pt I was successfully creating a dimensionless scalar -- but couldn't figure out why the value was off. – joeshiki Jun 5 '18 at 15:04
  • @joeshiki I didn't actually check if \n2/\n1 gives Xpt, but I guess that was the problem. Exactly why you get Xpt instead of X I'm not 100% sure of actually. – Torbjørn T. Jun 5 '18 at 15:09
  • I was able to run the second solution, which is great. When I tried to use scalar, however I got the error, Package PGF Math Error: Unknown function scalar' (in 'scalar(veclen...` Is this a question of a library update I'm missing or something like that? Thanks again. – joeshiki Jun 5 '18 at 15:23
  • @joeshiki If you don't have scalar you're probably still on version 3.0.0 or earlier of pgf/TikZ. That function was, I think, introduced in version 3.0.1a of pgf/TikZ, which was released in 2015 but is still the current stable version. So yes, it's a question of an update you're missing, an update of pgf itself. – Torbjørn T. Jun 5 '18 at 15:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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