TransWikia.com

Flatten an arc while keeping length fixed

TeX - LaTeX Asked on September 1, 2021

Question: How to ensure the blue shape of the second picture has same length as the annulus in the first picture?

Context: To illustrate the process of "un-coiling" the annulus after a straight cut. I plan to make an animation with 3 or 4 intermediate steps from "circle" to "line".

documentclass[border=5mm, varwidth]{standalone}
usepackage{tikz}
begin{document}

begin{tabular}{@{}c@{}}

begin{tikzpicture}
filldraw [fill=gray!30, draw=black] (0,0) circle[radius=1];
filldraw [fill=blue!15, draw=black, even odd rule] (0,0) circle[radius=1] circle[radius=2];
end{tikzpicture}

vspace{2cm} 

begin{tikzpicture}
filldraw [fill=gray!30, draw=black] (0,0) circle[radius=1];
filldraw[fill=blue!15, draw=black, shift={(0,2)}] (330:3) arc (330:210:3) -- (210:4) arc (210:330:4) -- cycle;
end{tikzpicture}

end{tabular}

end{document}

enter image description here

Since the inner circle has radius 1cm and the outer circle radius 2cm, the length of the annulus would be about 3 times pi.

EDIT 1

I am hoping that something could be done with the nonlineartransformations PGF module. I have seen examples of transformations using polar coordinates and examples using arbitrary transformations. I think what I’m missing are the parametric equations that would flatten a semi-circle into a line. That is, if we forget about the thickness of the annulus and consider a semi-circle starting at (0,0) and ending at (0, 1) anti-clockwise, the transformation is one that would keep the point (0,0) unchanged but would pull (0,1) to the right and eventually down to the (1,0) point. Once I know how to produce the transformation to the rhs semi-circle, I can apply the symmetric transformation to the lhs semi-circle, to complete the circle transformation. And then do that for another pair of semi-circles with a different radius to get the annulus.

EDIT 2

With John Kormylo’s suggestions (thanks John!), I was able to write a function that transforms the semi-circle to "flatten" it. Next is to generalize this to a filldraw command for an annulus.

documentclass[margin=3mm,varwidth]{standalone}
usepackage{tikz}

