Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What algorithm can I use to determine points within a semi-circle?

I have a list of two-dimensional points and I want to obtain which of them fall within a semi-circle.

Originally, the target shape was a rectangle aligned with the x and y axis. So the current algorithm sorts the pairs by their X coord and binary searches to the first one that could fall within the rectangle. Then it iterates over each point sequentially. It stops when it hits one that is beyond both the X and Y upper-bound of the target rectangle.

This does not work for a semi-circle as you cannot determine an effective upper/lower x and y bounds for it. The semi-circle can have any orientation.

Worst case, I will find the least value of a dimension (say x) in the semi-circle, binary search to the first point which is beyond it and then sequentially test the points until I get beyond the upper bound of that dimension. Basically testing an entire band's worth of points on the grid. The problem being this will end up checking many points which are not within the bounds.

like image 910
khayman218 Avatar asked Feb 11 '09 00:02

khayman218


People also ask

How do you find the points of a semicircle?

In general, when the equation (x - h)2 + ( y - k)2 = r 2 is solved for y, the result is a pair of equations in the form y = ±√r 2 - (x - h)2 + k. The equation with the positive square root describes the upper semicircle, and the equation with the negative square root describes the lower semicircle.

How do you check if a given point is inside a circle?

If you have the equation of the circle, simply plug in the x and y from your point (x,y). After working out the problem, check to see whether your added values are greater than, less than, or equal to the r^2 value. If it is greater, then the point lies outside of the circle.

How do you find all points on a circle?

For a circle with center (0,0) the equation of a circle is x^2 + y^2 = r^2 (which is the Pythagorean Theorem). So given a center point (h,k) and radius r you can find the points (x,y) that lie on the circumference of the circle.


1 Answers

Checking whether a point is inside or outside a semi-circle (or a rectangle for that matter) is a constant-time operation.

Checking N points lie inside or outside a semi-circle or rectangle is O(N).

Sorting your N points is O(N*lg(N)).

It is asymptotically faster to test all points sequentially than it is to sort and then do a fast culling of the points based on a binary search.

This may be one of those times where what seems fast and what is fast are two different things.

EDIT

There's also a dead-simple way to test containment of a point in the semi-circle without mucking about with rotations, transformations, and the like.

Represent the semi-circle as two components:

  • a line segment from point a to b representing the diameter of the semi-circle
  • an orientation of either left-of or right-of indicating that the semi-circle is either to the left or right of line segment ab when traveling from a to b

You can exploit the right-hand rule to determine if the point is inside the semicircle.

Then some pseudo-code to test if point p is in the semi-circle like:

procedure bool is_inside:
    radius = distance(a,b)/2
    center_pt = (a+b)/2    
    vec1 = b - center_pt
    vec2 = p - center_pt
    prod = cross_product(vec1,vec2) 
    if orientation == 'left-of'
        return prod.z >= 0 && distance(center_pt,p) <= radius
    else
        return prod.z <= 0 && distance(center_pt,p) <= radius

This method has the added benefit of not using any trig functions and you can eliminate all square-roots by comparing to the squared distance. You can also speed it up by caching the 'vec1' computation, the radius computation, center_pt computation, and reorder a couple of the operations to bail early. But I was trying to go for clarity.

The 'cross_product' returns an (x,y,z) value. It checks if the z-component is positive or negative. This can also be sped up by not using a true cross product and only calculating the z-component.

like image 170
user21714 Avatar answered Apr 15 '23 23:04

user21714