Jump to content
  • Advertisement
cebugdev

how to check if a point is inside an angle of a circle

Recommended Posts

hi,

like the subject above, how to check if a point/coordinates is inside an arbitrary angle, 

image.png.dc4441bc4c6b36dfbab69e159e747aa3.png

the rendering is in OpenGL orthogonal therefore using 2D screen coordinates with the origin 0,0 is top left, 
In the screenshot above, P1 is inside the angle point therefore will be rendered and P2 is not.

What i am trying to do here is only display the part in the circle using the shaders depending on the angle. Like a circular progress bar or something.

Share this post


Link to post
Share on other sites
Advertisement

I'd say, build the pie shape geometry at run time and submit that to the renderer. The  2D trigeometry or vector math seems straight forward. Are the equations in question here? A spline might be neat here as one of the sides of the dynamic pie shape.

Share this post


Link to post
Share on other sites

You can subtract the center from the point, and consider this 2d vector, if normalized, as x coordinate being cosine and y coordinate being sine.

Then just immediately compare those trigonometric values againts the two reference contain angles trigonomteric values.

Share this post


Link to post
Share on other sites

Its exactly like JohnnyCode explained, so here is a javascript code i have written a few years ago which does exactly that:

/**
  * <p>Normalizes an angle - bring it into 0 - 2 PI range</p>
  * <p>Does handle negative angles as well.</p>
  * @param rad {Number} Angle in radians
  * @returns {Number}
  */
radNormalize: function(rad) {
  while (rad < 0) {
    rad += TAU;
  }
  while (rad > TAU) {
    rad -= TAU;
  }
  return rad;
},

CircleShape.prototype.containsPoint = function (x, y) {
	var v = new Vec2(x - this.pos.x, y - this.pos.y);
	var angle = radNormalize(Math.atan2(v.y, v.x) - this.startAngle);
	var lenSquared = math.vec2Dot(v, v);
	var insideCircle = lenSquared <= this.radius * this.radius;
    var insideSegment = angle <= (this.endAngle - this.startAngle);
	return insideCircle && insideSegment;
};

 

Share this post


Link to post
Share on other sites
Posted (edited)

As usual, you can do this without angles, and you probably should. Friends don't let friends use angles. :)

You are really trying to determine if a vector v is in the arc limited by two other vectors v1 and v2. Start by normalizing all the vectors so they have length 1. Now that we are looking at points on a circle, all you need to do is look at the points (*) v1, v2, v and see if they are in clockwise or anticlockwise order. The function ccw() here does the job: https://algs4.cs.princeton.edu/91primitives/

Or you can try to compute the area of the triangle whose vertices are v1, v2, v using a determinant and check what sign it comes out with. That's essentially the same method. Think about it whichever way seems more natural to you.

You can also use complex numbers to represent points and vectors in 2D. In that case, this code would do the trick:

#include <complex>

typedef std::complex<float> C;

bool is_between(C v, C v1, C v2) {
  v /= std::abs(v);
  v1 /= std::abs(v1);
  v2 /= std::abs(v2);
  return ((v - v1) * std::conj(v - v2)).imag() > 0;
}

(*)- I am being a loose with the distinction between points and vectors here, but non-mathematicians probably won't even notice.

 

Edited by alvaro

Share this post


Link to post
Share on other sites
13 hours ago, GoliathForge said:

I'd say, build the pie shape geometry at run time and submit that to the renderer. The  2D trigeometry or vector math seems straight forward. Are the equations in question here? A spline might be neat here as one of the sides of the dynamic pie shape.

Going further on this, you could just build a circle out of e.g. 360 triangles, then in the drawcall specify the number of triangles to draw, without needing to modify the geometry.

Another way for interesting health bar shapes might be to store the 'maximum angle' for each texel in a texture, then in the fragment shader simply compare a uniform 'health angle' against the stored value. You could then have complex shapes for no extra cost.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!