makeatletter
pgfmathdeclarefunction{alpha}{1}{%
    begingroup
        pgfmathparse{180/#1-90}%
        pgf@x=pgfmathresult ptrelax
        pgfmathreturnpgf@x
    endgroup
}
makeatother

defshape#1#2{
  draw [draw={#1}] (0,0) arc[start angle=-90, end angle={alpha(#2)}, radius={#2}]; 
}

begin{document}

begin{tikzpicture}[scale=3]
shape{red}{1}
shape{red!90}{2}
shape{red!80}{3}
shape{red!70}{4}
shape{red!60}{5}
shape{red!50}{6}
shape{red!40}{7}
shape{red!30}{8}
shape{red!20}{9}
shape{black}{100}
end{tikzpicture}

end{document}

enter image description here

The left-hand side follows by symmetry. Putting it together yields a somewhat unwieldy function with 6 arguments, including color, center, radius, and angles. This is still not an answer to my original question, so I’m including it here, rather than posting it as an answer. Also, I’m pretty sure the code can be cleaned up.

documentclass[margin=3mm,varwidth]{standalone}
usepackage{tikz}

% alpha takes 2 arguments:
% #1: angle of arc, for semi-circle either -180 or 180
% #2: radius of arcs
% #3: rotation of angle
makeatletter
pgfmathdeclarefunction{alpha}{3}{%
    begingroup
        pgfmathparse{#1/#2+#3}%
        pgf@x=pgfmathresult ptrelax
        pgfmathreturnpgf@x
    endgroup
}
makeatother

% shape takes 5 arguments:
% #1: draw color, e.g. red
% #2: center, e.g. (0,0)
% #3: radius
% #4: start angle, e.g. 0 for starting at (1,0), -90 for (0,-1)
% #5: angle of arc, for semi-circle either -180 or 180
% #6: rotation of end angle, e.g. -90 to go from (1,0) to (0,-1)
defshape#1#2#3#4#5#6{
  draw [draw={#1}] {#2} arc[radius={#3}, start angle={#4}, end angle={alpha(#6,#3,#5)}]; 
}

begin{document}

begin{tikzpicture}[scale=1.8]

shape{blue!100}{(0,0)}{1}{-90}{-90}{180}
shape{blue!100}{(0,0)}{1}{-90}{-90}{-180}

shape{blue!80}{(0,0)}{2}{-90}{-90}{180}
shape{blue!80}{(0,0)}{2}{-90}{-90}{-180}

shape{blue!60}{(0,0)}{6}{-90}{-90}{180}
shape{blue!60}{(0,0)}{6}{-90}{-90}{-180}

shape{blue!50}{(0,0)}{150}{-90}{-90}{180}
shape{blue!50}{(0,0)}{150}{-90}{-90}{-180}

end{tikzpicture}

end{document}

enter image description here

2 Answers

I propose two constructions (answers):

  1. flattening the annulus enter image description here

  2. flattening and stretching the annulus. enter image description here

Assume that the annulus is a family of concentric circles spread between the interior and exterior frontier circles. Each circle of this family is transformed during the flattening process and eventually becomes a segment. In the first construction, the length of these curves is constant throughout the process. In particular, the region of the plane that represents the deformed annulus has constant area. In the second construction, these curves have increasing length, but the one corresponding to the exterior circle.

Before giving the code some explanations. We consider an annulus with S and N two diametrically opposed points on the exterior circle C. We denote by T_S the tangent line to C at S. We cut the annulus along the ray passing through N and want to flatten it such that, at the end, the curve corresponding to the exterior circle becomes a segment contained in the tangent line T_S with S its midpoint.

enter image description here

I'll briefly explain the first construction which appears, for example, in Cavalieri's work on the method of indivisibles; see https://fr.wikipedia.org/wiki/M%C3%A9thode_des_indivisibles#:~:text=spirale%20d'Archim%C3%A8de.-,Aire%20du%20disque,varie%20de%200%20%C3%A0%20R. It is based on the following idea: to flatten the exterior circle let's say, we imagine it as being a wire with its end points at N, wound around a disk which is tangent to T_S. If the disk's radius increases but the disk remains tangent to T_S, the evolution of the wire gives the desired flattening process of the circle.

enter image description here

The construction is build around this limiting process; there is a set of circles C_k with increasing radii that describe the flattening process of the exterior circle (see the figure above). The interior circle is forced to follow the exterior one in the sens that its flattening process is defined by circles that are concentric to the corresponding C_k circles and remain tangent to the fixed point S'.

To finish the construction, we compute the angles defining all these arcs for each value of k (done through the variable q in the code bellow).

The code for the first construction

documentclass[margin=10pt]{standalone}
usepackage[rgb]{xcolor}
usepackage{tikz}
usetikzlibrary{math, calc}
xdefinecolor{O}{RGB}{255, 102, 17}
xdefinecolor{R}{RGB}{238, 34, 34}
xdefinecolor{B}{RGB}{17, 87, 221}

begin{document}
tikzmath{%
  real r, R, h, q;
  r = 1.5;
  R = 2.75;
  h = R-r;
}
begin{tikzpicture}[every node/.style={scale=0.8}, rotate=-90]
  path[clip] (-R-2, -10) rectangle (R+1, 10);
  path
  (R, 0) coordinate (S)
  (-R, 0) coordinate (N);

  draw[B, fill=B!30, fill opacity=.5, even odd rule]
  (0, 0) circle (r)
  (0, 0) circle (R);

  % foreach k [evaluate=k as q using r/(k*R-h)]
  % in {1.03, 1.1, 1.2, 1.32, 1.5, 1.7, 2, 2.4, 3, 3.8, 5.1, 8, 17}{%
  foreach k [evaluate=k as q using r/(k*R-h)]
  in {1.03, 1.2, 1.5, 2, 3, 5, 8, 17}{%
    path
    ($({(1-k)*R}, 0) + (-{180*q}: {k*R-h})$) coordinate (A)
    ($({(1-k)*R}, 0) + ({180*q}: {k*R-h})$) coordinate (B)
    ($({(1-k)*R}, 0) + ({180/k}: {k*R})$) coordinate (C)
    ($({(1-k)*R}, 0) + (-{180/k}: {k*R})$) coordinate (D);    
    draw[B, fill=B!30, fill opacity=.5]
    (D) -- (A) arc ({-180*q}: {180*q}: {k*R-h}) -- 
    (B) -- (C) arc ({180/k}: {-180/k}: {k*R}) -- cycle;
  }
  draw[B, fill=B!30, fill opacity=.5] (r, -{3.142*r}) -- (r, {3.142*r})
  -- (R, {3.142*R}) -- (R, -{3.142*R}) -- cycle;
end{tikzpicture}

In the code for the second construction, the lines corresponding to the foreach command and the last two ones are replaced by what follows.

  foreach k in {1.03, 1.2, 1.5, 2, 3, 5, 8, 17}{%
    path
    ($({(1-k)*R}, 0) + (-{180/k}: {k*R-h})$) coordinate (A)
    ($({(1-k)*R}, 0) + ({180/k}: {k*R-h})$) coordinate (B)
    ($({(1-k)*R}, 0) + ({180/k}: {k*R})$) coordinate (C)
    ($({(1-k)*R}, 0) + (-{180/k}: {k*R})$) coordinate (D);    
    draw[B, fill=B!30, fill opacity=.5]
    (D) -- (A) arc ({-180/k}: {180/k}: {k*R-h}) -- 
    (B) -- (C) arc ({180/k}: {-180/k}: {k*R}) -- cycle;
  }
  draw[B, fill=B!30, fill opacity=.5]
  (r, -{3.142*R}) rectangle (R, {3.142*R});

Remark. Since the angles appearing in the command arc are angles measured with respect to the Ox axis (of the TikZ coordinate system), I made all the drawing vertically and then rotated the images.

With not too many changes, we can obtain animations of the two constructions. enter image description here enter image description here

Here is a code yielding the images that compose the first animation, for example.

documentclass[multi=page, margin=10pt]{standalone}
usepackage[rgb]{xcolor}
usepackage{tikz}
usetikzlibrary{math, calc}
xdefinecolor{R}{RGB}{238, 34, 34}
xdefinecolor{B}{RGB}{17, 87, 221}

begin{document}
tikzmath{%
  real r, R, h, q;
  r = 1.5;
  R = 2.75;
  h = R-r;
}
begin{page}
  begin{tikzpicture}[rotate=-90]
    path[clip] (-R-2, -10) rectangle (R+1, 10);
    draw[B, fill=B!50, even odd rule]
    (0, 0) circle (r)
    (0, 0) circle (R);
  end{tikzpicture}
end{page}
  foreach k [evaluate=k as q using r/(k*R-h)]
  in {1.03, 1.1, 1.2, 1.32, 1.5, 1.7, 2, 2.4, 3, 3.8, 5.1, 8, 17}{%
  begin{page}
    begin{tikzpicture}[rotate=-90]
      path[clip] (-R-2, -10) rectangle (R+1, 10);      
      path
      ($({(1-k)*R}, 0) + (-{180*q}: {k*R-h})$) coordinate (A)
      ($({(1-k)*R}, 0) + ({180*q}: {k*R-h})$) coordinate (B)
      ($({(1-k)*R}, 0) + ({180/k}: {k*R})$) coordinate (C)
      ($({(1-k)*R}, 0) + (-{180/k}: {k*R})$) coordinate (D);    
      draw[B, fill=B!50]
      (D) -- (A) arc ({-180*q}: {180*q}: {k*R-h}) -- 
      (B) -- (C) arc ({180/k}: {-180/k}: {k*R}) -- cycle;
      draw[R, thick] (A) -- (D)  (B) -- (C);
    end{tikzpicture}    
  end{page}
}
foreach k in {1, 2, 3, 4}{% the last image lasts longer
  begin{page}
    begin{tikzpicture}[rotate=-90]
      path[clip] (-R-2, -10) rectangle (R+1, 10);
      draw[B, fill=B!50] (r, -{3.142*r}) -- (r, {3.142*r})
      -- (R, {3.142*R}) -- (R, -{3.142*R}) -- cycle;
      draw[R, thick]
      (r, -{3.142*r}) -- (R, -{3.142*R})
      (r, {3.142*r}) -- (R, {3.142*R});
    end{tikzpicture}
  end{page}
}
end{document}

Correct answer by Daniel N on September 1, 2021

This is a partial answer, but it feels appropriate to place my code here rather than editing my question over and over. Recap: my original question was (to coin a term) How to uncoil an annulus? My aim was to draw a "simulation" of cutting an annulus at the top and bending the two parts until they lay horizontally (see the first figure in my original question).

Part 1: Cutting and Bending an Arc

First, here is code that "uncoils arcs". The result is similar to what I presented in an edit to my question, except that now I have a more robust way of calculating the positions of the "fixed point" (in the example, the point in center-south position) and of the "cut point" (in the example, the point that starts at the center-north position and is gradually pulled to the left/right until it lies at a horizontal distance equal to the radius).

I modified the arc command to use the center of the circle as an input, rather than a point on the circumference (as intended with the arc command). Here is where I saw how to do that. I made one small change to the usual syntax because I wanted to be able to call this way: (center)(radius)(start angle:end angle). That's because I intend to call the annulus with: (center)(inner radius:outer radius)(start angle:end angle). I wanted to be able to input the center of the annulus, rather than a point on the circumference, because it seemed more natural to me.

I then introduced a dilation factor, that is the factor by which the radius of the arc is increased in order to give the uncoiling effect. The radius is increased from the "fixed point" to the center. To keep the length of the arc fixed, the "end angle" used in the arc command has to change according to the value of the dilation.

documentclass[margin=3mm]{standalone}
usepackage{tikz}
usepackage[EULERGREEK]{sansmath}
usetikzlibrary{calc}
usetikzlibrary{shapes}
usetikzlibrary{shapes.misc}% "cross out" shape
usepackage{amssymb}% symbols
pgfdeclarelayer{bg}
pgfdeclarelayer{fg}
pgfsetlayers{bg,main,fg}

% arcus(center)(radius)(start angle:end angle)
newcommandarcus{}
defarcus(#1)(#2)(#3:#4){%
  ($(#1)+({#2*cos(#3)},{#2*sin(#3)})$)arc(#3:#4:#2)}

% cutarcus(center)(radius)(fixpoint:cutpoint)(dilation)
newcommandcutarcus{}
defcutarcus(#1)(#2)(#3:#4)(#5){%
  ($(#1)+({#2*cos(#3)},{#2*sin(#3)})$)arc(#3:#3+(#4-#3)/#5:#2*#5)}

% mark the cutpoint (depends on dilation factor)
defcutpoint[#1,(#2)](#3)(#4)(#5:#6)(#7){%
  pathcutarcus(#3)(#4)(#5:#6)(#7)node[#1,pos=1,font=tiny]{#2};}

% mark the fixpoint (independent of dilation factor)
deffixpoint[#1,(#2)](#3)(#4)(#5:#6)(#7){%
  pathcutarcus(#3)(#4)(#5:#6)(#7)node[#1,pos=0,font=tiny]{#2};}

tikzset{%
  center/.style={circle, fill, fill=white, draw=black, minimum size=2pt, inner sep=0pt, outer sep=0pt},
  fixpoint/.style={diamond, fill, fill=black, draw=black, minimum size=2pt, inner sep=0pt, outer sep=0pt},
  cutpoint/.style={circle, fill, fill=black, draw=black, minimum size=2pt, inner sep=0pt, outer sep=0pt},}

begin{document}

begin{tikzpicture}[font=sffamilytiny,scale=1]

% background layer
begin{pgfonlayer}{bg}
  % define grid lines
  draw[help lines, color=gray!30, dashed, line width=0.5pt]% 
    (-3.5,-1.5) grid (3.5,1.5);
end{pgfonlayer}

% foreground layer
clip (-1.5,-1.5) rectangle + (3,4.5);

begin{pgfonlayer}{fg}

foreach m in {1,2,4,8,16,32,64}
%foreach m in {1,1.1,...,100}
{%
  draw[red]cutarcus(0,0)(1)(270:90)(m);
  draw[blue]cutarcus(0,0)(1)(-90:90)(m);
  % label the cutpoints
  cutpoint[blue,($bullet$)](0,0)(1)(-90:90)(m);
  cutpoint[red,($bullet$)](0,0)(1)(270:90)(m);
}%

% label the center
node at (0,0) [font=tiny] {$circ$};

% label the fixed point
fixpoint[black,($mathbin{blacklozenge}$)](0,0)(1)(-90:90)(1);

% make a legend  
matrix [draw,below left] at (3,3) {
  node [center,label=right:center] {}; 
  node [fixpoint,label=right:fixed point] {}; 
  node [cutpoint,label=right:cut point] {}; 
};

end{pgfonlayer}

end{tikzpicture}

end{document}

enter image description here

The colors are just a way of indicating that I split the problem into two parts (here, left and right). If you look carefully at the code, you'll see that my legend was produced by creating tikz styles, while the labels in the figure rely on other code. That's because I produced the legend as an afterthought and I couldn't quickly see how to make the legend consistent with the symbols used (or vice versa), and decided to move on.

Part 2: Cutting and Bending an Annulus [UNFINISHED]

Now on to "cutting the annulus". The code appears to produce the correct lines, but sadly the color fill isn't applied properly. Perhaps someone can help me fix the problem. Or offer a better solution.

documentclass[margin=3mm]{standalone}
usepackage{tikz}
usetikzlibrary{calc}

% cutarcus(center)(radius)(fixpoint:cutpoint)(dilation)
newcommandcutarcus{}
defcutarcus(#1)(#2)(#3:#4)(#5){%
  ($(#1)+({#2*cos(#3)},{#2*sin(#3)})$)arc(#3:#3+(#4-#3)/#5:#2*#5)}

% cutannulus(center)(inner radius:outer radius)(fixpoint:cutpoint)(dilation)
newcommandcutannulus{}
defcutannulus[#1](#2)(#3:#4)(#5:#6)(#7){%
  filldraw[fill opacity=0.5,#1,even odd rule]cutarcus(#2)(#3)(#5:#6)(#7)cutarcus(#2)(#4)(#5:#6)(#7)}

begin{document}

begin{tikzpicture}

filldraw[fill=gray!50]arcus(0,0)(1)(-180:180);
cutannulus[fill=blue!50](0,0)(1:2)(270:90)(1);
cutannulus[fill=blue!50](0,0)(1:2)(-90:90)(1);

begin{scope}[yshift=-5cm,on grid]
filldraw[fill=gray!50]arcus(0,0)(1)(-180:180);
cutannulus[fill=blue!50](0,0)(1:2)(270:90)(1.5);
cutannulus[fill=blue!50](0,0)(1:2)(-90:90)(1.5);
end{scope}

end{tikzpicture}

end{document}

The fill color isn't applied properly:

enter image description here

Because of my limited experience in creating tikz commands, they are very sensitive to spaces. The arguments must be given without white spaces in between (and naturally, the bracket scheme must be respected).

Answered by PatrickT on September 1, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP