使用线条以编程方式绘制圆

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>