Math.atan2和cos sin角度不与画布相交

时间:2017-04-14 20:55:05

标签: canvas trigonometry sin cos atan2

我需要圆圈始终与线相交。 我是数学函数的新手,并试图牢牢掌握它们。 我认为这与罪和cos有关,但我可能是错的。 为什么它的表现不如预期?

codepen: http://codepen.io/philipbell/pen/PmwybL

let canvas = document.querySelector('#canvas');
let context = canvas.getContext('2d');
let width = canvas.width = window.innerWidth;
let height = canvas.height = window.innerHeight;

let centerY = height / 2;
let centerX = width / 2;

let circleSize = 10;
let Xradius = width / 2 - circleSize;
let Yradius = height / 2 - circleSize;

let angle = 0;

let dx = 10;
let dy = 10;
let distance = 20;

render();

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

  context.save();
  context.translate(centerX, centerY);
  context.rotate(angle);

  context.beginPath();
  context.moveTo(0, 0);
  context.lineTo(window.innerWidth, 0);
  context.moveTo(distance, 0);
  context.lineTo(distance - 10, -10);
  context.moveTo(distance, 0);
  context.lineTo(distance - 10, 10);
  context.stroke();
  context.restore();

  // why isn't the line always intersecting the circle?
  var xCos = centerX + Math.cos(angle) * Xradius;
  var ySin = centerY + Math.sin(angle) * Yradius;
  context.beginPath();
  context.arc(xCos, ySin, circleSize, 0, Math.PI * 2, false);
  context.fill();

  requestAnimationFrame(render);

}

document.body.addEventListener('mousemove', (event) => {
  dx = event.clientX - centerX;
  dy = event.clientY - centerY;
  distance = Math.sqrt(dx * dx + dy * dy)
  angle = Math.atan2(dy, dx) 
})

1 个答案:

答案 0 :(得分:1)

您需要在展平的圆圈中找到角度。要做到这一点,只需将y分量乘以与atan2获得角度时宽度与高度的比率。见例。

从OP的codepen复制并修改的示例。

const ctx = canvas.getContext('2d');
const width = canvas.width = window.innerWidth;
const height = canvas.height = window.innerHeight;

const centerY = height / 2;
const centerX = width / 2;

const circleSize = 10;
const Xradius =(width / 2 - circleSize);
const Yradius =( height / 2 - circleSize);

var dx = 10;
var dy = 10;

render();

function render() {
  var distance;
  var angle;
  var ang2;
  ctx.setTransform(1, 0, 0, 1, 0, 0);
  ctx.clearRect(0, 0, width, height);
  
  distance = Math.sqrt(dx * dx + dy * dy);
  // get angle in scaled space
  ang2 = Math.atan2(dy* (Xradius / Yradius), dx);
  // get angle in unscaled space
  angle = Math.atan2(dy, dx);

  ctx.setTransform(1, 0, 0, 1, centerX, centerY);
  ctx.rotate(angle); // use unscaled angle

  ctx.beginPath();
  ctx.moveTo(0, 0);
  ctx.lineTo(window.innerWidth, 0);
  ctx.moveTo(distance, 0);
  ctx.lineTo(distance - 10, -10);
  ctx.moveTo(distance, 0);
  ctx.lineTo(distance - 10, 10);
  ctx.stroke();
  ctx.setTransform(1, 0, 0, 1, centerX, centerY);
  ctx.beginPath();
  ctx.arc(  // use scaled angle
      Math.cos(ang2) * Xradius,
      Math.sin(ang2) * Yradius, 
      circleSize, 
      0, Math.PI * 2
  );
  ctx.fill();

  requestAnimationFrame(render);

}

document.body.addEventListener('mousemove', (event) => {
  dx = event.clientX - centerX;
  dy = event.clientY - centerY;
})
canvas {
   position: absolute;
   top : 0px;
   left : 0px;
}
<canvas id=canvas></canvas>