Markers at specific distances along an archimedian spiral

by issackelly

HTML

<div>
  <h3>
  Markers at specific distances.
  </h3>
  <canvas id="c" width="400" height="300"></canvas>

  <table>
    <tr>
      <td>Constant modifier</td>
      <td>
        <input id="constant_modifier" type="text" value='4' />
      </td>
    </tr>

    <tr>
      <td>Growth rate. smaller is a tighter spiral</td>
      <td>
        <input id="growth_rate" type="text" value='3' />
      </td>
    </tr>

    <tr>
      <td>Target distance between markers</td>
      <td>
        <input id="target_distance" type="text" value='30' />
      </td>
    </tr>

    <tr>
      <td>Spiral resolution. Smaller approximates curves</td>
      <td>
        <input id="spiral_resolution" type="text" value='0.05' />
      </td>
    </tr>

  </table>


  <button id="draw">Click here to re-draw</button>
  <p>
    By <a href="https://www.issackelly.com/">Issac Kelly</a>
  </p>
</div>

CSS

#c {
  border: 1px solid #6e3982;
}

table {
  width: 400px;
}

button {
  width: 400px;
  font-size: 18px;
  text-align: center;
  background: #6e3982;
  border: 2px solid #FFF;
  color: white;
  font-family: Gotham, Helvetica, sans;
}

body {
  font-family: Gotham, Helvetica, sans;
}

div {
  width: 400px;
  margin: 10px auto;
}

JavaScript

var c = document.getElementById('c');
var context = c.getContext("2d");
var centerx = context.canvas.width / 2;
var centery = context.canvas.height / 2;

marks_at = [40, 60, 100, 200, 280, 600, 900, 1600, 2900, 4000]

$('#draw').click(function() {
  constant_modifier = parseFloat($('#constant_modifier').val());
  growth_rate = parseFloat($('#growth_rate').val());

  target_distance = parseFloat($('#target_distance').val());
  spiral_resolution = parseFloat($('#spiral_resolution').val());
  arc_distance = 0;

  last_x = 0;
  last_y = 0;

  marker_radius = 2;
  spiral_size = 1000;

  context.clearRect(0, 0, 400, 300);

  context.moveTo(centerx, centery);
  context.beginPath();
  for (i = 0; i < spiral_size; i++) {
    angle = i * spiral_resolution;
    x = centerx + (constant_modifier + growth_rate * angle) * Math.cos(angle);
    y = centery + (constant_modifier + growth_rate * angle) * Math.sin(angle);


    var distance = Math.sqrt((last_x - x) * (last_x - x) + (last_y - y) * (last_y - y));
    arc_distance += distance

    //console.log(arc_distance, x, y, last_x, last_y);
    if (marks_at && (arc_distance > marks_at[0])) {
      context.arc(x, y, marker_radius, 0, 2 * Math.PI, false);
      //remove the first item from the markers list
      working_point = marks_at.shift()
      
      //Now you know where the marker goes for this distance, you can take
      //X any Y and convert that into radius and angle.
      var radius = Math.sqrt((centerx - x) * (centerx - x) + (centery - y) * (centery - y));
      var angle = Math.sin(x/radius)
      console.log(working_point, radius, angle);
    }

    last_x = x;
    last_y = y;
    context.lineTo(x, y);
  }

  context.strokeStyle = "#6e3982";
  context.stroke();

});
$("#draw").click();