示例#1
0
QList<RVector> RShape::getIntersectionPointsAE(const RArc& arc1,
        const REllipse& ellipse2, bool limited) {
    QList<RVector> candidates =
            RShape::getIntersectionPointsCE(
                RCircle(arc1.getCenter(), arc1.getRadius()),
                ellipse2);

    if (!limited) {
        return candidates;
    }

    QList<RVector> res;

    for (int i=0; i<candidates.count(); i++) {
        RVector c = candidates[i];
        if (arc1.isOnShape(c)) {
            if (!ellipse2.isFullEllipse()) {
                double a1 = ellipse2.getCenter().getAngleTo(ellipse2.getStartPoint());
                double a2 = ellipse2.getCenter().getAngleTo(ellipse2.getEndPoint());
                double a = ellipse2.getCenter().getAngleTo(c);
                if (!RMath::isAngleBetween(a, a1, a2, ellipse2.isReversed())) {
                    continue;
                }
            }

            res.append(c);
        }
    }

    return res;
}
示例#2
0
void REllipseEntity::setShape(const REllipse& e) {
    data.setCenter(e.getCenter());
    data.setMajorPoint(e.getMajorPoint());
    data.setRatio(e.getRatio());
    data.setStartParam(e.getStartParam());
    data.setEndParam(e.getEndParam());
    data.setReversed(e.isReversed());
}
示例#3
0
/**
 * Exports an ellipse with the current attributes.
 * \todo switch from line based interpolation to arcs.
 */
