@@ -45,22 +45,83 @@ pnpoly(PyObject *self, PyObject *args)
4545 if (! PyArg_ParseTuple (args , "ddO" , & x , & y , & vertsarg ))
4646 return NULL ;
4747
48- if (!PyArray_Check (vertsarg ))
48+ verts = (PyArrayObject * ) PyArray_FromObject (vertsarg ,PyArray_DOUBLE , 2 , 2 );
49+
50+ if (verts == NULL )
4951 {
50- PyErr_SetString (PyExc_TypeError ,
51- "Arguments must be float, float, Nx2 array" );
52+ PyErr_SetString (PyExc_ValueError ,
53+ "Arguments verts must be a Nx2 array." );
54+ Py_XDECREF (verts );
5255 return NULL ;
56+
5357 }
5458
55- verts = ( PyArrayObject * ) PyArray_ContiguousFromObject ( vertsarg , PyArray_DOUBLE , 2 , 2 ) ;
56-
57- if (verts == NULL )
59+ npol = verts -> dimensions [ 0 ] ;
60+ //printf ("found %d verts\n", npol);
61+ if (verts -> dimensions [ 1 ] != 2 )
5862 {
5963 PyErr_SetString (PyExc_ValueError ,
6064 "Arguments verts must be a Nx2 array." );
6165 Py_XDECREF (verts );
6266 return NULL ;
67+
68+ }
69+
70+
71+ xv = (double * ) PyMem_Malloc (sizeof (double ) * npol );
72+ if (xv == NULL )
73+ {
74+ Py_XDECREF (verts );
75+ return NULL ;
76+ }
77+
78+ yv = (double * ) PyMem_Malloc (sizeof (double ) * npol );
79+ if (yv == NULL )
80+ {
81+ Py_XDECREF (verts );
82+ PyMem_Free (xv );
83+ return NULL ;
84+ }
85+
86+ for (i = 0 ; i < npol ; ++ i ) {
87+ xv [i ] = * (double * )(verts -> data + i * verts -> strides [0 ]);
88+ yv [i ] = * (double * )(verts -> data + i * verts -> strides [0 ] + verts -> strides [1 ]);
89+ //printf("adding vert: %1.3f, %1.3f\n", xv[i], yv[i]);
90+ }
91+
92+ b = pnpoly_api (npol , xv , yv , x , y );
93+ //printf("in poly %d\n", b);
94+
95+ Py_XDECREF (verts );
96+ PyMem_Free (xv );
97+ PyMem_Free (yv );
98+ return Py_BuildValue ("i" , b );
99+
100+ }
63101
102+ static PyObject *
103+ points_inside_poly (PyObject * self , PyObject * args )
104+ {
105+ int npol , npoints , i ;
106+ double * xv , * yv , x , y ;
107+ int b ;
108+ PyObject * xypointsarg , * vertsarg ;
109+ PyArrayObject * xypoints , * verts ;
110+ PyArrayObject * mask ;
111+ int dimensions [1 ];
112+
113+ if (! PyArg_ParseTuple (args , "OO" , & xypointsarg , & vertsarg ))
114+ return NULL ;
115+
116+ verts = (PyArrayObject * ) PyArray_FromObject (vertsarg ,PyArray_DOUBLE , 2 , 2 );
117+
118+ if (verts == NULL )
119+ {
120+ PyErr_SetString (PyExc_ValueError ,
121+ "Argument verts must be a Nx2 array." );
122+ Py_XDECREF (verts );
123+ return NULL ;
124+
64125 }
65126
66127 npol = verts -> dimensions [0 ];
@@ -71,45 +132,97 @@ pnpoly(PyObject *self, PyObject *args)
71132 "Arguments verts must be a Nx2 array." );
72133 Py_XDECREF (verts );
73134 return NULL ;
74-
135+
75136 }
76137
77138
78- xv = (double * ) PyMem_Malloc (sizeof (double ) * npol );
79- if (xv == NULL )
139+ xv = (double * ) PyMem_Malloc (sizeof (double ) * npol );
140+ if (xv == NULL )
80141 {
81142 Py_XDECREF (verts );
82- return NULL ;
143+ return NULL ;
83144 }
145+
146+ yv = (double * ) PyMem_Malloc (sizeof (double ) * npol );
147+ if (yv == NULL )
148+ {
149+ Py_XDECREF (verts );
150+ PyMem_Free (xv );
151+ return NULL ;
152+ }
153+
154+ // fill the verts arrays
155+ for (i = 0 ; i < npol ; ++ i ) {
156+ xv [i ] = * (double * )(verts -> data + i * verts -> strides [0 ]);
157+ yv [i ] = * (double * )(verts -> data + i * verts -> strides [0 ] + verts -> strides [1 ]);
158+ //printf("adding vert: %1.3f, %1.3f\n", xv[i], yv[i]);
159+ }
84160
85- yv = (double * ) PyMem_Malloc (sizeof (double ) * npol );
86- if (yv == NULL )
161+ xypoints = (PyArrayObject * ) PyArray_FromObject (xypointsarg ,PyArray_DOUBLE , 2 , 2 );
162+
163+ if (xypoints == NULL )
87164 {
165+ PyErr_SetString (PyExc_ValueError ,
166+ "Arguments xypoints must an Nx2 array." );
88167 Py_XDECREF (verts );
168+ Py_XDECREF (xypoints );
89169 PyMem_Free (xv );
170+ PyMem_Free (yv );
90171 return NULL ;
172+
91173 }
92174
93- for (i = 0 ; i < npol ; ++ i ) {
94- xv [i ] = * (double * )(verts -> data + i * verts -> strides [0 ]);
95- yv [i ] = * (double * )(verts -> data + i * verts -> strides [0 ] + verts -> strides [1 ]);
96- //printf("adding vert: %1.3f, %1.3f\n", xv[i], yv[i]);
175+ if (xypoints -> dimensions [1 ]!= 2 )
176+ {
177+ PyErr_SetString (PyExc_ValueError ,
178+ "Arguments xypoints must be a Nx2 array." );
179+
180+ Py_XDECREF (verts );
181+ Py_XDECREF (xypoints );
182+ PyMem_Free (xv );
183+ PyMem_Free (yv );
184+ return NULL ;
97185 }
186+
187+ npoints = xypoints -> dimensions [0 ];
188+ dimensions [0 ] = npoints ;
189+
190+ mask = (PyArrayObject * )PyArray_FromDims (1 ,dimensions ,PyArray_INT );
191+ if (mask == NULL ) {
192+ Py_XDECREF (verts );
193+ Py_XDECREF (xypoints );
194+ PyMem_Free (xv );
195+ PyMem_Free (yv );
196+ return NULL ; }
98197
198+ for (i = 0 ; i < npoints ; ++ i ) {
199+ x = * (double * )(xypoints -> data + i * xypoints -> strides [0 ]);
200+ y = * (double * )(xypoints -> data + i * xypoints -> strides [0 ] + xypoints -> strides [1 ]);
99201 b = pnpoly_api (npol , xv , yv , x , y );
100- //printf("in poly %d\n", b);
202+ //printf("checking %d, %d, %1.3f, %1.3f, %d\n", npol, npoints, x, y, b);
203+ * (int * )(mask -> data + i * mask -> strides [0 ]) = b ;
101204
102- Py_XDECREF (verts );
103- PyMem_Free (xv );
104- PyMem_Free (yv );
105- return Py_BuildValue ("i" , b );
106-
205+ }
206+
207+
208+ Py_XDECREF (verts );
209+ Py_XDECREF (xypoints );
210+
211+ PyMem_Free (xv );
212+ PyMem_Free (yv );
213+ PyObject * ret = Py_BuildValue ("O" , mask );
214+ Py_XDECREF (mask );
215+ return ret ;
216+
217+
107218}
108219
109220
110221
222+
111223static PyMethodDef module_methods [] = {
112- {"pnpoly" , pnpoly , METH_VARARGS },
224+ {"pnpoly" , pnpoly , METH_VARARGS , "inside = pnpoly(x, y, xyverts)\nreturn True if x,y is inside the polygon defined by the sequence of x,y vertices in xyverts" },
225+ {"points_inside_poly" , points_inside_poly , METH_VARARGS , "mask = points_inside_poly(xypoints, xyverts)\nreturn a mask of length xypoints indicating whether each x,y point is inside the polygon defined by the sequence of x,y vertices in xyverts" },
113226 {NULL } /* Sentinel */
114227};
115228
0 commit comments