Reputation: 396
How can i draw a circle using lines, by having a constant pixel difference between points?
I have been trying to edit this algorithm
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var step = 2 * Math.PI / 22; //(22 points)
var h = 250;
var k = 250;
var r = 105;
ctx.beginPath(); //tell canvas to start a set of lines
for (var theta = 0; theta < 2 * Math.PI; theta += step) {
var x = h + r * Math.cos(theta);
var y = k - r * Math.sin(theta);
ctx.lineTo(x, y);
ctx.stroke();
}
ctx.closePath();
#myCanvas {
border: thin solid grey;
}
<canvas id="myCanvas" width="500px" height="500px"></canvas>
This algorithm draws a circle which has 22 points. How can i change this algorithm so that a pixel difference between two points will always be a value, for example 50 pixels between each point?
Upvotes: 1
Views: 928
Reputation: 48600
If you want the distance between the points to be consistent, you can calculate the radius given the number of points (aka sides) and the distance you want the points to be apart from one another.
x = (distance / 2) / sine(step / 2)
const sides = 3;
const distance = 100;
const step = Math.PI * 2 / sides;
const radius = (distance / 2) / Math.sin(step / 2); // 57.735
In the example below, eight (odd-sided) polygons are drawn with each adjacent point 50 pixels from one another.
const DEBUG = true;
const main = () => {
const
ctx = document.getElementById('myCanvas').getContext('2d'),
origin = { x: ctx.canvas.width / 2, y: ctx.canvas.height / 2 },
distance = 50, maxPoints = 18, start = 3, step = 2;
for (let points = start; points < maxPoints; points += step) {
drawCircle(ctx, origin.x, origin.y, distance, points);
}
};
const drawCircle = (ctx, x, y, distance, sides) => {
if (sides < 2) throw new Error('Circle must have 3 or more sides');
const
vector = (x, y, radius, theta) => ({
x: x + radius * Math.cos(theta),
y: y + radius * Math.sin(theta)
}),
d = 2 * Math.PI,
step = d / sides,
radius = (distance / 2) / Math.sin(step / 2),
limit = d + step;
// Display
if (DEBUG) {
const
d2 = distance / 2, h = ctx.canvas.height / 2,
y1 = h - d2, y2 = h + d2, x1 = 0, x2 = ctx.canvas.width;
ctx.beginPath();
ctx.setLineDash([2, 5]);
ctx.strokeStyle = 'red';
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y1);
ctx.moveTo(x1, y2);
ctx.lineTo(x2, y2);
ctx.stroke();
ctx.closePath();
}
ctx.beginPath();
ctx.setLineDash([]);
ctx.strokeStyle = 'blue';
for (let theta = 0; theta < limit; theta += step) {
const { x: xOffset, y: yOffset } = vector(x, y, radius, theta);
ctx.lineTo(xOffset, yOffset);
}
ctx.stroke();
ctx.closePath();
};
main();
#myCanvas {
border: thin solid grey;
}
<canvas id="myCanvas" width="300px" height="300px"></canvas>
Upvotes: 2