Example #1
0
/**
 * @return Intersection between two lines.
 */
RS_VectorSolutions RS_Information::getIntersectionLineLine(RS_Line* e1,
        RS_Line* e2) {

    RS_VectorSolutions ret;

    if (e1==NULL || e2==NULL) {
        RS_DEBUG->print("RS_Information::getIntersectionLineLin() for NULL entities");
        return ret;
    }

    RS_Vector p1 = e1->getStartpoint();
    RS_Vector p2 = e1->getEndpoint();
    RS_Vector p3 = e2->getStartpoint();
    RS_Vector p4 = e2->getEndpoint();

    double num = ((p4.x-p3.x)*(p1.y-p3.y) - (p4.y-p3.y)*(p1.x-p3.x));
    double div = ((p4.y-p3.y)*(p2.x-p1.x) - (p4.x-p3.x)*(p2.y-p1.y));

    if (fabs(div)>RS_TOLERANCE) {
        double u = num / div;

        double xs = p1.x + u * (p2.x-p1.x);
        double ys = p1.y + u * (p2.y-p1.y);
        ret = RS_VectorSolutions(RS_Vector(xs, ys));
    }

    // lines are parallel
    else {
        ret = RS_VectorSolutions();
    }

    return ret;
}
Example #2
0
/**
 * @return One or two intersection points between given entities.
 */
RS_VectorSolutions RS_Information::getIntersectionArcArc(RS_Entity const* e1,
		RS_Entity const* e2) {

    RS_VectorSolutions ret;

	if (!(e1 && e2)) return ret;

	if(e1->rtti() != RS2::EntityArc && e1->rtti() != RS2::EntityCircle)
		return ret;
	if(e2->rtti() != RS2::EntityArc && e2->rtti() != RS2::EntityCircle)
		return ret;

    RS_Vector c1 = e1->getCenter();
    RS_Vector c2 = e2->getCenter();

    double r1 = e1->getRadius();
    double r2 = e2->getRadius();

    RS_Vector u = c2 - c1;

    // concentric
    if (u.magnitude()<1.0e-6) {
        return ret;
    }

    RS_Vector v = RS_Vector(u.y, -u.x);

    double s, t1, t2, term;

    s = 1.0/2.0 * ((r1*r1 - r2*r2)/(RS_Math::pow(u.magnitude(), 2.0)) + 1.0);

    term = (r1*r1)/(RS_Math::pow(u.magnitude(), 2.0)) - s*s;

    // no intersection:
    if (term<0.0) {
        ret = RS_VectorSolutions();
    }

    // one or two intersections:
    else {
        t1 = sqrt(term);
        t2 = -sqrt(term);
        bool tangent = false;

        RS_Vector sol1 = c1 + u*s + v*t1;
        RS_Vector sol2 = c1 + u*s + v*t2;

        if (sol1.distanceTo(sol2)<1.0e-4) {
            sol2 = RS_Vector(false);
			ret = RS_VectorSolutions({sol1});
            tangent = true;
        } else {
			ret = RS_VectorSolutions({sol1, sol2});
        }

        ret.setTangent(tangent);
    }

    return ret;
}
Example #3
0
/**
 * @return Intersection between two lines.
 */
RS_VectorSolutions RS_Information::getIntersectionLineLine(RS_Line* e1,
        RS_Line* e2) {

    RS_VectorSolutions ret;

	if (!(e1 && e2)) {
		RS_DEBUG->print("RS_Information::getIntersectionLineLin() for nullptr entities");
        return ret;
    }

    RS_Vector p1 = e1->getStartpoint();
    RS_Vector p2 = e1->getEndpoint();
    RS_Vector p3 = e2->getStartpoint();
    RS_Vector p4 = e2->getEndpoint();

    double num = ((p4.x-p3.x)*(p1.y-p3.y) - (p4.y-p3.y)*(p1.x-p3.x));
    double div = ((p4.y-p3.y)*(p2.x-p1.x) - (p4.x-p3.x)*(p2.y-p1.y));

	if (fabs(div)>RS_TOLERANCE &&
			fabs(remainder(e1->getAngle1()-e2->getAngle1(), M_PI))>=RS_TOLERANCE*10.) {
		double u = num / div;

		double xs = p1.x + u * (p2.x-p1.x);
		double ys = p1.y + u * (p2.y-p1.y);
		ret = RS_VectorSolutions({RS_Vector(xs, ys)});
	}

    // lines are parallel
    else {
        ret = RS_VectorSolutions();
    }

    return ret;
}
Example #4
0
RS_VectorSolutions RS_Circle::getRefPoints() const
{
	RS_Vector v1(data.radius, 0.0);
	RS_Vector v2(0.0, data.radius);

	return RS_VectorSolutions ({data.center,
						   data.center+v1, data.center+v2,
						   data.center-v1, data.center-v2});
}
Example #5
0
/**
 * @return One or two intersection points between given entities.
 */