void RExporter::exportEllipse(const REllipse& ellipse, double offset) {
    if (ellipse.getMajorRadius()<RS::PointTolerance ||
            ellipse.getMinorRadius()<RS::PointTolerance) {
        return;
    }

    RPolyline polyline;

    RVector cp = ellipse.getCenter();
    double radius1 = ellipse.getMajorRadius();
    double radius2 = ellipse.getMinorRadius();
    double angle = ellipse.getAngle();
    double a1 = ellipse.getStartParam();
    double a2 = ellipse.getEndParam();
    bool reversed = ellipse.isReversed();

    double aStep;         // Angle Step (rad)
    double a;             // Current Angle (rad)

    aStep=0.05;
    RVector vp;
    RVector vc(cp.x, cp.y);
    vp.set(cp.x+cos(a1)*radius1,
           cp.y+sin(a1)*radius2);
    vp.rotate(angle, vc);
    polyline.appendVertex(vp);
    if (!reversed) {
        // Arc Counterclockwise:
        if (a1>a2-RS::AngleTolerance) {
            a2+=2*M_PI;
        }
        for(a=a1+aStep; a<=a2; a+=aStep) {
            vp.set(cp.x+cos(a)*radius1,
                   cp.y+sin(a)*radius2);
            vp.rotate(angle, vc);
            polyline.appendVertex(vp);
        }
    } else {
        // Arc Clockwise:
        if (a1<a2+RS::AngleTolerance) {
            a2-=2*M_PI;
        }
        for(a=a1-aStep; a>=a2; a-=aStep) {
            vp.set(cp.x+cos(a)*radius1,
                   cp.y+sin(a)*radius2);
            vp.rotate(angle, vc);
            polyline.appendVertex(vp);
        }
    }
    vp.set(cp.x+cos(a2)*radius1,
           cp.y+sin(a2)*radius2);
    vp.rotate(angle, vc);
    polyline.appendVertex(vp);

    exportPolyline(polyline, offset);
}
示例#4
0
QList<RVector> RShape::getIntersectionPointsEE(const REllipse& ellipse1, const REllipse& ellipse2, bool limited) {
    QList<RVector> candidates = getIntersectionPointsEE(ellipse1, ellipse2);

    if (!limited) {
        return candidates;
    }

    QList<RVector> ret;

    for (int i=0; i<candidates.length(); i++) {
        RVector c = candidates[i];
        bool onShape = true;

        double a1 = ellipse1.getCenter().getAngleTo(ellipse1.getStartPoint());
        double a2 = ellipse1.getCenter().getAngleTo(ellipse1.getEndPoint());
        double a = ellipse1.getCenter().getAngleTo(c);
        if (!RMath::isAngleBetween(a, a1, a2, ellipse1.isReversed())) {
//            qDebug() << "1) angle NOT between: "
//                << " a: " << RMath::rad2deg(a)
//                << " a1: " << RMath::rad2deg(a1)
//                << " a2: " << RMath::rad2deg(a2)
//                << " r: " << ellipse1.isReversed();
            //ret.append(c);
            onShape = false;
        }

        a1 = ellipse2.getCenter().getAngleTo(ellipse2.getStartPoint());
        a2 = ellipse2.getCenter().getAngleTo(ellipse2.getEndPoint());
        a = ellipse2.getCenter().getAngleTo(c);
        if (!RMath::isAngleBetween(a, a1, a2, ellipse2.isReversed())) {
//            qDebug() << "2) angle NOT between: "
//                << " a: " << RMath::rad2deg(a)
//                << " a1: " << RMath::rad2deg(a1)
//                << " a2: " << RMath::rad2deg(a2)
//                << " r: " << ellipse2.isReversed();
            //ret.append(c);
            onShape = false;
        }

        if (onShape) {
            ret.append(c);
        }
    }

    return ret;
}
示例#5
0
QList<RVector> RShape::getIntersectionPointsLE(const RLine& line1,
        const REllipse& ellipse2, bool limited) {

    QList<RVector> res;

    // find out if line1 is (almost) a tangent:
    QList<RLine> tangents = ellipse2.getTangents(line1.getMiddlePoint());
    for (int i=0; i<tangents.length(); i++) {
        double a = tangents[i].getAngle();
        double ad1 = fabs(RMath::getAngleDifference180(a, line1.getDirection1()));
        double ad2 = fabs(RMath::getAngleDifference180(a, line1.getDirection2()));

        if (ad1 < 1.0e-2 || ad2 < 1.0e-2) {
            res.append(tangents[i].getEndPoint());

            // no need to continue: max. one tangent possible:
            return res;
        }
    }

    // rotate into normal position:
    double ang = ellipse2.getAngle();

    double rx = ellipse2.getMajorRadius();
    double ry = ellipse2.getMinorRadius();
    RVector center = ellipse2.getCenter();
    RVector a1 = line1.getStartPoint();
    a1.rotate(-ang, center);
    RVector a2 = line1.getEndPoint();
    a2.rotate(-ang, center);
    RVector origin = a1;
    RVector dir = a2-a1;
    RVector diff = origin - center;
    RVector mDir = RVector(dir.x/(rx*rx), dir.y/(ry*ry));
    RVector mDiff = RVector(diff.x/(rx*rx), diff.y/(ry*ry));

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

    RVector res1 = RVector::invalid;
    RVector res2 = RVector::invalid;

    if (d < 0) {
        // no solution
    } else if ( d > 0 ) {
        double root = sqrt(d);
        double t_a = (-b - root) / a;
        double t_b = (-b + root) / a;

        res1 = a1.getLerp(a2, t_a).rotate(ang, center);
        res2 = a1.getLerp(a2, t_b).rotate(ang, center);
    } else {
        double t = -b/a;
        if ( 0 <= t && t <= 1 ) {
            // one solution:
            res1 = a1.getLerp(a2, t).rotate(ang, center);
        } else {
            // no solution
        }
    }

    if (res1.isValid()) {
        if (!limited || (line1.isOnShape(res1) && ellipse2.isOnShape(res1))) {
            res.append(res1);
        }
    }
    if (res2.isValid()) {
        if (!limited || (line1.isOnShape(res2) && ellipse2.isOnShape(res2))) {
            res.append(res2);
        }
    }

    return res;
}