0
\$\begingroup\$

This question already has an answer here:

How can I detect and do something if the cursor is inside a hexagonal shape? Is there any way other than detecting if it's in a rectangle area close to the shape of the hexagon? It would also have to work with a grid of hexagons, detecting each individually.

\$\endgroup\$

marked as duplicate by sam hocevar, congusbongus, Anko, bummzack, Seth Battin Mar 3 '15 at 13:11

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

1
\$\begingroup\$

You can detect on which side of a line the cursor is by using a cross product. If the cursor is on the "inside" of all edges then it is inside of the hexagon. This only works for convex polygons though.

For a grid You can approximate is with a rectangular grid and then refine it by testing just a few lines.

\$\endgroup\$
0
\$\begingroup\$

One way of testing whether or not your point is inside a simple polygon is to use what is called a ray casting algorithm http://en.wikipedia.org/wiki/Point_in_polygon.

What you do is create a line that goes through the point you are checking, and count how many times it intersects with all of the line segments that make up your Polygon.

If the number of intersections is divisible by 2 then the point is outside the Polygon, otherwise it is inside. (Zero is even in this case)

I implemented this function in python using an arbitrarily large line segment for my 'ray'. And used two functions to test line segment intersection.

def counterclockwise(self, A, B, C):
    return (C[1]- A[1]) * (B[0] - A[0]) > (B[1] - A[1]) * (C[0] - A[0])

def segment_intersect(self,A, B, C, D):
    return counterclockwise(A,C,D) != counterclockwise(B,C,D) and counterclockwise(A,B,C) != counterclockwise(A,B,D)

def ray_cast(self, point, polyPoints, farAwayPoint):
    intersections = 0
    for i in range(len(polyPoints)-1):
        if segment_intersect(point, farAwayPoint,  polyPoints[i], polyPoints[i+1]) :
            intersections += 1
    if intersections % 2 == 0:
        return 'outside'
    else:
        return 'inside'

Notice I used point and farAwayPoint as my arbitrarily large segment. Obviously you could just choose any arbitrarily large point like (point.x + 10000, point.y + 10000) without making an extra function argument.

I hope this helps.

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.