0

I'm trying to highlight pixels that fall within a sector of a circle. I'm writing a shader to do this, but I'm implementing the logic in JavaScript until I get it right.

Essentially, each pixel coordinate in a canvas is scaled to be between 0 and 1, and is passed into the following code along with the canvas context:

function isWithinSector(ctx, x, y) {
  let startAngle = degToRad(135), endAngle = degToRad(205);

  // Distance of pixel from the circle origin (0.5, 0.5).
  let dx = scaledX - 0.5;
  let dy = scaledY - 0.5;

  let angle = Math.atan2(dy, dx);

  if (angle >= startAngle && angle <= endAngle) {
    ctx.fillStyle = "rgba(255, 255, 0, .5)";
    ctx.fillRect(x, y, 1, 1);
  }
}

This works fine for some angles, but not for others. Pixels highlighted between 135 and 205 degrees appear like this (i.e. only 135 to 180 degrees are highlighted):

Canvas

Note that the highlighted pixels don't match my black arc (the source of truth). I've been trying all kinds of things from Google but I'm stuck.

I have a CodePen that shows the issue: https://codepen.io/chrisparton1991/pen/XRpqXb. Can anybody guide me on what I'm doing wrong in my algorithm?

Thanks!

Chris Parton
  • 1,052
  • 9
  • 16
  • possible duplicate of [this](http://stackoverflow.com/questions/14120015/check-if-coordinate-in-selected-area) – Torben Apr 27 '17 at 11:19

1 Answers1

1

You get the problem if the angle is greater than 180°, as the atan2 function will then return a negative angle that is 360° smaller. This can be corrected by

let angle = Math.atan2(dy, dx);
if (angle<0) angle += 2*Math.PI;

But this is still not sufficient if you want to highlight the sector from 350° to 10°, that is, the small sector containing the 0° ray. Then the following extended normalization procedure helps.

let angle = Math.atan2(dy, dx);
let before = angle-startAngle;
if(before < -Math.PI) 
    before += 2*Math.PI; 
let after = angle-endAngle;
if(after < -Math.PI)
    after += 2*Math.PI;

Note that your image is upside-down as the screen origin is top-right, where you put the coordinates (0,1).

Lutz Lehmann
  • 25,219
  • 2
  • 22
  • 51
  • Great, thanks for your help. I had been fiddling with adding 2*pi earlier, but it wasn't solving all my issues. Namely, I need to be able to have 0 degrees facing upwards. I've found that flipping and inverting the arguments to atan2() in various combinations will do this for me, along with adding 2*pi. – Chris Parton Apr 28 '17 at 03:40