RS_VectorSolutions RS_Information::getIntersectionLineEllipse(RS_Line* line,
        RS_Ellipse* ellipse) {

    RS_VectorSolutions ret;

    if (line==NULL || ellipse==NULL) {
        return ret;
    }

    // rotate into normal position:
    double ang = ellipse->getAngle();

    double rx = ellipse->getMajorRadius();
    double ry = ellipse->getMinorRadius();
    RS_Vector center = ellipse->getCenter();
    RS_Vector a1 = line->getStartpoint().rotate(center, -ang);
    RS_Vector a2 = line->getEndpoint().rotate(center, -ang);
    RS_Vector origin = a1;
    RS_Vector dir = a2-a1;
    RS_Vector diff = origin - center;
    RS_Vector mDir = RS_Vector(dir.x/(rx*rx), dir.y/(ry*ry));
    RS_Vector mDiff = RS_Vector(diff.x/(rx*rx), diff.y/(ry*ry));

    double a = RS_Vector::dotP(dir, mDir);
    double b = RS_Vector::dotP(dir, mDiff);
    double c = RS_Vector::dotP(diff, mDiff) - 1.0;
    double d = b*b - a*c;

    if (d < 0) {
        RS_DEBUG->print("RS_Information::getIntersectionLineEllipse: outside 0");
    } else if ( d > 0 ) {
        double root = sqrt(d);
        double t_a = (-b - root) / a;
        double t_b = (-b + root) / a;

        /*if ( (t_a < 0 || 1 < t_a) && (t_b < 0 || 1 < t_b) ) {
            if ( (t_a < 0 && t_b < 0) || (t_a > 1 && t_b > 1) ) {
                RS_DEBUG->print("RS_Information::getIntersectionLineEllipse: outside 1");
            }
            else {
                RS_DEBUG->print("RS_Information::getIntersectionLineEllipse: inside 1");
            }
        } else {*/
        RS_DEBUG->print("RS_Information::getIntersectionLineEllipse: intersection 1");
        RS_Vector ret1(false);
        RS_Vector ret2(false);
        //if ( 0 <= t_a && t_a <= 1 ) {
        //RS_DEBUG->print("RS_Information::getIntersectionLineEllipse: 0<=t_a<=1");
        ret1 = a1.lerp(a2, t_a);
        RS_DEBUG->print("RS_Information::getIntersectionLineEllipse: ret1: %f/%f", ret1.x, ret1.y);
        //}
        //if ( 0 <= t_b && t_b <= 1 ) {
        //RS_DEBUG->print("RS_Information::getIntersectionLineEllipse: 0<=t_b<=1");
        ret2 = a1.lerp(a2, t_b);
        RS_DEBUG->print("RS_Information::getIntersectionLineEllipse: ret2: %f/%f", ret2.x, ret2.y);
        //}
        if (ret1.valid && ret2.valid) {
            ret = RS_VectorSolutions(ret1, ret2);
        }
        else {
            if (ret1.valid) {
                ret = RS_VectorSolutions(ret1);
            }
            if (ret2.valid) {
                ret = RS_VectorSolutions(ret2);
            }
        }
        //}
    } else {
        double t = -b/a;
        if ( 0 <= t && t <= 1 ) {
            RS_DEBUG->print("RS_Information::getIntersectionLineEllipse: 0<=t<=1");
            RS_DEBUG->print("RS_Information::getIntersectionLineEllipse: intersection 2");
            ret = RS_VectorSolutions(a1.lerp(a2, t));
            RS_DEBUG->print("RS_Information::getIntersectionLineEllipse: ret1: %f/%f", ret.get(0).x, ret.get(0).y);
        } else {
            RS_DEBUG->print("RS_Information::getIntersectionLineEllipse: outside 2");
        }
    }

    ret.rotate(center, ang);
    return ret;



    /*
    RS_Arc* arc = new RS_Arc(NULL,
                             RS_ArcData(ellipse->getCenter(),
                                        ellipse->getMajorRadius(),
                                        ellipse->getAngle1(),
                                        ellipse->getAngle2(),
                                        false));
    RS_Line* other = (RS_Line*)line->clone();
    double angle = ellipse->getAngle();
    //double ratio = ellipse->getRatio();

    // rotate entities:
    other->rotate(ellipse->getCenter(), -angle);
    other->scale(ellipse->getCenter(), RS_Vector(1.0, 1.0/ellipse->getRatio()));

    ret = getIntersectionLineArc(other, arc);

    ret.scale(ellipse->getCenter(), RS_Vector(1.0, ellipse->getRatio()));
    ret.rotate(ellipse->getCenter(), angle);

    delete arc;
    delete other;

    return ret;
    */
}
Example #6
0
/**
 * @return One or two intersection points between given entities.
 */
