コード例 #1
0
ファイル: RArc.cpp プロジェクト: Alpha-Kand/qcad
/**
 * Creates an arc from 3 points.
 */
RArc RArc::createFrom3Points(const RVector& startPoint,
                              const RVector& point,
                              const RVector& endPoint) {
    // intersection of two middle lines

    // middle points between first two points:
    RVector mp1 = RVector::getAverage(startPoint, point);
    double a1 = startPoint.getAngleTo(point) + M_PI / 2.0;
    // direction from middle point to center:
    RVector dir1 = RVector::createPolar(1.0, a1);

    // middle points between last two points:
    RVector mp2 = RVector::getAverage(point, endPoint);
    double a2 = point.getAngleTo(endPoint) + M_PI / 2.0;
    // direction from middle point to center:
    RVector dir2 = RVector::createPolar(1.0, a2);

    RLine midLine1(mp1, mp1 + dir1);
    RLine midLine2(mp2, mp2 + dir2);

    QList<RVector> ips = midLine1.getIntersectionPoints(midLine2, false);
    if (ips.length()!=1) {
        //this.error = qsTr("No arc possible");
        return RArc();
    }

    RVector center = ips[0];
    double radius = center.getDistanceTo(endPoint);
    double angle1 = center.getAngleTo(startPoint);
    double angle2 = center.getAngleTo(endPoint);
    bool reversed = RMath::isAngleBetween(center.getAngleTo(point),
                                            angle1, angle2, true);

    return RArc(center, radius, angle1, angle2, reversed);
}
コード例 #2
0
ファイル: RExporter.cpp プロジェクト: DanielJSlick/qcad
void RExporter::exportArc(const RArc& arc, double offset) {
    if (!arc.isValid()) {
        return;
    }

    RLinetypePattern p = getLinetypePattern();

    if (getEntity() == NULL || !p.isValid() || p.getNumDashes() == 1 || draftMode || screenBasedLinetypes) {
        exportArcSegment(arc);
        return;
    }

    RArc normalArc = arc;
    if (arc.isReversed()) {
        normalArc.reverse();
    }

    if (normalArc.radius < 1.0e-12) {
        return;
    }

    p.scale(getPatternFactor());

    double length = normalArc.getLength();
    double patternLength = p.getPatternLength();

    // avoid huge number of small segments due to very fine 
    // pattern or long lines:
    if (patternLength<RS::PointTolerance || length / patternLength > 5000) {
        exportArcSegment(arc);
        return;
    }

    double* vp = NULL;
    vp = new double[p.getNumDashes()];
    for (int i = 0; i < p.getNumDashes(); ++i) {
        vp[i] = fabs(p.getDashLengthAt(i)) / normalArc.radius;
    }

    if (RMath::isNaN(offset)) {
        offset = getPatternOffset(length, p);
    }

    QList<RArc> arcSegments;
    bool done = false;
    int i = 0;
    double cursor = normalArc.getStartAngle() + offset / normalArc.radius;
    double total = offset;
    bool dashFound = false;
    bool gapFound = false;
    double a1 = normalArc.getStartAngle();
    double a2;
    do {
        if (dashFound && !gapFound) {
            if (total + fabs(p.getDashLengthAt(i)) >= length - 1.0e-6) {
                arcSegments.append(RArc(normalArc.getCenter(), normalArc.getRadius(), a1, normalArc.getEndAngle()));
                break;
            }
            arcSegments.append(RArc(normalArc.getCenter(), normalArc.getRadius(), a1, a2));
        }
        if (p.getDashLengthAt(i) > 0) {
            // dash, no gap
            if (total + p.getDashLengthAt(i) > 0) {
                a1 = cursor;
                if (total < 0 || !dashFound) {
                    a1 = normalArc.startAngle;
                }
                a2 = cursor + vp[i];
                if (fabs(a2 - normalArc.getStartAngle()) > 1.0e-6) {
                    dashFound = true;
                }
            }
            gapFound = false;
        } else {
            gapFound = true;
        }
        cursor += vp[i];
        total += fabs(p.getDashLengthAt(i));
        done = total > length;
        ++i;
        if (i >= p.getNumDashes()) {
            i = 0;
        }
    } while (!done);

    if (!gapFound || !dashFound) {
        if (total + fabs(p.getDashLengthAt(i)) >= length - 1.0e-6) {
            arcSegments.append(RArc(normalArc.getCenter(), normalArc.getRadius(), a1, normalArc.getEndAngle()));
        } else {
            arcSegments.append(RArc(normalArc.getCenter(), normalArc.getRadius(), a1, a2));
        }
    }

    if (arc.isReversed()) {
        for (int i=arcSegments.length()-1; i>=0; i--) {
            arcSegments[i].reverse();
            exportArcSegment(arcSegments[i]);
        }
    }
    else {
        for (int i=0; i<arcSegments.length(); i++) {
            exportArcSegment(arcSegments[i]);
        }
    }

    delete[] vp;
}