Just one of the spirals from the "Triskelion 🌀" by Jurgen
Triskelion 🌀
Log in to post a comment.
// Forked from "Triskelion 🌀" by Jurgen
// https://turtletoy.net/turtle/e994e50d7a
const rIncPerRev = 2; //min=2 max=50 step=1
const rMin = 48; //min=5 max=500 step=1
const correctCenter = 1;
const outline = 1;
const hatching = 0;
// 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 add2 = (a, b) => [a[0]+b[0],a[1]+b[1]];
const lenSq2 = (a) => a[0]**2+a[1]**2;
const len2 = (a) => lenSq2(a)**.5;
const rot2 = (a) => [Math.cos(a), -Math.sin(a), Math.sin(a), Math.cos(a)];
const trans2 = (m, a) => [m[0]*a[0]+m[2]*a[1], m[1]*a[0]+m[3]*a[1]];
const spiralPts = spiral(rIncPerRev, rMin, Math.PI, 0.1);
const startR = spiralPts[0][0];
const endR = len2(spiralPts[spiralPts.length - 1]);
const width = startR + endR * 2;
const height = (width**2 - (width/2)**2)**.5;
const pts = Array.from({length: 1}).flatMap((v, t) => spiralPts.map(p => trans2(rot2(t*4*Math.PI/3), p)).map(p => add2(trans2(rot2(t*4*Math.PI/3), [-width/2, height/3]), p)))
const centerOffset = correctCenter? pts.reduce((p, c) => [[Math.min(p[0][0], c[0]), Math.max(p[0][1], c[0])], [Math.min(p[1][0], c[1]), Math.max(p[1][1], c[1])]], [[0,0],[0,0]]).map(i => (-i[0]-i[1])/2): [0, 0];
const walk = (i) => outline === 0? false: turtle[i==0?'jump':'goto'](add2(centerOffset, pts.shift())) || pts.length > 0;
function spiral(rIncreasePerRev, rMin, angleOne, angleTwo) {
const result = [];
const res = 100; //resolution
const phaseOneMax = 2 * Math.PI * Math.ceil(rMin / rIncreasePerRev) + angleOne;
const phaseTwoMax = 2 * Math.PI * Math.ceil(rMin / rIncreasePerRev) + angleTwo;
let phase = 0;
let i = 0;
while(phase < phaseOneMax || phase < phaseTwoMax) {
phase = 2 * Math.PI * i / res;
const r = rIncreasePerRev * i / res;
if(phase < phaseOneMax) result.unshift([r * -Math.cos(phase), r * Math.sin(phase)]);
if(phase < phaseTwoMax) result.push([r * Math.cos(phase), r * -Math.sin(phase)]);
i++;
}
result.unshift([(phaseOneMax / (2*Math.PI)) * rIncreasePerRev * -Math.cos(phaseOneMax), (phaseOneMax / (2*Math.PI)) * rIncreasePerRev * Math.sin(phaseOneMax)]);
result.push([(phaseTwoMax / (2*Math.PI)) * rIncreasePerRev * Math.cos(phaseTwoMax), (phaseTwoMax / (2*Math.PI)) * rIncreasePerRev * -Math.sin(phaseTwoMax)]);
return result;
}