### The knot 10_123

This flowery shape has a sort of sacred significance to me, it symbolizes five vows I made to Jesus many years ago: one of Love (or one might say Growth), one of Honesty, one of Compassion, one of Ambition, and one of Humility.

The beauty in these diagrams comes from wanting circular arcs in a polyhedron which are tangent to the lines of that polyhedron (dotted lines). What makes the middle wonderful is that the inner arcs have the same radius as the bounding circle. That's actually also true for the top diagram, too.

Created by crdrost on 2018/12/18
126
2

```// You can find the Turtle API reference here: https://turtletoy.net/syntax
Canvas.setpenopacity(1);

// Global code will be evaluated once.
const turtle = new Turtle();

const deg = Math.PI/180;
const sind = angle => Math.sin(deg * angle);

const dotting = 0.125;
const dotting_count = 20;

function flower(R, num_sides, skip_nodes) {
// to describe a regular n-gon a turtle has to turn by τ = 360° / n.
const turn = 360 / num_sides;
// side length of the polygon, necessary to walk between sublattices
const len = R * 2 * sind(turn / 2);
if (skip_nodes <= 0) {
// degenerate case with infinitely large circles centered at infinity
return i => {
if (i >= num_sides) {
// reset orientation and be done
turtle.left(turn / 2);
return false;
}
if (i === 0) {
turtle.right(turn / 2);
}
const major = dotting * len / dotting_count;
const minor = (1 - dotting) * len / dotting_count;
for (let i = 0; i < dotting_count; i++) {
turtle.forward(major/2);
turtle.penup();
turtle.forward(minor);
turtle.pendown();
turtle.forward(major/2);
}
turtle.right(turn);
return true;
}
}
/*
Let s be the number of skipped nodes in the n-gon, with points G_1, ... G_n.
We'll number these so the inner-circle arc begins at B = G_1 and ends at E = G_{s+2}.
The arc is centered at some flower center F while the bounding circle is centered at
some absolute center C.

We first want to know how much angle the circular arc about F subtends, call that ψ, then
we can use that to calculate the radius.

We can calculate ψ with turtle power! Since we have tangency, a turtle which walks the arc
must turn just as much as a turtle that walks from B to E along the G_i, and that one turns
a total of s times by τ (defined above), so

ψ = s · 360° / n.
*/
const arc_angle = skip_nodes * 360 / num_sides;
/*
Now for the radius, we have the angle ∠BFC = ψ/2 and we need ∠CFB. There are two ways to see
this angle. The first is directly: an angle ∠G_iCG_{i+1} subtends 360° / n and walking
backwards from G_1 = G_{n+1} back to G_{s+2} we have n − s − 1 arcs of that size, CF must
bisect that angle. But I also like the turtle argument: think about the line tangent to the
circle at B, and for clarity let's rotate or project G_2 onto a point L on this line so that we
have some point on that line to talk about. We saw above that this angle ∠LBG_2 is τ / 2, that
is how much the turtle has to turn to begin the inscribed n-gon after walking the circle that
circumscribes it. But notice that you have two right angles which share B: ∠LBC = 90° and of
course that from tangency, ∠FBG_2 = 90°, and you know that the rotation mapping the one onto
the other is τ / 2. This rotation appears directly as also being ∠FBC = τ / 2.

So since we are looking at this triangle FBC with angles s τ / 2 and τ / 2, the remaining angle
is just ∠BCF = 180° − (s + 1) τ / 2.

Once we have this triangle we can say that its altitude must be:

R sin ∠BCF = r sin ∠CFB

which gives us r/R. Since the sin(180° − x) = sin(x) we have just:
*/
const r = R * sind((skip_nodes + 1) * turn / 2) / sind(skip_nodes * turn / 2);
return i => {
if (i >= num_sides) {
turtle.right(turn / 2);
return false;
}
if (i === 0) {
turtle.right(turn / 2);
} else if ( i * (skip_nodes + 1) % num_sides === 0) {
turtle.penup();
turtle.forward(len);
turtle.right(turn);
turtle.pendown();
}
turtle.circle(r, arc_angle);
turtle.right(turn);
return true;
};
}
function doFlower(center_x, center_y, radius, sides, skip) {
turtle.penup();
turtle.pendown();
const straights = flower(radius, sides, 0);
for (let i = 0; straights(i); i++);
const walker = flower(radius, sides, skip);
for (let i = 0; walker(i); i++);
}

function walk(i) {
switch (i) {
case 0:
doFlower(0, -80, 10, 3, 1);
return true;
case 1:
doFlower(-40, -50, 10, 4, 1);
return true;
case 2:
doFlower(40, -50, 10, 4, 2);
return true;
case 3:
doFlower(-65, 2.5, 10, 5, 1);
return true;
case 4:
doFlower(0, 2.5, 40, 5, 2);
return true;
case 5:
doFlower(65, 2.5, 10, 5, 3);
return true;
case 6:
doFlower(-65, 65, 10, 6, 1);
return true;
case 7:
doFlower(-22.5, 65, 10, 6, 2);
return true;
case 8:
doFlower(22.5, 65, 10, 6, 3);
return true;
case 9:
doFlower(65, 65, 10, 6, 4);
return true;
default:
return false;
}
}
```