Exemplo n.º 1
0
//wrapper to do Circle-Ellipse and Arc-Ellipse using Ellipse-Ellipse intersection
RS_VectorSolutions RS_Information::getIntersectionCircleEllipse(RS_Circle* c1,
        RS_Ellipse* e1) {
    RS_VectorSolutions ret;
	if (!(c1 && e1)) return ret;

	RS_Ellipse const e2{c1->getParent(),
			{c1->getCenter(), {c1->getRadius(),0.},
			1.0,
			0., 2.*M_PI,
			false}};
	return getIntersectionEllipseEllipse(e1, &e2);
}
Exemplo n.º 2
0
RS_VectorSolutions RS_Information::getIntersectionArcEllipse(RS_Arc * a1,
        RS_Ellipse* e1) {
    RS_VectorSolutions ret;
	if (!(a1 && e1)) {
        return ret;
	}
	RS_Ellipse const e2{a1->getParent(),
			{a1->getCenter(),
			{a1->getRadius(), 0.},
			1.0,
			a1->getAngle1(), a1->getAngle2(),
			a1->isReversed()}};
	return getIntersectionEllipseEllipse(e1, &e2);
}
Exemplo n.º 3
0
//wrapper to do Circle-Ellipse and Arc-Ellipse using Ellipse-Ellipse intersection
RS_VectorSolutions RS_Information::getIntersectionCircleEllipse(RS_Circle* c1,
        RS_Ellipse* e1) {
    RS_VectorSolutions ret;
	if (!(c1 && e1)) return ret;

    RS_EllipseData d(
        c1->getCenter(),
        RS_Vector(c1->getRadius(),0.),
        1.0,
        0.,
        2.*M_PI,
        false);
    RS_Ellipse * e2= new RS_Ellipse(c1->getParent(),d);
    return getIntersectionEllipseEllipse(e1,e2);
}
Exemplo n.º 4
0
RS_VectorSolutions RS_Information::getIntersectionArcEllipse(RS_Arc * a1,
        RS_Ellipse* e1) {
    RS_VectorSolutions ret;
    if (a1==NULL || e1==NULL) {
        return ret;
    }
    RS_EllipseData d(
        a1->getCenter(),
        RS_Vector(a1->getRadius(),0.),
        1.0,
        a1->getAngle1(),
        a1->getAngle2(),
        a1->isReversed());
    RS_Ellipse * e2= new RS_Ellipse(a1->getParent(),d);
    return getIntersectionEllipseEllipse(e1,e2);
}
Exemplo n.º 5
0
/**
 * Calculates the intersection point(s) between two entities.
 *
 * @param onEntities true: only return intersection points which are
 *                   on both entities.
 *                   false: return all intersection points.
 *
 * @todo support more entities
 *
 * @return All intersections of the two entities. The tangent flag in
 * RS_VectorSolutions is set if one intersection is a tangent point.
 */
