Example #1
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);
}
Example #2
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;
}