RS_VectorSolutions RS_Information::getIntersectionLineArc(RS_Line* line,
        RS_Arc* arc) {

    RS_VectorSolutions ret;

    if (line==NULL || arc==NULL) {
        return ret;
    }

    double dist=0.0;
    RS_Vector nearest;
    nearest = line->getNearestPointOnEntity(arc->getCenter(), false, &dist);

    // special case: arc touches line (tangent):
    if (fabs(dist - arc->getRadius()) < 1.0e-4) {
        ret = RS_VectorSolutions(nearest);
        ret.setTangent(true);
        return ret;
    }

    RS_Vector p = line->getStartpoint();
    RS_Vector d = line->getEndpoint() - line->getStartpoint();
    if (d.magnitude()<1.0e-6) {
        return ret;
    }

    RS_Vector c = arc->getCenter();
    double r = arc->getRadius();
    RS_Vector delta = p - c;

    // root term:
    double term = RS_Math::pow(RS_Vector::dotP(d, delta), 2.0)
                  - RS_Math::pow(d.magnitude(), 2.0)
                  * (RS_Math::pow(delta.magnitude(), 2.0) - RS_Math::pow(r, 2.0));

    // no intersection:
    if (term<0.0) {
        RS_VectorSolutions s;
        ret = s;
    }

    // one or two intersections:
    else {
        double t1 = (- RS_Vector::dotP(d, delta) + sqrt(term))
                    / RS_Math::pow(d.magnitude(), 2.0);
        double t2;
        bool tangent = false;

        // only one intersection:
        if (fabs(term)<RS_TOLERANCE) {
            t2 = t1;
            tangent = true;
        }

        // two intersections
        else {
            t2 = (-RS_Vector::dotP(d, delta) - sqrt(term))
                 / RS_Math::pow(d.magnitude(), 2.0);
        }

        RS_Vector sol1;
        RS_Vector sol2(false);

        sol1 = p + d * t1;

        if (!tangent) {
            sol2 = p + d * t2;
        }

        ret = RS_VectorSolutions(sol1, sol2);
        ret.setTangent(tangent);
    }

    return ret;
}
Example #7
0
RS_VectorSolutions RS_DimDiametric::getRefPoints() const
{
		return RS_VectorSolutions({edata.definitionPoint,
												data.definitionPoint, data.middleOfText});
}
Example #8
0
/**
 * @return One or two intersection points between given entities.
 */
