[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] Re: Hexagonal collision detection?



>> On Sep 15, 7:35 am, Ian Mallett <geometr...@xxxxxxxxx> wrote:
>>>  As used in my projecthttp://www.pygame.org/project/649/.
>>>     def pointtest(self,point):
>>>         #drawpoints is a list containing points defining your polygon
>>>         #point is the mouse position
>>>         #if it doesn't work, list them in opposite order.
>>>         #works for arbitrary convex geometry
>>>         x = point[0]
>>>         y = point[1]
>>>         Lines = []
>>>         index = 0
>>>         for index in xrange(len(drawpoints)):
>>>             p0 = drawpoints[index]
>>>             try: p1 = drawpoints[index+1]
>>>             except: p1 = drawpoints[0]
>>>             Lines.append([p0,p1])
>>>         for l in Lines:
>>>             p0 = l[0]
>>>             p1 = l[1]
>>>             x0 = p0[0]; y0 = p0[1]
>>>             x1 = p1[0]; y1 = p1[1]
>>>             test = (y - y0)*(x1 - x0) - (x - x0)*(y1 - y0)
>>>             if test < 0: return False
>>>         return True
>>> Ian
> 
> I usually use a list comprehension to generate the "Lines" variable:
>     Lines = [[drawpoints[idx], drawpoints[idx + 1]] for idx in
> xrange(-1, len(drawpoints) - 1)]
> I just love the negative indexing capabilities of python!



Actually, the double loop is pointless, since the list is just unpacked
again the second time round.  The above could be rewritten

def pointtest(point, polygon):
    x, y = point
    for p0, p1 in zip(polygon, polygon[1:] + polygon[:1]):
        x0, y0 = p0
        x1, y1 = p1
        if (y - y0) * (x1 - x0) - (x - x0) * (y1 - y0) < 0:
            return False
    return True

though using indexes might be quicker than constructing the zip, in
which case it would be better to use % rather than Ian's try-except.
But if you take the odd case out of the loop, as well as speeding it up,
you can also get rid of the "if it doesn't work, list them in opposite
order" injunction.  Like this:

def pointtest2(point, polygon):
    x, y = point

    x0, y0 = polygon[-1]
    x1, y1 = polygon[0]
    side = cmp((y - y0) * (x1 - x0), (x - x0) * (y1 - y0))

    for i in range(len(polygon) - 1):
        x0, y0 = polygon[i]
        x1, y1 = polygon[i + 1]
        if cmp((y - y0) * (x1 - x0), (x - x0) * (y1 - y0)) != side:
            return False
    return True



Douglas