Example #1
0
	IntersectResult PolygonSegmentIntersect(Segment* edge, TYPE* polygon)
	{
		{
			Rectangle* bb1 = polygon->GetBoundingBox();
			Rectangle* bb2 = edge->GetBoundingBox();
			if (!bb1->Collide(bb2, true))
				return IR_SEPERATE;
		}
		Rectangle* bb1 = edge->GetBoundingBox();
		Node* node_c = edge->A();
		Node* node_d = edge->B();
		Segment* edge_cd = new Segment(node_c, node_d);
		Nodes::iterator it = polygon->begin();
		IntersectResult ret = IR_SEPERATE;
		int index = 0;
		for (; it != polygon->end();it++,index++)
		{
			if(typeid(polygon) == typeid(OpenPolygon*))
				if(polygon->IsPortal(index)) continue;
			Node* node_a = *it;
			Node* node_b = *(polygon->GetNext(it));
			Segment* edge_ab = new Segment(node_a, node_b);
			edge_ab->Calculate();
			Rectangle* bb2 = edge_ab->GetBoundingBox();
			if (bb1->Collide(bb2, true))
			{
				IntersectResult result = SegmentSegmentIntersect(edge_ab, edge_cd);
				if (result == IR_INTERSECT) return IR_INTERSECT;
				if (result == IR_TOUCH)
				{
					if (node_c->Equal(node_a) || node_d->Equal(node_a))
					{
						ret = IR_TOUCH;
					}
					// CAD straight
					else if (GetConvex(node_c, node_a, node_d) == CR_STRAIGHT)
					{
						Node* node_z = *(polygon->GetPrevious(it));
						// Z and B in 2 different plane seperated by CD
						if (GetConvex(node_c, node_z, node_d) != GetConvex(node_c, node_b, node_d))
						{
							return IR_INTERSECT;
						}
						else
						{
							ret = IR_TOUCH;
						}
					}
					else
					{
						ret = IR_TOUCH;
					}
				}
			}
		}
		return ret;
	}
Example #2
0
	/*------------------------------------------------
	NAME: SegmentSegmentIntersect
	DATE: 11st JAN 2014
	TASK: return ralation of 2 segment, seperate, touch, or intersect
	-------------------------------------------------*/
	IntersectResult SegmentSegmentIntersect(Segment* s1, Segment* s2)
	{
		Rectangle* bb1 = s1->GetBoundingBox();
		Rectangle* bb2 = s2->GetBoundingBox();
		if (!bb1->Collide(bb2, true)) return IR_SEPERATE;
		Node *a = s1->A();
		Node *b = s1->B();
		Node *c = s2->A();
		Node *d = s2->B();
		return SegmentSegmentIntersect(a->X(), a->Y(), b->X(), b->Y(),
			c->X(), c->Y(), d->X(), d->Y());
	}
Example #3
0
/**
 * uses iteration of SegmentSegmentIntersect.
 *
 * returns the number of intersections it finds
 */
int SegmentPolylineIntersect(
    const ON_3dPoint& P,
    const ON_3dPoint& Q,
    const ON_Polyline& pline,
    ON_SimpleArray<ON_3dPoint> out,
    double tol
    )
{
    int rv = 0;
    int my_rv = 0; /* what this function will return at the end */
    ON_3dPoint result[2];
    for (int i = 0; i < (pline.Count() - 1); i++) {
	rv = SegmentSegmentIntersect(P, Q, pline[i], pline[i+1], result, tol);
	if (out) { /* the output field can be made null to use the function to check for intersections but not return them */
	    for (int j = 0; j < rv; j++) {
		out.Append(result[j]);
	    }
	}
	my_rv += rv;
    }
    return my_rv;
}
Example #4
0
bool PointInPolyline(
    const ON_3dPoint& P,
    const ON_Polyline pline,
    double tol
    )
{
    if (!pline.IsClosed(tol)) { /* no inside to speak of */
	return false;
    }
    /* First we need to find a point that's in the plane and outside the polyline */
    ON_BoundingBox bbox;
    PolylineBBox(pline, &bbox);
    ON_3dPoint adder;
    int i;
    for (i = 0; i < pline.Count(); i++) {
	adder = P - pline[i];
	if (!VNEAR_ZERO(adder, tol)) {
	    break;
	}
    }
    ON_3dPoint DistantPoint = P;
    int multiplier = 2;
    do {
	DistantPoint += adder*multiplier;
	multiplier = multiplier*multiplier;
    } while (bbox.IsPointIn(DistantPoint, false));
    bool inside = false;
    int rv;
    ON_3dPoint result[2];
    for (i = 0; i < pline.Count() - 1; i++) {
	rv = SegmentSegmentIntersect(P, DistantPoint, pline[i], pline[i + 1], result, tol);
	if (rv == 1) {
	    inside = !inside;
	} else if (rv == 2) {
	    bu_exit(-1, "This is very unlikely bug in PointInPolyline which needs to be fixed\n");
	}
    }
    return inside;
}
Example #5
0
/**
 * intersects a triangle ABC with a line PQ
 *
 * return values:
 * -1: error
 * 0: no intersection
 * 1: intersects in a point
 * 2: intersects in a line
 */
