/** * \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; }
void RExporter::exportSpline(const RSpline& spline, double offset) { RLinetypePattern p = getLinetypePattern(); bool continuous = false; if (getEntity() == NULL || !p.isValid() || p.getNumDashes() == 1 || draftMode || screenBasedLinetypes) { continuous = true; } if (!continuous) { p.scale(getPatternFactor()); if (RMath::isNaN(offset)) { double length = spline.getLength(); offset = getPatternOffset(length, p); } exportExplodable(spline, offset); } else { // version <= 3.0.0 was (line interpolation): //exportExplodable(spline, offset); // performance improvement (using real splines): RPainterPath pp; pp.setPen(QPen(Qt::SolidLine)); pp.addSpline(spline); exportPainterPaths(QList<RPainterPath>() << pp); } /* RLinetypePattern p = getLinetypePattern(); p.scale(getPatternFactor()); if (RMath::isNaN(offset)) { double length = spline.getLength(); offset = getPatternOffset(length, p); } double currentOffset = offset; QList<QSharedPointer<RShape> > sub = spline.getExploded(); QList<QSharedPointer<RShape> >::iterator it; for (it=sub.begin(); it!=sub.end(); ++it) { QSharedPointer<RLine> line = (*it).dynamicCast<RLine>(); if (!line.isNull()) { exportLine(*line.data(), currentOffset); currentOffset -= line->getLength(); } QSharedPointer<RArc> arc = (*it).dynamicCast<RArc>(); if (!arc.isNull()) { exportArc(*arc.data(), currentOffset); currentOffset -= arc->getLength(); } } */ }
void RExporter::exportSpline(const RSpline& spline, double offset) { RLinetypePattern p = getLinetypePattern(); bool continuous = false; if (getEntity() == NULL || !p.isValid() || p.getNumDashes() <= 1 || draftMode || screenBasedLinetypes || twoColorSelectedMode) { continuous = true; } p.scale(getLineTypePatternScale(p)); double patternLength = p.getPatternLength(); if (patternLength<RS::PointTolerance || spline.getLength() / patternLength > RSettings::getDashThreshold()) { continuous = true; } if (!continuous) { if (getEntity()!=NULL && (getEntity()->getType()!=RS::EntitySpline || RSpline::hasProxy())) { // we have a spline proxy: RShapesExporter(*this, QList<QSharedPointer<RShape> >() << QSharedPointer<RShape>(spline.clone()), offset); } else { // fallback if we don't have a spline proxy: p.scale(getLineTypePatternScale(p)); if (RMath::isNaN(offset)) { double length = spline.getLength(); offset = p.getPatternOffset(length); } exportExplodable(spline, offset); } } else { // version <= 3.0.0 was (line interpolation): //exportExplodable(spline, offset); // performance improvement (using real splines): RPainterPath pp; pp.setPen(currentPen); pp.setInheritPen(true); pp.addSpline(spline); exportPainterPaths(QList<RPainterPath>() << pp); } /* RLinetypePattern p = getLinetypePattern(); p.scale(getLineTypePatternScale(p)); if (RMath::isNaN(offset)) { double length = spline.getLength(); offset = p.getPatternOffset(length); } double currentOffset = offset; QList<QSharedPointer<RShape> > sub = spline.getExploded(); QList<QSharedPointer<RShape> >::iterator it; for (it=sub.begin(); it!=sub.end(); ++it) { QSharedPointer<RLine> line = (*it).dynamicCast<RLine>(); if (!line.isNull()) { exportLine(*line.data(), currentOffset); currentOffset -= line->getLength(); } QSharedPointer<RArc> arc = (*it).dynamicCast<RArc>(); if (!arc.isNull()) { exportArc(*arc.data(), currentOffset); currentOffset -= arc->getLength(); } } */ }
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); } } } }