Circle spiral

approximate a circle with many vertices

by Nicolaus Maloney

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.23.0/ramda.js"></script>
<canvas id='c'></canvas>

JavaScript

const width = 500,
      height = 500;
var canvas = new fabric.Canvas('c', {
  width: width,
  height: height,
});
const ctx = canvas.getContext();
ctx.translate(Math.floor(width / 2), 
  Math.floor(height / 2));

const num = 24;
const r = 50;

const vertex = R.range(0, num).map(i => ({
  x: r * Math.cos(i * 2 * Math.PI / num),
  y: r * Math.sin(i * 2 * Math.PI / num),
}));

/* const vertex = [
  { x: 0, y: -70 },
  { x: -50, y: 50 },
  { x: 50, y: 50 },
  { x: 70, y: -20 },
]; */

// This defines the initial state
const initial = {
  iter: 0,
  scale: 1,
  x: vertex[0].x,
  y: vertex[0].y,
};

// This function takes the last state, and return the next state
function getNext(last) {
  const iter = last.iter + 1,
        scale = last.scale * 1.009,
      v = vertex[iter % vertex.length];
  return {
    iter: iter,
    scale: scale,
    x: v.x * scale,
    y: v.y * scale,
  };
}

// This takes last and next, and does the drawing
function draw(last, next) {
  const opts = {
    stroke: `hsl(${(last.iter * 10) % 360}, 100%, 50%)`,
    //stroke: 'hsl(50, 100%, 50%)',
    strokeWidth: 5 * last.scale,
    fill: false,
    strokeLineCap: 'round',
  };
  const path = new fabric.Path(`M ${last.x} ${last.y} ` +
    `L ${next.x} ${next.y}`, opts);    
  canvas.add(path);
}

// This function takes the last state, computes the next state,
// draws, and returns the new state.
function segment(last) {
  const next = getNext(last);
  draw(last, next);
  return next;
}

var last = initial;
for (var i = 0; i <200; ++i) {
  last = segment(last);
}