From 132b7c9fc64d953699d14b7b079498289d879d86 Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Mon, 13 Nov 2017 10:53:27 +0200 Subject: [PATCH] CSR - special modeling case. --HG-- branch : develop --- src/libs/qmuparser/qmuparser.cpp | 105 +++++++++++++++++++++++++ src/libs/qmuparser/qmuparser.h | 2 + src/libs/vmisc/def.cpp | 6 +- src/libs/vmisc/def.h | 3 + src/libs/vpatterndb/vtranslatevars.cpp | 4 + 5 files changed, 119 insertions(+), 1 deletion(-) diff --git a/src/libs/qmuparser/qmuparser.cpp b/src/libs/qmuparser/qmuparser.cpp index 5254fd941..d7398f581 100644 --- a/src/libs/qmuparser/qmuparser.cpp +++ b/src/libs/qmuparser/qmuparser.cpp @@ -22,6 +22,7 @@ #include "qmuparser.h" #include +#include #include #include #include @@ -32,12 +33,94 @@ #include "qmuparserdef.h" #include "qmuparsererror.h" #include "../vmisc/vmath.h" +#include "../vmisc/def.h" /** * @file * @brief Implementation of the standard floating point QmuParser. */ +namespace +{ +//--------------------------------------------------------------------------------------------------------------------- +/** + * @brief CSR calcs special modeling case. + * According to case we cut a piece on @param length, split up on distance @param split and splited piece rotate on + * angle that will create arc with length @param arcLength. + * @param length length of cut line + * @param split distance between two pieces + * @param arcLength length of arc that create two pieces after rotation + * @return an angle the second piece should be rotated + */ +qreal CSR(qreal length, qreal split, qreal arcLength) +{ + length = qAbs(length); + arcLength = qAbs(arcLength); + + if (qFuzzyIsNull(length) || qFuzzyIsNull(split) || qFuzzyIsNull(arcLength)) + { + return 0; + } + const qreal sign = std::copysign(1.0, split); + + const QLineF line(QPointF(0, 0), QPointF(0, length)); + + QLineF tmp = line; + tmp.setAngle(tmp.angle()+90.0*sign); + tmp.setLength(split); + + QPointF p1 = tmp.p2(); + + tmp = QLineF(QPointF(0, length), QPointF(0, 0)); + tmp.setAngle(tmp.angle()-90.0*sign); + tmp.setLength(split); + + QPointF p2 = tmp.p2(); + + const QLineF line2(p1, p2); + + qreal angle = 180; + qreal arcL = INT_MAX; + do + { + if (arcL > arcLength) + { + angle = angle - angle/2.0; + } + else if (arcL < arcLength) + { + angle = angle + angle/2.0; + } + else + { + return angle; + } + + if (angle < 0 || angle >= 360) + { + return 0; + } + + tmp = line2; + tmp.setAngle(tmp.angle()+angle*sign); + + QPointF crosPoint; + const auto type = line.intersect(tmp, &crosPoint); + if (type == QLineF::NoIntersection) + { + return 0; + } + + QLineF radius(crosPoint, tmp.p2()); + const qreal arcAngle = sign > 0 ? line.angleTo(radius): radius.angleTo(line); + arcL = (M_PI*radius.length())/180.0 * arcAngle; + } + while(qAbs(arcL - arcLength) > (0.5/*mm*/ / 25.4) * PRINTDPI); + + return angle; +} +} + /** * @brief Namespace for mathematical applications. */ @@ -176,6 +259,26 @@ qreal QmuParser::R2CM(qreal v) return Rint(v*10.0)/10.0; } +//--------------------------------------------------------------------------------------------------------------------- +qreal QmuParser::CSRCm(qreal length, qreal split, qreal arcLength) +{ + length = ((length * 10.0) / 25.4) * PRINTDPI; + split = ((split * 10.0) / 25.4) * PRINTDPI; + arcLength = ((arcLength * 10.0) / 25.4) * PRINTDPI; + + return CSR(length, split, arcLength); +} + +//--------------------------------------------------------------------------------------------------------------------- +qreal QmuParser::CSRInch(qreal length, qreal split, qreal arcLength) +{ + length = length * PRINTDPI; + split = split * PRINTDPI; + arcLength = arcLength * PRINTDPI; + + return CSR(length, split, arcLength); +} + //--------------------------------------------------------------------------------------------------------------------- qreal QmuParser::Sign(qreal v) { @@ -372,6 +475,8 @@ void QmuParser::InitFun() DefineFun("sign", Sign); DefineFun("rint", Rint); DefineFun("r2cm", R2CM); + DefineFun("csrCm", CSRCm); + DefineFun("csrInch", CSRInch); DefineFun("abs", Abs); DefineFun("fmod", FMod); // Functions with variable number of arguments diff --git a/src/libs/qmuparser/qmuparser.h b/src/libs/qmuparser/qmuparser.h index 2bfb6a173..3b873b9d4 100644 --- a/src/libs/qmuparser/qmuparser.h +++ b/src/libs/qmuparser/qmuparser.h @@ -85,6 +85,8 @@ namespace qmu static qreal Abs(qreal); static qreal Rint(qreal); static qreal R2CM(qreal); + static qreal CSRCm(qreal length, qreal split, qreal arcLength); + static qreal CSRInch(qreal length, qreal split, qreal arcLength); static qreal Sign(qreal); static qreal FMod(qreal, qreal); // Prefix operators diff --git a/src/libs/vmisc/def.cpp b/src/libs/vmisc/def.cpp index c61b4f61c..7778b1c59 100644 --- a/src/libs/vmisc/def.cpp +++ b/src/libs/vmisc/def.cpp @@ -90,6 +90,8 @@ const QString sqrt_F = QStringLiteral("sqrt"); const QString sign_F = QStringLiteral("sign"); const QString rint_F = QStringLiteral("rint"); const QString r2cm_F = QStringLiteral("r2cm"); +const QString csrCm_F = QStringLiteral("csrCm"); +const QString csrInch_F = QStringLiteral("csrInch"); const QString abs_F = QStringLiteral("abs"); const QString min_F = QStringLiteral("min"); const QString max_F = QStringLiteral("max"); @@ -126,6 +128,8 @@ const QStringList builInFunctions = QStringList() << degTorad_F << sign_F << rint_F << r2cm_F + << csrCm_F + << csrInch_F << abs_F << min_F << max_F @@ -235,7 +239,7 @@ void SetItemOverrideCursor(QGraphicsItem *item, const QString &pixmapPath, int h #endif } -const qreal PrintDPI = 96.0; +const qreal PrintDPI = PRINTDPI; //--------------------------------------------------------------------------------------------------------------------- double ToPixel(double val, const Unit &unit) diff --git a/src/libs/vmisc/def.h b/src/libs/vmisc/def.h index 899ae9f63..b29bfeb89 100644 --- a/src/libs/vmisc/def.h +++ b/src/libs/vmisc/def.h @@ -346,6 +346,8 @@ extern const QString sqrt_F; extern const QString sign_F; extern const QString rint_F; extern const QString r2cm_F; +extern const QString csrCm_F; +extern const QString csrInch_F; extern const QString abs_F; extern const QString min_F; extern const QString max_F; @@ -419,6 +421,7 @@ extern const QString unitPX; void SetItemOverrideCursor(QGraphicsItem *item, const QString & pixmapPath, int hotX = -1, int hotY = -1); +#define PRINTDPI 96.0 extern const qreal PrintDPI; Q_REQUIRED_RESULT double ToPixel(double val, const Unit &unit); diff --git a/src/libs/vpatterndb/vtranslatevars.cpp b/src/libs/vpatterndb/vtranslatevars.cpp index b48f5eaf3..f4fa577ea 100644 --- a/src/libs/vpatterndb/vtranslatevars.cpp +++ b/src/libs/vpatterndb/vtranslatevars.cpp @@ -438,6 +438,10 @@ void VTranslateVars::InitFunctions() functions.insert(sign_F, translate("VTranslateVars", "sign", "sign function -1 if x<0; 1 if x>0")); functions.insert(rint_F, translate("VTranslateVars", "rint", "round to nearest integer")); functions.insert(r2cm_F, translate("VTranslateVars", "r2cm", "round to up to 1 decimal")); + functions.insert(csrCm_F, translate("VTranslateVars", "csrCm", "cut, split and rotate modeling operation. Takes" + " cm units.")); + functions.insert(csrInch_F, translate("VTranslateVars", "csrInch", "cut, split and rotate modeling operation. Takes" + " inch units.")); functions.insert(abs_F, translate("VTranslateVars", "abs", "absolute value")); functions.insert(min_F, translate("VTranslateVars", "min", "min of all arguments")); functions.insert(max_F, translate("VTranslateVars", "max", "max of all arguments"));