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

Reply via email to