RS_VectorSolutions RS_Information::getIntersection(RS_Entity* e1,
        RS_Entity* e2, bool onEntities) {

    RS_VectorSolutions ret;
    double tol = 1.0e-4;

    if (e1==NULL || e2==NULL ) {
        RS_DEBUG->print("RS_Information::getIntersection() for NULL entities");
        return ret;
    }
    if (e1->getId() == e2->getId()) {
        RS_DEBUG->print("RS_Information::getIntersection() of the same entity");
        return ret;
    }

    // unsupported entities / entity combinations:
    if (
        e1->rtti()==RS2::EntityText || e2->rtti()==RS2::EntityText ||
        isDimension(e1->rtti()) || isDimension(e2->rtti())) {
        return ret;
    }
    // a little check to avoid doing unneeded intersections, an attempt to avoid O(N^2) increasing of checking two-entity information
    if (onEntities
            && (
                e1 -> getMin().x > e2 -> getMax().x
                || e1 -> getMax().x < e2 -> getMin().x
                || e1 -> getMin().y > e2 -> getMax().y
                || e1 -> getMax().y < e2 -> getMin().y
                )
            ) {
            return ret;
    }

    // one entity is an ellipse:
    if (e1->rtti()==RS2::EntityEllipse || e2->rtti()==RS2::EntityEllipse) {
        if (e2->rtti()==RS2::EntityEllipse) std::swap( e1, e2);
        if (e2->rtti()==RS2::EntityEllipse) {
            ret = getIntersectionEllipseEllipse((RS_Ellipse*)e1, (RS_Ellipse *) e2);
        }
        if (e2->rtti()==RS2::EntityCircle) {
            ret = getIntersectionCircleEllipse((RS_Circle *)e2, (RS_Ellipse *) e1);
        }
        if (e2->rtti()==RS2::EntityArc) {
            ret = getIntersectionArcEllipse((RS_Arc *)e2, (RS_Ellipse *) e1);
        }
        if (e2->rtti()==RS2::EntityLine) {
            ret = getIntersectionLineEllipse((RS_Line*)e2, (RS_Ellipse*) e1);
            tol = 1.0e-1;
        }

        // not supported:
        else {
            return ret;
        }
    } else {

        RS_Entity* te1 = e1;
        RS_Entity* te2 = e2;

        // entity copies - so we only have to deal with lines and arcs
        RS_Line l1(NULL,
                   RS_LineData(RS_Vector(0.0, 0.0), RS_Vector(0.0,0.0)));
        RS_Line l2(NULL,
                   RS_LineData(RS_Vector(0.0, 0.0), RS_Vector(0.0,0.0)));

        RS_Arc a1(NULL,
                  RS_ArcData(RS_Vector(0.0,0.0), 1.0, 0.0, 2*M_PI, false));
        RS_Arc a2(NULL,
                  RS_ArcData(RS_Vector(0.0,0.0), 1.0, 0.0, 2*M_PI, false));

        // convert construction lines to lines:
        if (e1->rtti()==RS2::EntityConstructionLine) {
            RS_ConstructionLine* cl = (RS_ConstructionLine*)e1;

            l1.setStartpoint(cl->getPoint1());
            l1.setEndpoint(cl->getPoint2());

            te1 = &l1;
        }
        if (e2->rtti()==RS2::EntityConstructionLine) {
            RS_ConstructionLine* cl = (RS_ConstructionLine*)e2;

            l2.setStartpoint(cl->getPoint1());
            l2.setEndpoint(cl->getPoint2());

            te2 = &l2;
        }


        // convert circles to arcs:
        if (e1->rtti()==RS2::EntityCircle) {
            RS_Circle* c = (RS_Circle*)e1;

            RS_ArcData data(c->getCenter(), c->getRadius(), 0.0, 2*M_PI, false);
            a1.setData(data);

            te1 = &a1;
        }
        if (e2->rtti()==RS2::EntityCircle) {
            RS_Circle* c = (RS_Circle*)e2;

            RS_ArcData data(c->getCenter(), c->getRadius(), 0.0, 2*M_PI, false);
            a2.setData(data);

            te2 = &a2;
        }


        // line / line:
        //
        //else
        if (te1->rtti()==RS2::EntityLine &&
                te2->rtti()==RS2::EntityLine) {
            RS_Line * line1=(RS_Line*) te1;
            RS_Line * line2=(RS_Line*) te2;
            /* ToDo: 24 Aug 2011, Dongxu Li, if rtti() is not defined for the parent, the following check for splines may still cause segfault */
            if ( line1->getParent() != NULL && line1->getParent() == line2->getParent()) {
                if ( line1->getParent()->rtti()==RS2::EntitySpline ) {
                    //do not calculate intersections from neighboring lines of a spline
                    if ( abs(line1->getParent()->findEntity(line1) - line1->getParent()->findEntity(line2)) <= 1 ) {
                        return ret;
                    }
                }
            }

            ret = getIntersectionLineLine(line1, line2);
        }

        // line / arc:
        //
        else if (te1->rtti()==RS2::EntityLine &&
                 te2->rtti()==RS2::EntityArc) {

            RS_Line* line = (RS_Line*)te1;
            RS_Arc* arc = (RS_Arc*)te2;

            ret = getIntersectionLineArc(line, arc);
        }

        // arc / line:
        //
        else if (te1->rtti()==RS2::EntityArc &&
                 te2->rtti()==RS2::EntityLine) {

            RS_Arc* arc = (RS_Arc*)te1;
            RS_Line* line = (RS_Line*)te2;

            ret = getIntersectionLineArc(line, arc);
        }

        // arc / arc:
        //
        else if (te1->rtti()==RS2::EntityArc &&
                 te2->rtti()==RS2::EntityArc) {

            RS_Arc* arc1 = (RS_Arc*)te1;
            RS_Arc* arc2 = (RS_Arc*)te2;

            ret = getIntersectionArcArc(arc1, arc2);
            // ellipse / ellipse
            //
        } else {
            RS_DEBUG->print("RS_Information::getIntersection:: Unsupported entity type.");
        }

    }


    // Check all intersection points for being on entities:
    //
    if (onEntities==true) {
        if (!e1->isPointOnEntity(ret.get(0), tol) ||
                !e2->isPointOnEntity(ret.get(0), tol)) {
            ret.set(0, RS_Vector(false));
        }
        if (!e1->isPointOnEntity(ret.get(1), tol) ||
                !e2->isPointOnEntity(ret.get(1), tol)) {
            ret.set(1, RS_Vector(false));
        }
        if (!e1->isPointOnEntity(ret.get(2), tol) ||
                !e2->isPointOnEntity(ret.get(2), tol)) {
            ret.set(2, RS_Vector(false));
        }
        if (!e1->isPointOnEntity(ret.get(3), tol) ||
                !e2->isPointOnEntity(ret.get(3), tol)) {
            ret.set(3, RS_Vector(false));
        }
    }

    int k=0;
    for (int i=0; i<4; ++i) {
        if (ret.get(i).valid) {
            ret.set(k, ret.get(i));
            k++;
        }
    }
    for (int i=k; i<4; ++i) {
        ret.set(i, RS_Vector(false));
    }

    return ret;
}