Ejemplo n.º 1
0
bool RPolylineData::moveReferencePoint(const RVector& referencePoint,
        const RVector& targetPoint) {
    bool ret = false;

    QList<RVector>::iterator it;
    for (it=vertices.begin(); it!=vertices.end(); ++it) {
        if (referencePoint.equalsFuzzy(*it)) {
            (*it) = targetPoint;
            ret = true;
        }
    }

    for (int i=0; i<countSegments(); i++) {
        if (isArcSegmentAt(i)) {
            QSharedPointer<RArc> arc = getSegmentAt(i).dynamicCast<RArc>();
            if (!arc.isNull()) {
                if (referencePoint.equalsFuzzy(arc->getMiddlePoint())) {
                    RArc a = RArc::createFrom3Points(arc->getStartPoint(), targetPoint, arc->getEndPoint());
                    setBulgeAt(i, a.getBulge());
                    ret = true;
                }
            }
        }
    }

    return ret;
}
Ejemplo n.º 2
0
void RArcEntity::setShape(const RArc& a) {
    data.setCenter(a.getCenter());
    data.setRadius(a.getRadius());
    data.setStartAngle(a.getStartAngle());
    data.setEndAngle(a.getEndAngle());
    data.setReversed(a.isReversed());
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
RArc RArc::createTangential(const RVector& startPoint, const RVector& pos,
                            double direction, double radius) {
    RArc arc;

    arc.radius = radius;

    // orthogonal to base entity:
    RVector ortho;
    ortho.setPolar(radius, direction + M_PI/2.0);

    // two possible center points for arc:
    RVector center1 = startPoint + ortho;
    RVector center2 = startPoint - ortho;
    if (center1.getDistanceTo(pos) < center2.getDistanceTo(pos)) {
        arc.center = center1;
    } else {
        arc.center = center2;
    }

    // angles:
    arc.startAngle = arc.center.getAngleTo(startPoint);
    arc.endAngle = arc.center.getAngleTo(pos);

    // handle arc direction:
    arc.reversed = false;
    double diff = RMath::getNormalizedAngle(arc.getDirection1() - direction);
    if (fabs(diff-M_PI) < 1.0e-1) {
        arc.reversed = true;
    }

    return arc;
}
Ejemplo n.º 5
0
QList<RVector> RShape::getIntersectionPointsAT(const RArc& arc1,
            const RTriangle& triangle2, bool limited) {

    Q_UNUSED(limited)

    RTriangle plane(arc1.getCenter(), arc1.getStartPoint(), arc1.getEndPoint());
    QList<RVector> r = plane.getIntersectionPoints(RLine(triangle2.getCorner(0), triangle2.getCorner(1)));
    r.append(plane.getIntersectionPoints(RLine(triangle2.getCorner(1), triangle2.getCorner(2))));
    r.append(plane.getIntersectionPoints(RLine(triangle2.getCorner(2), triangle2.getCorner(0))));
    if (r.size()<2) {
        return QList<RVector>();
    }

    RLine l(r[0], r[1]);
    return l.getIntersectionPoints(arc1);
}
Ejemplo n.º 6
0
QList<RVector> RShape::getIntersectionPointsAC(const RArc& arc1,
        const RCircle& circle2, bool limited) {
    QList<RVector> candidates =
            RShape::getIntersectionPoints(
                RCircle(arc1.getCenter(), arc1.getRadius()),
                circle2
            );
    if (!limited) {
        return candidates;
    }

    QList<RVector> res;

    for (int i=0; i<candidates.count(); i++) {
         if (arc1.isOnShape(candidates[i])) {
             res.append(candidates[i]);
         }
    }
    // ret.setTangent(tangent);

    return res;
}
Ejemplo n.º 7
0
QList<RVector> RShape::getIntersectionPointsLA(const RLine& line1,
        const RArc& arc2, bool limited1, bool limited2) {

    QList<RVector> candidates =
            RShape::getIntersectionPointsLC(
                line1, RCircle(arc2.getCenter(), arc2.getRadius()), limited1
            );
    if (!limited2) {
        return candidates;
    }

    QList<RVector> res;

    for (int i=0; i<candidates.count(); i++) {
         if (arc2.isOnShape(candidates[i])) {
             res.append(candidates[i]);
         }
    }
    // ret.setTangent(tangent);

    return res;
}
Ejemplo n.º 8
0
/**
 *  \return List of splines which approximate the given arc.
 */
QList<RSpline> RSpline::createSplinesFromArc(const RArc& arc) {
    RArc a = arc;
    if (a.isReversed()) {
        a.reverse();
    }

    double startAngle = RMath::getNormalizedAngle(a.getStartAngle());
    double endAngle = RMath::getNormalizedAngle(a.getEndAngle());
    if (a.isFullCircle()) {
        startAngle = 0.0;
        endAngle = 2*M_PI;
    }

    // normalize startAngle, endAngle to [-2PI, 2PI]
    double twoPI = M_PI * 2;
    //double startAngle = RMath::getNormalizedAngle(a.getStartAngle());
    //double endAngle = RMath::getNormalizedAngle(a.getEndAngle());
    if (startAngle>endAngle) {
        startAngle-=2*M_PI;
    }
    double radius = a.getRadius();
    double EPSILON = 0.00001;

    // Compute the sequence of arc curves, up to PI/2 at a time.  Total arc angle
    // is less than 2PI.

    QList<RSpline> curves;

    double piOverTwo = M_PI_2;
    double segmentationAngle = piOverTwo/4;
    //double segmentationAngle = M_PI/8;
    double sgn = (startAngle < endAngle) ? +1 : -1;

    double a1 = startAngle;
    for (double totalAngle = qMin(twoPI, qAbs(endAngle - startAngle)); totalAngle > EPSILON; ) {
        double a2 = a1 + sgn * qMin(totalAngle, segmentationAngle);
        RSpline sp = RSpline::createBezierFromSmallArc(radius, a1, a2);
        sp.move(a.getCenter());
        curves.append(sp);
        totalAngle -= qAbs(a2 - a1);
        a1 = a2;
    }

    return curves;
}
Ejemplo n.º 9
0
void RExporter::exportArcSegment(const RArc& arc) {
    double segmentLength;
    if (pixelSizeHint>0.0) {
        // approximate arc with segments with the length of 2 pixels:
        segmentLength = pixelSizeHint * 2;
    }
    else {
        segmentLength = arc.getRadius() / 40.0;
    }

    // avoid a segment length of 0:
    if (segmentLength<1.0e-4) {
        segmentLength = 1.0e-4;
    }

    double a1 = arc.getStartAngle();
    double a2 = arc.getEndAngle();
    RVector center = arc.getCenter();
    double radius = arc.getRadius();
    // avoid huge radius and slow down to almost stand-still:
    if (radius>1.0e6) {
        return;
    }

    double aStep;
    if (radius<1.0e-3) {
        aStep = 0.1;
    }
    else {
        aStep = segmentLength / radius;
        if (aStep>1.0) {
            aStep = 1.0;
        }
        double minAStep = 2*M_PI/360.0;
        if (!draftMode) {
            minAStep /= 4;
        }

        if (aStep<minAStep) {
            aStep = minAStep;
        }
    }
    RVector prev = arc.getStartPoint();
    RVector ci;
    double a;

    if(!arc.isReversed()) {
        // Arc Counterclockwise:
        if(a1>a2-RS::AngleTolerance) {
            a2+=2*M_PI;
        }
        for(a=a1+aStep; a<=a2; a+=aStep) {
            ci.x = center.x + cos(a) * radius;
            ci.y = center.y + sin(a) * radius;
            //path.lineTo(RVector(ci.x, ci.y));
            this->exportLineSegment(RLine(prev, ci));
            prev = ci;
        }
    } else {
        // Arc Clockwise:
        if(a1<a2+RS::AngleTolerance) {
            a2-=2*M_PI;
        }
        for(a=a1-aStep; a>=a2; a-=aStep) {
            ci.x = center.x + cos(a) * radius;
            ci.y = center.y + sin(a) * radius;
            this->exportLineSegment(RLine(prev, ci));
            //path.lineTo(RVector(cix, ciy));
            prev = ci;
        }
    }
    this->exportLineSegment(RLine(prev, arc.getEndPoint()));
    //path.lineTo(arc.getEndPoint());
}
Ejemplo n.º 10
0
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;
}
Ejemplo n.º 11
0
void RExporter::exportArc(const RArc& arc, double offset) {
    if (!arc.isValid()) {
        return;
    }

    if (getEntity() == NULL || draftMode || screenBasedLinetypes || twoColorSelectedMode) {
        exportArcSegment(arc);
        return;
    }

    RLinetypePattern p = getLinetypePattern();
    if (!p.isValid() || p.getNumDashes() <= 1) {
        exportArcSegment(arc);
        return;
    }

    p.scale(getLineTypePatternScale(p));
    double patternLength = p.getPatternLength();
    if (patternLength<RS::PointTolerance || arc.getLength() / patternLength > RSettings::getDashThreshold()) {
        exportArcSegment(arc);
        return;
    }

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

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

    RArcExporter(*this, arc, offset);

    /*
    p.scale(getLineTypePatternScale(p));

    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;
    }

    //bool optimizeEnds = false;
    if (RMath::isNaN(offset)) {
        offset = p.getPatternOffset(length);
        //optimizeEnds = true;
    }

    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 = 0.0;
    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.0) {
            // dash, no gap
            if (total + p.getDashLengthAt(i) >= 0.0) {
                a1 = cursor;
                if (total < 0.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;

        if (!done && total>0.0) {
            // handle shape at end of dash / gap:
            if (p.hasShapeAt(i)) {
                QList<RPainterPath> pps = p.getShapeAt(i);
//                RVector min = RPainterPath::getMinList(pps);
//                RVector max = RPainterPath::getMaxList(pps);
                RPainterPath::rotateList(pps, cursor+M_PI/2);
                RPainterPath::translateList(pps, normalArc.getPointAtAngle(cursor));
                exportPainterPaths(pps);
            }
        }

        ++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], true);
        }
    }
    else {
        for (int i=0; i<arcSegments.length(); i++) {
            exportArcSegment(arcSegments[i], true);
        }
    }

    delete[] vp;
    */
}
Ejemplo n.º 12
0
void RExporter::exportArcSegment(const RArc& arc, bool allowForZeroLength) {
    if (allowForZeroLength && arc.isFullCircle()) {
        exportLineSegment(RLine(arc.getStartPoint(), arc.getEndPoint()), arc.getDirection1());
        return;
    }

    double segmentLength;
    if (pixelSizeHint>0.0) {
        // approximate arc with segments with the length of 2 pixels:
        segmentLength = pixelSizeHint * 2;
    }
    else {
        segmentLength = arc.getRadius() / 40.0;
    }

    // avoid a segment length of 0:
    if (segmentLength<1.0e-4) {
        segmentLength = 1.0e-4;
    }

    double a1 = arc.getStartAngle();
    double a2 = arc.getEndAngle();
    RVector center = arc.getCenter();
    double radius = arc.getRadius();

    double aStep;
    if (radius<1.0e-3) {
        aStep = 0.1;
    }
    else {
        aStep = segmentLength / radius;
        if (aStep>1.0) {
            aStep = 1.0;
        }

        double minAStep = RSettings::getMinArcAngleStep();
        if (draftMode) {
            minAStep *= 4;
        }

        if (aStep<minAStep) {
            aStep = minAStep;
        }
    }
    RVector prev = arc.getStartPoint();
    RVector ci;
    double a;

    if (!arc.isReversed()) {
        // Arc Counterclockwise:
        if(a1>a2-RS::AngleTolerance) {
            a2+=2*M_PI;
        }
        for (a=a1+aStep; a<=a2; a+=aStep) {
            ci.x = center.x + cos(a) * radius;
            ci.y = center.y + sin(a) * radius;
            exportLineSegment(RLine(prev, ci), a+M_PI_2);
            prev = ci;
        }
    } else {
        // Arc Clockwise:
        if (a1<a2+RS::AngleTolerance) {
            a2-=2*M_PI;
        }
        for (a=a1-aStep; a>=a2; a-=aStep) {
            ci.x = center.x + cos(a) * radius;
            ci.y = center.y + sin(a) * radius;
            exportLineSegment(RLine(prev, ci), a+M_PI_2);
            prev = ci;
        }
    }
    this->exportLineSegment(RLine(prev, arc.getEndPoint()), arc.getEndAngle()+M_PI_2);
}
Ejemplo n.º 13
0
void RGraphicsSceneQt::exportArcSegment(const RArc& arc, bool allowForZeroLength) {
    Q_ASSERT(currentPainterPath.isValid());

    if (arc.getRadius()<RS::PointTolerance) {
        currentPainterPath.addPoint(arc.getCenter());
        return;
    }

    // arc threshold is configurable (FS#1012):
    if (arc.getAngleLength(allowForZeroLength)<=RSettings::getArcAngleLengthThreshold()) {
        // Qt won't export a zero length line as point:
        RVector startPoint = arc.getStartPoint() - RVector::createPolar(0.01, arc.getStartAngle()+M_PI_2);
        RVector endPoint = arc.getEndPoint() + RVector::createPolar(0.01, arc.getStartAngle()+M_PI_2);
        currentPainterPath.moveTo(startPoint);
        currentPainterPath.lineTo(endPoint);
        return;
    }

    // arc approximation with splines: faster but not precise enough:
//     RPainterPath p;
//     p.addArc(arc);
//     currentPainterPath.addPath(p);

    if (twoColorSelectedMode) {
        // QPainterPath with pattern shown as solid when clipped bug workaround:
        currentPainterPath.moveTo(arc.getStartPoint());
        currentPainterPath.arcTo(
            arc.getCenter().x-arc.getRadius(),
            arc.getCenter().y-arc.getRadius(),
            arc.getRadius()*2, arc.getRadius()*2,
            RMath::rad2deg(-arc.getStartAngle()),
            RMath::rad2deg(-arc.getSweep())
        );
    }
    else {
        currentPainterPath.setAutoRegen(true);
        RGraphicsScene::exportArcSegment(arc, allowForZeroLength);
    }
}
Ejemplo n.º 14
0
void REcmaHelper::fromScriptValue(QScriptEngine* engine, QScriptValue scriptValue, QList<QSharedPointer<RShape> >& cppValue) {
    QVariantList variantList = engine->fromScriptValue<QVariantList>(scriptValue);
    for (int i = 0; i < variantList.size(); ++i) {
        QVariant v = variantList.at(i);
        QSharedPointer<RShape> pShape = v.value<QSharedPointer<RShape> >();
        if (!pShape.isNull()) {
            cppValue.append(pShape);
        }
        else {
            RShape* shape = v.value<RShape*>();
            if (shape!=NULL) {
                QSharedPointer<RShape> pShape(shape->clone());
                cppValue.append(pShape);
            }

            else if (v.canConvert<RArc>()) {
                RArc obj = v.value<RArc>();
                QSharedPointer<RArc> p(obj.clone());
                cppValue.append(p);
            }

            else if (v.canConvert<RCircle>()) {
                RCircle obj = v.value<RCircle>();
                QSharedPointer<RCircle> p(obj.clone());
                cppValue.append(p);
            }

            else if (v.canConvert<RLine>()) {
                RLine obj = v.value<RLine>();
                QSharedPointer<RLine> p(obj.clone());
                cppValue.append(p);
            }

            else if (v.canConvert<RPoint>()) {
                RPoint obj = v.value<RPoint>();
                QSharedPointer<RPoint> p(obj.clone());
                cppValue.append(p);
            }

            else if (v.canConvert<RPolyline>()) {
                RPolyline obj = v.value<RPolyline>();
                QSharedPointer<RPolyline> p(obj.clone());
                cppValue.append(p);
            }

            else if (v.canConvert<RSpline>()) {
                RSpline obj = v.value<RSpline>();
                QSharedPointer<RSpline> p(obj.clone());
                cppValue.append(p);
            }

            else if (v.canConvert<RTextLabel>()) {
                RTextLabel obj = v.value<RTextLabel>();
                QSharedPointer<RTextLabel> p(obj.clone());
                cppValue.append(p);
            }

            else if (v.canConvert<RTriangle>()) {
                RTriangle obj = v.value<RTriangle>();
                QSharedPointer<RTriangle> p(obj.clone());
                cppValue.append(p);
            }
        }
    }
}