New math util funcitons:
- equals_v2v2 - project_v2_v2v2 - isect_seg_seg_v2_point which would be necessery for my further multires interpolation commit M_Geometry_LineIntersect2D now uses isect_seg_seg_v2_point(). Behaviour of this function was changed a bit -- it haven't returned intersection point in several cases when two segments are making angle.
This commit is contained in:
@@ -587,7 +587,7 @@ static PyObject *M_Geometry_PolyFill(PyObject *UNUSED(self), PyObject * polyLine
|
||||
static PyObject *M_Geometry_LineIntersect2D(PyObject *UNUSED(self), PyObject* args)
|
||||
{
|
||||
VectorObject *line_a1, *line_a2, *line_b1, *line_b2;
|
||||
float a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y, xi, yi, a1,a2,b1,b2, newvec[2];
|
||||
float vi[2];
|
||||
if( !PyArg_ParseTuple ( args, "O!O!O!O!",
|
||||
&vector_Type, &line_a1,
|
||||
&vector_Type, &line_a2,
|
||||
@@ -600,86 +600,12 @@ static PyObject *M_Geometry_LineIntersect2D(PyObject *UNUSED(self), PyObject* ar
|
||||
|
||||
if(!BaseMath_ReadCallback(line_a1) || !BaseMath_ReadCallback(line_a2) || !BaseMath_ReadCallback(line_b1) || !BaseMath_ReadCallback(line_b2))
|
||||
return NULL;
|
||||
|
||||
a1x= line_a1->vec[0];
|
||||
a1y= line_a1->vec[1];
|
||||
a2x= line_a2->vec[0];
|
||||
a2y= line_a2->vec[1];
|
||||
|
||||
b1x= line_b1->vec[0];
|
||||
b1y= line_b1->vec[1];
|
||||
b2x= line_b2->vec[0];
|
||||
b2y= line_b2->vec[1];
|
||||
|
||||
if((MIN2(a1x, a2x) > MAX2(b1x, b2x)) ||
|
||||
(MAX2(a1x, a2x) < MIN2(b1x, b2x)) ||
|
||||
(MIN2(a1y, a2y) > MAX2(b1y, b2y)) ||
|
||||
(MAX2(a1y, a2y) < MIN2(b1y, b2y)) ) {
|
||||
if(isect_seg_seg_v2_point(line_a1->vec, line_a2->vec, line_b1->vec, line_b2->vec, vi) == 1) {
|
||||
return newVectorObject(vi, 2, Py_NEW, NULL);
|
||||
} else {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
/* Make sure the hoz/vert line comes first. */
|
||||
if (fabs(b1x - b2x) < eps || fabs(b1y - b2y) < eps) {
|
||||
SWAP_FLOAT(a1x, b1x, xi); /*abuse xi*/
|
||||
SWAP_FLOAT(a1y, b1y, xi);
|
||||
SWAP_FLOAT(a2x, b2x, xi);
|
||||
SWAP_FLOAT(a2y, b2y, xi);
|
||||
}
|
||||
|
||||
if (fabs(a1x-a2x) < eps) { /* verticle line */
|
||||
if (fabs(b1x-b2x) < eps){ /*verticle second line */
|
||||
Py_RETURN_NONE; /* 2 verticle lines dont intersect. */
|
||||
}
|
||||
else if (fabs(b1y-b2y) < eps) {
|
||||
/*X of vert, Y of hoz. no calculation needed */
|
||||
newvec[0]= a1x;
|
||||
newvec[1]= b1y;
|
||||
return newVectorObject(newvec, 2, Py_NEW, NULL);
|
||||
}
|
||||
|
||||
yi = (float)(((b1y / fabs(b1x - b2x)) * fabs(b2x - a1x)) + ((b2y / fabs(b1x - b2x)) * fabs(b1x - a1x)));
|
||||
|
||||
if (yi > MAX2(a1y, a2y)) {/* New point above seg1's vert line */
|
||||
Py_RETURN_NONE;
|
||||
} else if (yi < MIN2(a1y, a2y)) { /* New point below seg1's vert line */
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
newvec[0]= a1x;
|
||||
newvec[1]= yi;
|
||||
return newVectorObject(newvec, 2, Py_NEW, NULL);
|
||||
} else if (fabs(a2y-a1y) < eps) { /* hoz line1 */
|
||||
if (fabs(b2y-b1y) < eps) { /*hoz line2*/
|
||||
Py_RETURN_NONE; /*2 hoz lines dont intersect*/
|
||||
}
|
||||
|
||||
/* Can skip vert line check for seg 2 since its covered above. */
|
||||
xi = (float)(((b1x / fabs(b1y - b2y)) * fabs(b2y - a1y)) + ((b2x / fabs(b1y - b2y)) * fabs(b1y - a1y)));
|
||||
if (xi > MAX2(a1x, a2x)) { /* New point right of hoz line1's */
|
||||
Py_RETURN_NONE;
|
||||
} else if (xi < MIN2(a1x, a2x)) { /*New point left of seg1's hoz line */
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
newvec[0]= xi;
|
||||
newvec[1]= a1y;
|
||||
return newVectorObject(newvec, 2, Py_NEW, NULL);
|
||||
}
|
||||
|
||||
b1 = (a2y-a1y)/(a2x-a1x);
|
||||
b2 = (b2y-b1y)/(b2x-b1x);
|
||||
a1 = a1y-b1*a1x;
|
||||
a2 = b1y-b2*b1x;
|
||||
|
||||
if (b1 - b2 == 0.0) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
xi = - (a1-a2)/(b1-b2);
|
||||
yi = a1+b1*xi;
|
||||
if ((a1x-xi)*(xi-a2x) >= 0 && (b1x-xi)*(xi-b2x) >= 0 && (a1y-yi)*(yi-a2y) >= 0 && (b1y-yi)*(yi-b2y)>=0) {
|
||||
newvec[0]= xi;
|
||||
newvec[1]= yi;
|
||||
return newVectorObject(newvec, 2, Py_NEW, NULL);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *M_Geometry_ClosestPointOnLine(PyObject *UNUSED(self), PyObject* args)
|
||||
|
Reference in New Issue
Block a user