Hi all,
This is a polygon class for checking whether a point is inside a polygon.
Alberto
# Panda 3D
#import direct.directbase.DirectStart
from pandac.PandaModules import *
from logger import defaultLogger
class Polygon:
"""
This class define a polygon in 2D (x,y)
dataX - it contains the list of points (X axis)
dataY - it contains the list of points (Y axis)
Points are defined as float values
"""
def __init__(self):
self.dataX = []
self.dataY = []
def setData(self, pointsX, pointsY):
if pointsX == None or pointsY == None:
defaultLogger.log("Polygon: Points are null")
return False
self.dataX = pointsX
self.dataY = pointsY
return True
"""
It returns True, if the point is inside the polygon or False if not.
px, py must be floats
"""
def isInto(self, position):
if not isinstance(position, Point3):
raise "Position parameter is not of Point3 type"
px = position.getX()
py = position.getY()
# First, check whether the point is a vertex
for i in range(len(self.dataX)):
if px == self.dataX[i] and py == self.dataY[i]:
return True
# Check whether the point is inside the polygon
"""
int pnpoly(int npol, float *xp, float *yp, float x, float y)
{
int i, j, c = 0;
for (i = 0, j = npol-1; i < npol; j = i++) {
if ((((yp[i] <= y) && (y < yp[j])) ||
((yp[j] <= y) && (y < yp[i]))) &&
(x < (xp[j] - xp[i]) * (y - yp[i]) / (yp[j] - yp[i]) + xp[i]))
c = !c;
}
return c;
}
"""
i = 0
j = 0
c = False
npol = len(self.dataX)
j = npol - 1
for i in range(0, npol):
if (((self.dataY[i] <= py and py < self.dataY[j]) or \
(self.dataY[j] <= py and py < self.dataY[i])) and \
(px < (self.dataX[j] - self.dataX[i]) * (py - self.dataY[i]) \
/ (self.dataY[j] - self.dataY[i]) + self.dataX[i])):
c = not c
#print c
j = i
return c
def __str__(self):
output = "Polygon: \n"
for i in range(len(self.dataX)):
output += str(self.dataX[i]) + ", " + str(self.dataY[i]) + "\n"
output += "\n"
return output
# Tests
if __name__ == "__main__":
p1 = Polygon()
data_x = [
-12.343873,
-11.730609,
-11.515260,
-11.730609,
-12.343873,
-13.261690,
-14.344327,
-15.426966,
-16.344782,
-16.958050,
-17.173397,
-16.958050,
-16.344782,
-15.426966,
-14.344327,
-13.261687,
]
data_y = [
-8.832416,
-9.750232,
-10.832870,
-11.915508,
-12.833324,
-13.446589,
-13.661940,
-13.446589,
-12.833325,
-11.915508,
-10.832870,
-9.750231,
-8.832415,
-8.219150,
-8.003799,
-8.219151,
]
p1.setData(data_x, data_y)
print p1
# A vertex. True
print p1.isInto(-11.730609, -9.750232)
# Inside. True
r = p1.isInto(-13.0, -10.0)
if not r:
print "Error: in -13,-10"
else:
print "-13,-10 is inside"
# Outside. False
r = p1.isInto(1.0, 1.0)
if r:
print "Error in 1, 1"
else:
print "1,1 is not inside"