forked from bartvdbraak/blender
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.
This commit is contained in:
parent
f001e58768
commit
25fc47aaf2
@ -2553,28 +2553,46 @@ short IsectLLPt2Df(float x0,float y0,float x1,float y1,
|
|||||||
} // end Intersect_Lines
|
} // 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 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 */
|
/* point in tri */
|
||||||
int IsectPT2Df(float pt[2], float v1[2], float v2[2], float v3[2])
|
int IsectPT2Df(float pt[2], float v1[2], float v2[2], float v3[2])
|
||||||
{
|
{
|
||||||
if ((SIDE_OF_LINE(v1,v2,pt)>=-ISECT_EPSILON) &&
|
if (SIDE_OF_LINE(v1,v2,pt)>=0.0) {
|
||||||
(SIDE_OF_LINE(v2,v3,pt)>=-ISECT_EPSILON) &&
|
if (SIDE_OF_LINE(v2,v3,pt)>=0.0) {
|
||||||
(SIDE_OF_LINE(v3,v1,pt)>=-ISECT_EPSILON))
|
if (SIDE_OF_LINE(v3,v1,pt)>=0.0) {
|
||||||
return 1;
|
return 1;
|
||||||
else {
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} 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 */
|
/* point in quad - only convex quads */
|
||||||
int IsectPQ2Df(float pt[2], float v1[2], float v2[2], float v3[2], float v4[2])
|
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) &&
|
if (SIDE_OF_LINE(v1,v2,pt)>=0.0) {
|
||||||
(SIDE_OF_LINE(v2,v3,pt)>=-ISECT_EPSILON) &&
|
if (SIDE_OF_LINE(v2,v3,pt)>=0.0) {
|
||||||
(SIDE_OF_LINE(v3,v4,pt)>=-ISECT_EPSILON) &&
|
if (SIDE_OF_LINE(v3,v4,pt)>=0.0) {
|
||||||
(SIDE_OF_LINE(v4,v1,pt)>=-ISECT_EPSILON))
|
if (SIDE_OF_LINE(v4,v1,pt)>=0.0) {
|
||||||
return 1;
|
return 1;
|
||||||
else
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,6 +54,7 @@ static PyObject *M_Geometry_PolyFill( PyObject * self, PyObject * polyLineSeq );
|
|||||||
static PyObject *M_Geometry_LineIntersect2D( PyObject * self, PyObject * args );
|
static PyObject *M_Geometry_LineIntersect2D( PyObject * self, PyObject * args );
|
||||||
static PyObject *M_Geometry_ClosestPointOnLine( 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_PointInTriangle2D( PyObject * self, PyObject * args );
|
||||||
|
static PyObject *M_Geometry_PointInQuad2D( PyObject * self, PyObject * args );
|
||||||
static PyObject *M_Geometry_BoxPack2D( PyObject * self, PyObject * args );
|
static PyObject *M_Geometry_BoxPack2D( PyObject * self, PyObject * args );
|
||||||
|
|
||||||
|
|
||||||
@ -62,7 +63,8 @@ static char M_Geometry_doc[] = "The Blender Geometry module\n\n";
|
|||||||
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_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_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_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[] = "";
|
static char M_Geometry_BoxPack2D_doc[] = "";
|
||||||
/*-----------------------METHOD DEFINITIONS ----------------------*/
|
/*-----------------------METHOD DEFINITIONS ----------------------*/
|
||||||
struct PyMethodDef M_Geometry_methods[] = {
|
struct PyMethodDef M_Geometry_methods[] = {
|
||||||
@ -70,6 +72,7 @@ struct PyMethodDef M_Geometry_methods[] = {
|
|||||||
{"LineIntersect2D", ( PyCFunction ) M_Geometry_LineIntersect2D, METH_VARARGS, M_Geometry_LineIntersect2D_doc},
|
{"LineIntersect2D", ( PyCFunction ) M_Geometry_LineIntersect2D, METH_VARARGS, M_Geometry_LineIntersect2D_doc},
|
||||||
{"ClosestPointOnLine", ( PyCFunction ) M_Geometry_ClosestPointOnLine, METH_VARARGS, M_Geometry_ClosestPointOnLine_doc},
|
{"ClosestPointOnLine", ( PyCFunction ) M_Geometry_ClosestPointOnLine, METH_VARARGS, M_Geometry_ClosestPointOnLine_doc},
|
||||||
{"PointInTriangle2D", ( PyCFunction ) M_Geometry_PointInTriangle2D, METH_VARARGS, M_Geometry_PointInTriangle2D_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},
|
{"BoxPack2D", ( PyCFunction ) M_Geometry_BoxPack2D, METH_O, M_Geometry_BoxPack2D_doc},
|
||||||
{NULL, NULL, 0, NULL}
|
{NULL, NULL, 0, NULL}
|
||||||
};
|
};
|
||||||
@ -313,9 +316,6 @@ static PyObject *M_Geometry_ClosestPointOnLine( PyObject * self, PyObject * args
|
|||||||
return ret;
|
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 )
|
static PyObject *M_Geometry_PointInTriangle2D( PyObject * self, PyObject * args )
|
||||||
{
|
{
|
||||||
VectorObject *pt_vec, *tri_p1, *tri_p2, *tri_p3;
|
VectorObject *pt_vec, *tri_p1, *tri_p2, *tri_p3;
|
||||||
@ -329,10 +329,24 @@ static PyObject *M_Geometry_PointInTriangle2D( PyObject * self, PyObject * args
|
|||||||
return ( EXPP_ReturnPyObjError
|
return ( EXPP_ReturnPyObjError
|
||||||
( PyExc_TypeError, "expected 4 vector types\n" ) );
|
( PyExc_TypeError, "expected 4 vector types\n" ) );
|
||||||
|
|
||||||
if POINT_IN_TRI(pt_vec->vec, tri_p1->vec, tri_p2->vec, tri_p3->vec)
|
return PyInt_FromLong(IsectPT2Df(pt_vec->vec, tri_p1->vec, tri_p2->vec, tri_p3->vec));
|
||||||
Py_RETURN_TRUE;
|
}
|
||||||
else
|
|
||||||
Py_RETURN_FALSE;
|
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 boxPack_FromPyObject(PyObject * value, boxPack **boxarray )
|
||||||
|
@ -59,8 +59,16 @@ def PointInTriangle2D(pt, tri_pt1, tri_pt2, tri_pt3):
|
|||||||
"""
|
"""
|
||||||
Takes 4 vectors (one for the test point and 3 for the triangle)
|
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.
|
This is a 2d function so only X and Y are used, Z and W will be ignored.
|
||||||
@rtype: bool
|
@rtype: int
|
||||||
@return: True or False depending on the points intersection.
|
@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):
|
def BoxPack2D(boxlist):
|
||||||
|
Loading…
Reference in New Issue
Block a user