Reputation:
The following image is a picture of three rotating disks on the theming of Smiler at Alton Towers:
My goal is to draw the rightmost spinner (the one circled in red) on an HTML canvas, using 27 circles of radii that linearly decrease from 270 to 10 (in increments of 10). The code below is the JavaScript code that I came up with,
var num_circles = 27;
var incr = 10;
var margin = 10;
var wr = 10;
var drt = 0.95;
var boxSize = 40 * num_circles;
var half = boxSize / 2 + margin;
$(document).ready(function() {
var cv = document.getElementById("CV");
$(cv).attr("width", boxSize + 2 * margin).attr("height", boxSize + 2 * margin);
$("#ROTATOR").css("width", cv.width).css("height", cv.height);
var ctx = cv.getContext("2d");
ctx.clearRect(0, 0, cv.width, cv.height);
var x = half, y = half;
for (var i = 0; i < num_circles; i++)
{
var j = num_circles - i, r_inst = wr * j;
ctx.beginPath();
ctx.fillStyle = (!(i % 2) ? "#000000" : "#ffff88");
console.log("x = " + (x - half + margin / 2) + ", y = " + (y - half - margin / 2) + ", r = " + r_inst);
var offset_x = wr / 2 * Math.sin(incr * (num_circles - i - 1) * Math.PI / 180);
var offset_y = wr / 2 * Math.cos(incr * (num_circles - i - 1) * Math.PI / 180);
ctx.arc(x, y, r_inst, 0, 2 * Math.PI, false);
// ctx.arc(x, y, r_inst, 0, 2 * Math.PI, false);
ctx.fill();
console.log("offset x = " + offset_x + ", offset y = " + offset_y + ", dist = " + Math.sqrt(Math.pow(offset_x, 2) + Math.pow(offset_y, 2)));
x += offset_x;
y += wr / 2 - offset_y;
}
});
The main problem with my code is that the inner circles are spaced too far apart:
How could I modify this code so that the figure that it draws more closely resembles the spinner in question? More specifically, what am I missing that would allow the circles to maintain the near-tangency?
Upvotes: 4
Views: 74
Reputation: 5960
I tried varying the offset as follows:
var incr = 13;
...
const theta = incr * (j + Math.sqrt(j) + 5) * Math.PI / 180;
var offset_x = wr / 2 * Math.sin(theta);
var offset_y = wr / 2 * Math.cos(theta);
var num_circles = 28;
var incr = 13;
var margin = 10;
var wr = 10;
var drt = 0.95;
var boxSize = 20 * num_circles;
var half = boxSize / 2 + margin;
$(document).ready(function() {
var cv = document.getElementById("CV");
$(cv).attr("width", boxSize + 2 * margin).attr("height", boxSize + 2 * margin);
$("#ROTATOR").css("width", cv.width).css("height", cv.height);
var ctx = cv.getContext("2d");
ctx.clearRect(0, 0, cv.width, cv.height);
var x = half,
y = half;
for (var i = 0; i < num_circles; i++) {
var j = num_circles - i,
r_inst = wr * j;
ctx.beginPath();
ctx.fillStyle = (!(i % 2) ? "#000000" : "#ffff88");
//console.log("x = " + ((x - half + margin) / 2) + ", y = " + ((y - half - margin) / 2) + ", r = " + r_inst);
const theta = incr * (j + Math.sqrt(j) + 5) * Math.PI / 180;
var offset_x = wr / 2 * Math.sin(theta);
var offset_y = wr / 2 * Math.cos(theta);
ctx.arc(x, y, r_inst, 0, 2 * Math.PI, false);
ctx.fill();
//console.log("offset x = " + offset_x + ", offset y = " + offset_y + ", dist = " + Math.sqrt(Math.pow(offset_x - x, 2) + Math.pow(offset_y - y, 2)));
x += offset_x;
y += wr / 2 - offset_y;
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas id="CV"></canvas>
Upvotes: 1