使用线条以编程方式绘制圆
Programmatically draw a circle using lines
如何通过点之间的恒定像素差使用直线绘制圆?
我一直在尝试修改这个算法
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>
这个算法画了一个有22个点的圆。我怎样才能改变这个算法,使两点之间的像素差始终是一个值,例如每个点之间有 50 个像素?
如果您希望点之间的距离一致,您可以根据点数(即边)和您希望点之间的距离来计算半径。
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
演示
在下面的示例中,绘制了八 (odd-sided) 个多边形,每个相邻点彼此相距 50 像素。
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>
如何通过点之间的恒定像素差使用直线绘制圆?
我一直在尝试修改这个算法
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>
这个算法画了一个有22个点的圆。我怎样才能改变这个算法,使两点之间的像素差始终是一个值,例如每个点之间有 50 个像素?
如果您希望点之间的距离一致,您可以根据点数(即边)和您希望点之间的距离来计算半径。
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
演示
在下面的示例中,绘制了八 (odd-sided) 个多边形,每个相邻点彼此相距 50 像素。
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>