javascript - 使用线条以编程方式绘制圆
问题描述
通过在点之间具有恒定的像素差,我如何使用线条画一个圆?
我一直在尝试编辑这个算法
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
演示
在下面的示例中,绘制了八个(奇边)多边形,每个相邻点彼此相距 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>
推荐阅读
- node.js - 尝试解析时未显示由扩展程序生成的 HTML
- c# - Xamarin 上的 FadeIn/FadeOut 背景颜色动画
- javascript - javascript如何只比较json的键而不是值
- r - 为什么 glm 函数返回此警告:glm.fit: 拟合概率为 0 或 1
- android - React Native - 用户向下滚动足够多后,使视图出现并跟随屏幕,视图出现和消失太慢
- c# - 为事件赋值
- javascript - 反应状态反复恢复到旧值
- r - 闪亮的交互式地图中未使用的参数错误
- botframework - 如何在基于 Bot framewok v4 构建的 Teams Chatbot 中启用语音
- android - Recycler 视图 + MQTT 有时不会在数据集更改后重绘