Revision: 16805 http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=16805 Author: campbellbarton Date: 2008-09-29 04:16:18 +0200 (Mon, 29 Sep 2008)
Log Message: ----------- tests for 2d triangle and quad intersection would only work if the points were ordered clockwise. now return 1 for clockwise, -1 for counter-clockwise and 0 for no intersection. Modified Paths: -------------- trunk/blender/source/blender/blenlib/intern/arithb.c trunk/blender/source/blender/python/api2_2x/Geometry.c trunk/blender/source/blender/python/api2_2x/doc/Geometry.py Modified: trunk/blender/source/blender/blenlib/intern/arithb.c =================================================================== --- trunk/blender/source/blender/blenlib/intern/arithb.c 2008-09-29 01:49:56 UTC (rev 16804) +++ trunk/blender/source/blender/blenlib/intern/arithb.c 2008-09-29 02:16:18 UTC (rev 16805) @@ -2553,29 +2553,47 @@ } // end Intersect_Lines #define SIDE_OF_LINE(pa,pb,pp) ((pa[0]-pp[0])*(pb[1]-pp[1]))-((pb[0]-pp[0])*(pa[1]-pp[1])) -#define ISECT_EPSILON 1e-6 - /* point in tri */ int IsectPT2Df(float pt[2], float v1[2], float v2[2], float v3[2]) { - if ((SIDE_OF_LINE(v1,v2,pt)>=-ISECT_EPSILON) && - (SIDE_OF_LINE(v2,v3,pt)>=-ISECT_EPSILON) && - (SIDE_OF_LINE(v3,v1,pt)>=-ISECT_EPSILON)) - return 1; - else { - return 0; + if (SIDE_OF_LINE(v1,v2,pt)>=0.0) { + if (SIDE_OF_LINE(v2,v3,pt)>=0.0) { + if (SIDE_OF_LINE(v3,v1,pt)>=0.0) { + return 1; + } + } + } else { + if (! (SIDE_OF_LINE(v2,v3,pt)>=0.0) ) { + if (! (SIDE_OF_LINE(v3,v1,pt)>=0.0)) { + return -1; + } + } } + + return 0; } /* point in quad - only convex quads */ int IsectPQ2Df(float pt[2], float v1[2], float v2[2], float v3[2], float v4[2]) { - if ((SIDE_OF_LINE(v1,v2,pt)>=-ISECT_EPSILON) && - (SIDE_OF_LINE(v2,v3,pt)>=-ISECT_EPSILON) && - (SIDE_OF_LINE(v3,v4,pt)>=-ISECT_EPSILON) && - (SIDE_OF_LINE(v4,v1,pt)>=-ISECT_EPSILON)) - return 1; - else - return 0; + if (SIDE_OF_LINE(v1,v2,pt)>=0.0) { + if (SIDE_OF_LINE(v2,v3,pt)>=0.0) { + if (SIDE_OF_LINE(v3,v4,pt)>=0.0) { + if (SIDE_OF_LINE(v4,v1,pt)>=0.0) { + return 1; + } + } + } + } else { + if (! (SIDE_OF_LINE(v2,v3,pt)>=0.0) ) { + if (! (SIDE_OF_LINE(v3,v4,pt)>=0.0)) { + if (! (SIDE_OF_LINE(v4,v1,pt)>=0.0)) { + return -1; + } + } + } + } + + return 0; } Modified: trunk/blender/source/blender/python/api2_2x/Geometry.c =================================================================== --- trunk/blender/source/blender/python/api2_2x/Geometry.c 2008-09-29 01:49:56 UTC (rev 16804) +++ trunk/blender/source/blender/python/api2_2x/Geometry.c 2008-09-29 02:16:18 UTC (rev 16805) @@ -54,6 +54,7 @@ static PyObject *M_Geometry_LineIntersect2D( PyObject * self, PyObject * args ); static PyObject *M_Geometry_ClosestPointOnLine( PyObject * self, PyObject * args ); static PyObject *M_Geometry_PointInTriangle2D( PyObject * self, PyObject * args ); +static PyObject *M_Geometry_PointInQuad2D( PyObject * self, PyObject * args ); static PyObject *M_Geometry_BoxPack2D( PyObject * self, PyObject * args ); @@ -62,7 +63,8 @@ static char M_Geometry_PolyFill_doc[] = "(veclist_list) - takes a list of polylines (each point a vector) and returns the point indicies for a polyline filled with triangles"; static char M_Geometry_LineIntersect2D_doc[] = "(lineA_p1, lineA_p2, lineB_p1, lineB_p2) - takes 2 lines (as 4 vectors) and returns a vector for their point of intersection or None"; static char M_Geometry_ClosestPointOnLine_doc[] = "(pt, line_p1, line_p2) - takes a point and a line and returns a (Vector, Bool) for the point on the line, and the bool so you can know if the point was between the 2 points"; -static char M_Geometry_PointInTriangle2D_doc[] = "(pt, tri_p1, tri_p2, tri_p3) - takes 4 vectors, one is the point and the next 3 define the triabgle, only the x and y are used from the vectors"; +static char M_Geometry_PointInTriangle2D_doc[] = "(pt, tri_p1, tri_p2, tri_p3) - takes 4 vectors, one is the point and the next 3 define the triangle, only the x and y are used from the vectors"; +static char M_Geometry_PointInQuad2D_doc[] = "(pt, quad_p1, quad_p2, quad_p3, quad_p4) - takes 5 vectors, one is the point and the next 4 define the quad, only the x and y are used from the vectors"; static char M_Geometry_BoxPack2D_doc[] = ""; /*-----------------------METHOD DEFINITIONS ----------------------*/ struct PyMethodDef M_Geometry_methods[] = { @@ -70,6 +72,7 @@ {"LineIntersect2D", ( PyCFunction ) M_Geometry_LineIntersect2D, METH_VARARGS, M_Geometry_LineIntersect2D_doc}, {"ClosestPointOnLine", ( PyCFunction ) M_Geometry_ClosestPointOnLine, METH_VARARGS, M_Geometry_ClosestPointOnLine_doc}, {"PointInTriangle2D", ( PyCFunction ) M_Geometry_PointInTriangle2D, METH_VARARGS, M_Geometry_PointInTriangle2D_doc}, + {"PointInQuad2D", ( PyCFunction ) M_Geometry_PointInQuad2D, METH_VARARGS, M_Geometry_PointInQuad2D_doc}, {"BoxPack2D", ( PyCFunction ) M_Geometry_BoxPack2D, METH_O, M_Geometry_BoxPack2D_doc}, {NULL, NULL, 0, NULL} }; @@ -313,9 +316,6 @@ return ret; } -#define SIDE_OF_LINE(pa,pb,pp) ((pa[0]-pp[0])*(pb[1]-pp[1]))-((pb[0]-pp[0])*(pa[1]-pp[1])) -#define POINT_IN_TRI(p0,p1,p2,p3) ((SIDE_OF_LINE(p1,p2,p0)>=0) && (SIDE_OF_LINE(p2,p3,p0)>=0) && (SIDE_OF_LINE(p3,p1,p0)>=0)) - static PyObject *M_Geometry_PointInTriangle2D( PyObject * self, PyObject * args ) { VectorObject *pt_vec, *tri_p1, *tri_p2, *tri_p3; @@ -329,12 +329,26 @@ return ( EXPP_ReturnPyObjError ( PyExc_TypeError, "expected 4 vector types\n" ) ); - if POINT_IN_TRI(pt_vec->vec, tri_p1->vec, tri_p2->vec, tri_p3->vec) - Py_RETURN_TRUE; - else - Py_RETURN_FALSE; + return PyInt_FromLong(IsectPT2Df(pt_vec->vec, tri_p1->vec, tri_p2->vec, tri_p3->vec)); } +static PyObject *M_Geometry_PointInQuad2D( PyObject * self, PyObject * args ) +{ + VectorObject *pt_vec, *quad_p1, *quad_p2, *quad_p3, *quad_p4; + + if( !PyArg_ParseTuple ( args, "O!O!O!O!O!", + &vector_Type, &pt_vec, + &vector_Type, &quad_p1, + &vector_Type, &quad_p2, + &vector_Type, &quad_p3, + &vector_Type, &quad_p4) + ) + return ( EXPP_ReturnPyObjError + ( PyExc_TypeError, "expected 5 vector types\n" ) ); + + return PyInt_FromLong(IsectPQ2Df(pt_vec->vec, quad_p1->vec, quad_p2->vec, quad_p3->vec, quad_p4->vec)); +} + int boxPack_FromPyObject(PyObject * value, boxPack **boxarray ) { int len, i; Modified: trunk/blender/source/blender/python/api2_2x/doc/Geometry.py =================================================================== --- trunk/blender/source/blender/python/api2_2x/doc/Geometry.py 2008-09-29 01:49:56 UTC (rev 16804) +++ trunk/blender/source/blender/python/api2_2x/doc/Geometry.py 2008-09-29 02:16:18 UTC (rev 16805) @@ -59,10 +59,18 @@ """ Takes 4 vectors (one for the test point and 3 for the triangle) This is a 2d function so only X and Y are used, Z and W will be ignored. - @rtype: bool - @return: True or False depending on the points intersection. + @rtype: int + @return: 1 for a clockwise intersection, -1 for counter clockwise intersection, 0 when there is no intersection. """ +def PointInQuad2D(pt, quad_pt1, quad_pt2, quad_pt3): + """ + Takes 5 vectors (one for the test point and 5 for the quad) + This is a 2d function so only X and Y are used, Z and W will be ignored. + @rtype: int + @return: 1 for a clockwise intersection, -1 for counter clockwise intersection, 0 when there is no intersection. + """ + def BoxPack2D(boxlist): """ Takes a list of 2D boxes and packs them into a square. _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org http://lists.blender.org/mailman/listinfo/bf-blender-cvs