int SegmentTriangleIntersect(
    const ON_3dPoint& a,
    const ON_3dPoint& b,
    const ON_3dPoint& c,
    const ON_3dPoint& p,
    const ON_3dPoint& q,
    ON_3dPoint out[2],
    double tol
    )
{
    ON_3dPoint triangle[3] = {a, b, c}; /* it'll be nice to have this as an array too*/

    /* First we need to get our plane into point normal form (N \dot (P - P0) = 0)
     * Where N is a normal vector, and P0 is a point in the plane
     * P0 can be any of {a, b, c} so that's easy
     * Finding N
     */

    double normal[3];
    VCROSS(normal, b - a, c - a);
    VUNITIZE(normal);

    ON_3dPoint P0 = a; /* could be b or c*/

    /* Now we've got our plane in a manageable form (two of them actually)
     * So here's the rest of the plan:
     * Every point P on the line can be written as: P = p + u (q - p)
     * We just need to find u
     * We know that when u is correct:
     * normal dot (q + u * (q-p) = N dot P0
     *		   N dot (P0 - p)
     * so u =      --------------
     *		   N dot (q - p)
     */

    if (!NEAR_ZERO(VDOT(normal, (p-q)), tol)) {/* if this is 0 it indicates the line and plane are parallel*/
	double u = VDOT(normal, (P0 - p))/VDOT(normal, (q - p));
	if (u < 0.0 || u > 1.0)	/* this means we're on the line but not the line segment*/
	    return 0;		/* so we can return early*/
	ON_3dPoint P = p + u * (q - p);

	if (PointInTriangle(a, b, c, P, tol)) {
	    out[0] = P;
	    return 1;
	}
	return 0;

    } else {
	/* If we're here it means that the line and plane are parallel*/

	if (NEAR_ZERO(VDOT(normal, p-P0), tol)) {/* yahtzee!!*/
	    /* The line segment is in the same plane as the triangle*/
	    /* So first we check if the points are inside or outside the triangle*/
	    bool p_in = PointInTriangle(a, b, c, p, tol);
	    bool q_in = PointInTriangle(a, b , c , q , tol);
	    ON_3dPoint x[2]; /* a place to put our results*/

	    if (q_in && p_in) {
		out[0] = p;
		out[1] = q;
		return 2;
	    } else if (q_in || p_in) {
		if (q_in)
		    out[0] = q;
		else
		    out[0] = p;

		int i;
		int rv;
		for (i=0; i<3; i++) {
		    rv = SegmentSegmentIntersect(triangle[i], triangle[(i+1)%3], p, q, x, tol);
		    if (rv == 1) {
			out[1] = x[0];
			return 1;
		    } else if (rv == 2) {
			out[0] = x[0];
			out[1] = x[1];
			return 2;
		    }
		}
	    } else {
		/* neither q nor p is in the triangle*/

		int i;
		int points_found = 0;
		int rv;
		for (i = 0; i < 3; i++) {
		    rv = SegmentSegmentIntersect(triangle[i], triangle[(i+1)%3], p, q, x, tol);
		    if (rv == 1) {
			if (points_found == 0 || !VNEAR_EQUAL(out[0], x[0], tol)) { /* in rare cases we can get the same point twice*/
			    out[points_found] = x[0];
			    points_found++;
			}
		    } else if (rv == 2) {
			out[0] = x[0];
			out[1] = x[1];
			return 2;
		    }
		}
		return points_found;
	    }
	} else
	    return 0;
    }
    return -1;
}