RS_VectorSolutions RS_Information::getIntersectionLineArc(RS_Line* line,
        RS_Arc* arc) {

    RS_VectorSolutions ret;

	if (!(line && arc)) return ret;

    double dist=0.0;
    RS_Vector nearest;
    nearest = line->getNearestPointOnEntity(arc->getCenter(), false, &dist);

    // special case: arc touches line (tangent):
    if (nearest.valid && fabs(dist - arc->getRadius()) < 1.0e-4) {
		ret = RS_VectorSolutions({nearest});
        ret.setTangent(true);
        return ret;
    }

    RS_Vector p = line->getStartpoint();
    RS_Vector d = line->getEndpoint() - line->getStartpoint();
    double d2=d.squared();
    RS_Vector c = arc->getCenter();
    double r = arc->getRadius();
    RS_Vector delta = p - c;
    if (d2<RS_TOLERANCE2) {
        //line too short, still check the whether the line touches the arc
        if ( fabs(delta.squared() - r*r) < 2.*RS_TOLERANCE*r ){
			return RS_VectorSolutions({line->getMiddlePoint()});
        }
        return ret;
    }


    //intersection
    // solution = p + t d;
    //| p -c+ t d|^2 = r^2
    // |d|^2 t^2 + 2 (p-c).d t + |p-c|^2 -r^2 = 0
    double a1 = RS_Vector::dotP(delta,d);
    double term1 = a1*a1 - d2*(delta.squared()-r*r);
//        std::cout<<" discriminant= "<<term1<<std::endl;
    if( term1 < - RS_TOLERANCE) {
//        std::cout<<"no intersection\n";
    return ret;
    }else{
        term1=fabs(term1);
//        std::cout<< "term1="<<term1 <<" threshold: "<< RS_TOLERANCE * d2 <<std::endl;
        if( term1 < RS_TOLERANCE * d2 ) {
            //tangential;
//            ret=RS_VectorSolutions(p - d*(a1/d2));
			ret=RS_VectorSolutions({line->getNearestPointOnEntity(c, false)});
            ret.setTangent(true);
//        std::cout<<"Tangential point: "<<ret<<std::endl;
            return ret;
        }
        double t = sqrt(fabs(term1));
    //two intersections
	 return RS_VectorSolutions({ p + d*(t-a1)/d2, p -d*(t+a1)/d2});
    }

//    // root term:
//    term1 = r*r - delta.squared() + term1*term1/d.squared();
//    double term = RS_Math::pow(RS_Vector::dotP(d, delta), 2.0)
//                  - RS_Math::pow(d.magnitude(), 2.0)
//                  * (RS_Math::pow(delta.magnitude(), 2.0) - RS_Math::pow(r, 2.0));
//    std::cout<<"old term= "<<term<<"\tnew term= "<<term1<<std::endl;

//    // no intersection:
//    if (term<0.0) {
//        ret = RS_VectorSolutions() ;
//    }

//    // one or two intersections:
//    else {
//        double t1 = (- RS_Vector::dotP(d, delta) + sqrt(term))
//                    / RS_Math::pow(d.magnitude(), 2.0);
//        double t2;
//        bool tangent = false;

//        // only one intersection:
//        if (fabs(term)<RS_TOLERANCE) {
//            t2 = t1;
//            tangent = true;
//        }

//        // two intersections
//        else {
//            t2 = (-RS_Vector::dotP(d, delta) - sqrt(term))
//                 / RS_Math::pow(d.magnitude(), 2.0);
//        }

//        RS_Vector sol1;
//        RS_Vector sol2(false);

//        sol1 = p + d * t1;

//        if (!tangent) {
//            sol2 = p + d * t2;
//        }

//        ret = RS_VectorSolutions(sol1, sol2);
//        ret.setTangent(tangent);
//    }

//    std::cout<<"ret= "<<ret<<std::endl;
//    return ret;
}
Example #9
0
RS_VectorSolutions RS_Spline::getRefPoints() {
	return RS_VectorSolutions(data.controlPoints);
}
Example #10
0
RS_VectorSolutions RS_Entity::getRefPoints() const
{
	return RS_VectorSolutions();
}
Example #11
0
RS_VectorSolutions RS_MText::getRefPoints() const{
		return RS_VectorSolutions({data.insertionPoint});
}
Example #12
0
RS_VectorSolutions RS_Entity::getTangentPoint(const RS_Vector& /*point*/) const {
	return RS_VectorSolutions();
}
RS_VectorSolutions RS_DimAligned::getRefPoints() const
{
		return RS_VectorSolutions({edata.extensionPoint1, edata.extensionPoint2,
												data.definitionPoint, data.middleOfText});
}
Example #14
0
RS_VectorSolutions LC_Hyperbola::getFoci() const {
    RS_Vector vp(getMajorP()*sqrt(1.-getRatio()*getRatio()));
	return RS_VectorSolutions({getCenter()+vp, getCenter()-vp});
}
Example #15
0
RS_VectorSolutions RS_Line::getRefPoints() const
{
	return RS_VectorSolutions({data.startpoint, data.endpoint});
}
Example #16
0
RS_VectorSolutions RS_DimRadial::getRefPoints() {
		return RS_VectorSolutions({edata.definitionPoint,
												data.definitionPoint, data.middleOfText});
}