haz hazzz
haz hazzz

Reputation: 113

Point in circle segment

I have a circle I want to divide up in to a number of segments all defined by X and Y coordinates. How to I test to see if a point (X, Y) is in a particular segment?

A code example would be preferable.

Upvotes: 2

Views: 1253

Answers (4)

helloflash
helloflash

Reputation: 2457

Your segment is defined by two intersections between the circle and a line. You just have to know if:

  • The angle between the center of your circle and your point is between the angles formed by the two previous points and the center.
  • the point is in the circle (the length from this point to the center is smaller than the radius)
  • from what side is the point compared to the line (it must be beyond the line).

Remark

In geometry, a circular segment (symbol: ⌓) is a region of a circle which is "cut off" from the rest of the circle by a secant or a chord.

Here is a segment:

enter image description here

Upvotes: 0

Boann
Boann

Reputation: 50010

  1. If x & y are not already relative to the center of the circle, subtract the coordinates of the center of the circle:

    x -= circle.x
    y -= circle.y
    
  2. Use atan2 to get the angle of the point about the origin of the circle:

    angle = atan2(y, x)
    
  3. This angle is negative for points below the x-axis, so adjust to always be positive:

    if (angle < 0) angle += 2 * pi
    
  4. Assuming your segments are equally spaced, use this formula to get the index of the segment:

    segment = floor((angle * numSegments) / (2 * pi))
    

If you find the result is referring to a segment on the opposite side of the circle to what you want, you might have to do y = -y in the beginning or a segment = (numSegments - 1) - segment at the end to flip it round the right way, but it should basically work.

Upvotes: -1

Sneftel
Sneftel

Reputation: 41454

You don't need to use trigonometry for this (and in general, trigonometry should be avoided whenever possible... it leads to too many precision, domain, and around-the-corner problems).

To determine whether a point P is counter-clockwise of another point A (in the sense of being in the half-plane defined by the left side of a directed line going through the origin and then through A), you can examine the sign of the result of Ax*Py - Ay*Px. This is generally known as the "perpendicular dot product", and is the same as the Z coordinate of the 3D cross product.

If there are two points A and B (with B defining the CCW-most extent) defining a sector, and the sector is less than half the circle, any point which is CCW of A and CW of B can be classified as in that sector.

That leaves only a sector which is more than half of the circle. Obviously, a given set of points can only define at most one such sector. There's clever things you can do with angle bisection, but the easiest approach is probably just to classify points as in that sector if you can't classify them as being in any other sector.

Oh, forgot to mention -- determining the order of the points for the purposes of pairing them up for sectors. Not to go against my previous advice, but the most straightforward thing here is just to sort them by their atan2 (not atan... never ever use atan).

Upvotes: 2

NPE
NPE

Reputation: 500177

Use the polar coordinate system centred at the centre of the circle, and examine the angular coordinate (φ in the Wikipedia article).

What exactly you do with φ depends on how your segments are defined. For example, if you have n equal segments that start at 0 radians, floor(φ * n / (2 * π)) will give you the segment number.

Upvotes: 0

Related Questions