CSR - special modeling case.

--HG--
branch : develop
This commit is contained in:
Roman Telezhynskyi 2017-11-13 10:53:27 +02:00
parent 238e6fb24b
commit 132b7c9fc6
5 changed files with 119 additions and 1 deletions

View file

@ -22,6 +22,7 @@
#include "qmuparser.h"
#include <QCoreApplication>
#include <QLineF>
#include <QStaticStringData>
#include <QStringData>
#include <QStringDataPtr>
@ -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

View file

@ -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

View file

@ -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)

View file

@ -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);

View file

@ -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"));