如何将位置固定在圆上?

问题描述 投票:0回答:1

我试图将一个小点夹入球体中,但每次这样做时,我都会得到一个矩形 - 我怎样才能正确地夹住它?

const canvas = document.getElementById("canvas");

const center = { x: canvas.width / 2, y: canvas.height / 2 }
const point = { ...center }

const ctx = canvas.getContext("2d");

const GROUND_RADIUS = 50;

function render() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  // ground

  ctx.beginPath();
  ctx.arc(center.x, center.y, GROUND_RADIUS, 0, 2 * Math.PI);
  ctx.stroke(); 

  // point

  ctx.beginPath();
  ctx.arc(point.x, point.y, 10, 0, 2 * Math.PI);
  ctx.fill();
  
  requestAnimationFrame(render)
}

requestAnimationFrame(render)

canvas.addEventListener("mousemove", event => {
  point.x = Math.max(Math.min(event.clientX, center.x + GROUND_RADIUS), center.x - GROUND_RADIUS);
  point.y = Math.max(Math.min(event.clientY, center.y + GROUND_RADIUS), center.y - GROUND_RADIUS);
})
canvas {
  border: 1px solid black;
}
<canvas id="canvas" width="150" height="150">

javascript canvas
1个回答
2
投票

位置与中心的角度等于

Math.tan(y/x)
。通过使用一些三角函数,我们可以将
x
限制为
radius * cos(alpha)
,对于
y
也同样(使用
sin
函数)。

const canvas = document.getElementById("canvas");
const status = document.getElementById("status");

const center = {
  x: canvas.width / 2,
  y: canvas.height / 2
}

const point = { ...center }

const ctx = canvas.getContext("2d");

const GROUND_RADIUS = 50;

function render() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  // ground
  ctx.beginPath();
  ctx.arc(center.x, center.y, GROUND_RADIUS, 0, 2 * Math.PI);
  ctx.stroke();

  // point
  ctx.beginPath();
  ctx.arc(point.x, point.y, 10, 0, 2 * Math.PI);
  ctx.fill();

  requestAnimationFrame(render)
}

function getAngle(dy, dx) {
  return (Math.atan2(dy, -dx) * 180 / Math.PI + 360) % 360;
}

requestAnimationFrame(render)

canvas.addEventListener("mousemove", event => {
  point.x = event.offsetX
  point.y = event.offsetY

  var dx = (center.x - point.x)
  var dy = (center.y - point.y)
  var alpha = getAngle(dy, dx);
  status.innerText = dx + ", " + dy + " and alpha = " + alpha.toFixed(2);

  var maxX = Math.abs(GROUND_RADIUS * Math.cos(alpha / 180 * Math.PI));
  var maxY = Math.abs(GROUND_RADIUS * Math.sin(alpha / 180 * Math.PI));

  dx = Math.min(Math.max(-maxX, dx), maxX)
  dy = Math.min(Math.max(-maxY, dy), maxY)

  point.x = -dx + center.x
  point.y = -dy + center.y
})
canvas {
  border: 1px solid black;
}
<div id="status"></div>
<canvas id="canvas" width="320" height="200">

© www.soinside.com 2019 - 2024. All rights reserved.