Improved calculation arc points.
--HG-- branch : develop
This commit is contained in:
parent
75701f8cad
commit
589bf173ae
|
@ -29,6 +29,7 @@
|
|||
#include "varc.h"
|
||||
#include "varc_p.h"
|
||||
#include "../ifc/ifcdef.h"
|
||||
#include "vspline.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QLineF>
|
||||
|
@ -192,32 +193,68 @@ qreal VArc::AngleArc() const
|
|||
QVector<QPointF> VArc::GetPoints() const
|
||||
{
|
||||
QVector<QPointF> points;
|
||||
qreal i = 0;
|
||||
const qreal angle = AngleArc();
|
||||
const qint32 k = static_cast<qint32>(angle);
|
||||
const qreal s = angle/(k/4); //-V636
|
||||
do
|
||||
QVector<qreal> sectionAngle;
|
||||
|
||||
QPointF pStart;
|
||||
d->isFlipped ? pStart = GetP2() : pStart = GetP1();
|
||||
|
||||
{
|
||||
QPointF pStart;
|
||||
if (d->isFlipped)
|
||||
qreal angle = AngleArc();
|
||||
|
||||
if (qFuzzyIsNull(angle))
|
||||
{
|
||||
pStart = GetP2();
|
||||
points.append(pStart);
|
||||
return points;
|
||||
}
|
||||
else
|
||||
|
||||
if (angle > 360 || angle < 0)
|
||||
{// Filter incorect value
|
||||
QLineF dummy(0,0, 100, 0);
|
||||
dummy.setAngle(angle);
|
||||
angle = dummy.angle();
|
||||
}
|
||||
|
||||
const qreal angleInterpolation = 45; //degree
|
||||
const int sections = qFloor(angle / angleInterpolation);
|
||||
for (int i = 0; i < sections; ++i)
|
||||
{
|
||||
pStart = GetP1();
|
||||
sectionAngle.append(angleInterpolation);
|
||||
}
|
||||
QLineF line(d->center.toQPointF(), pStart);
|
||||
line.setAngle(line.angle()+i);
|
||||
points.append(line.p2());
|
||||
i = i + s;
|
||||
if (i > angle)
|
||||
|
||||
const qreal tail = angle - sections * angleInterpolation;
|
||||
if (tail > 0)
|
||||
{
|
||||
QLineF line(d->center.toQPointF(), pStart);
|
||||
line.setAngle(line.angle()+angle);
|
||||
points.append(line.p2());
|
||||
sectionAngle.append(tail);
|
||||
}
|
||||
} while (i <= angle);
|
||||
}
|
||||
|
||||
for (int i = 0; i < sectionAngle.size(); ++i)
|
||||
{
|
||||
const qreal lDistance = GetRadius() * 4.0/3.0 * qTan(M_PI/180.0 * sectionAngle.at(i) * 0.25);
|
||||
|
||||
const QPointF center = GetCenter().toQPointF();
|
||||
|
||||
QLineF lineP1P2(pStart, center);
|
||||
lineP1P2.setAngle(lineP1P2.angle() - 90.0);
|
||||
lineP1P2.setLength(lDistance);
|
||||
|
||||
QLineF lineP4P3(center, pStart);
|
||||
lineP4P3.setAngle(lineP4P3.angle() + sectionAngle.at(i));
|
||||
lineP4P3.setLength(GetRadius());//in case of computing error
|
||||
lineP4P3 = QLineF(lineP4P3.p2(), center);
|
||||
lineP4P3.setAngle(lineP4P3.angle() + 90.0);
|
||||
lineP4P3.setLength(lDistance);
|
||||
|
||||
VSpline spl(VPointF(pStart), lineP1P2.p2(), lineP4P3.p2(), VPointF(lineP4P3.p1()), 1.0);
|
||||
QVector<QPointF> splPoints = spl.GetPoints();
|
||||
if (not splPoints.isEmpty() && i != sectionAngle.size() - 1)
|
||||
{
|
||||
splPoints.removeLast();
|
||||
}
|
||||
|
||||
points << splPoints;
|
||||
pStart = lineP4P3.p1();
|
||||
}
|
||||
return points;
|
||||
}
|
||||
|
||||
|
|
|
@ -89,91 +89,78 @@ void TST_VArc::TestGetPoints_data()
|
|||
QTest::newRow("Full circle: radius 1500") << 1500.0 << 0.0 << 360.0;
|
||||
QTest::newRow("Full circle: radius 50000") << 50000.0 << 0.0 << 360.0;
|
||||
QTest::newRow("Full circle: radius 90000") << 90000.0 << 0.0 << 360.0;
|
||||
QTest::newRow("Full circle: radius 900000") << 900000.0 << 0.0 << 360.0;
|
||||
|
||||
QTest::newRow("Arc less than 45 degree, radius 100") << 100.0 << 0.0 << 10.5;
|
||||
QTest::newRow("Arc less than 45 degree, radius 150") << 150.0 << 0.0 << 10.5;
|
||||
QTest::newRow("Arc less than 45 degree, radius 1500") << 1500.0 << 0.0 << 10.5;
|
||||
QTest::newRow("Arc less than 45 degree, radius 50000") << 50000.0 << 0.0 << 10.5;
|
||||
QTest::newRow("Arc less than 45 degree, radius 90000") << 90000.0 << 0.0 << 10.5;
|
||||
QTest::newRow("Arc less than 45 degree, radius 900000") << 900000.0 << 0.0 << 10.5;
|
||||
|
||||
QTest::newRow("Arc 45 degree, radius 100") << 100.0 << 0.0 << 45.0;
|
||||
QTest::newRow("Arc 45 degree, radius 150") << 150.0 << 0.0 << 45.0;
|
||||
QTest::newRow("Arc 45 degree, radius 1500") << 1500.0 << 0.0 << 45.0;
|
||||
QTest::newRow("Arc 45 degree, radius 50000") << 50000.0 << 0.0 << 45.0;
|
||||
QTest::newRow("Arc 45 degree, radius 90000") << 90000.0 << 0.0 << 45.0;
|
||||
QTest::newRow("Arc 45 degree, radius 900000") << 900000.0 << 0.0 << 45.0;
|
||||
|
||||
QTest::newRow("Arc less than 90 degree, radius 100") << 100.0 << 0.0 << 75.0;
|
||||
QTest::newRow("Arc less than 90 degree, radius 150") << 150.0 << 0.0 << 75.0;
|
||||
QTest::newRow("Arc less than 90 degree, radius 1500") << 1500.0 << 0.0 << 75.0;
|
||||
QTest::newRow("Arc less than 90 degree, radius 50000") << 50000.0 << 0.0 << 75.0;
|
||||
QTest::newRow("Arc less than 90 degree, radius 90000") << 90000.0 << 0.0 << 75.0;
|
||||
QTest::newRow("Arc less than 90 degree, radius 900000") << 900000.0 << 0.0 << 75.0;
|
||||
|
||||
QTest::newRow("Arc 90 degree, radius 100") << 100.0 << 0.0 << 90.0;
|
||||
QTest::newRow("Arc 90 degree, radius 150") << 150.0 << 0.0 << 90.0;
|
||||
QTest::newRow("Arc 90 degree, radius 1500") << 1500.0 << 0.0 << 90.0;
|
||||
QTest::newRow("Arc 90 degree, radius 50000") << 50000.0 << 0.0 << 90.0;
|
||||
QTest::newRow("Arc 90 degree, radius 90000") << 90000.0 << 0.0 << 90.0;
|
||||
QTest::newRow("Arc 90 degree, radius 900000") << 900000.0 << 0.0 << 90.0;
|
||||
|
||||
QTest::newRow("Arc less than 135 degree, radius 100") << 100.0 << 0.0 << 110.6;
|
||||
QTest::newRow("Arc less than 135 degree, radius 150") << 150.0 << 0.0 << 110.6;
|
||||
QTest::newRow("Arc less than 135 degree, radius 1500") << 1500.0 << 0.0 << 110.6;
|
||||
QTest::newRow("Arc less than 135 degree, radius 50000") << 50000.0 << 0.0 << 110.6;
|
||||
QTest::newRow("Arc less than 135 degree, radius 90000") << 90000.0 << 0.0 << 110.6;
|
||||
QTest::newRow("Arc less than 135 degree, radius 900000") << 900000.0 << 0.0 << 110.6;
|
||||
|
||||
QTest::newRow("Arc 135 degree, radius 100") << 100.0 << 0.0 << 135.0;
|
||||
QTest::newRow("Arc 135 degree, radius 150") << 150.0 << 0.0 << 135.0;
|
||||
QTest::newRow("Arc 135 degree, radius 1500") << 1500.0 << 0.0 << 135.0;
|
||||
QTest::newRow("Arc 135 degree, radius 50000") << 50000.0 << 0.0 << 135.0;
|
||||
QTest::newRow("Arc 135 degree, radius 90000") << 90000.0 << 0.0 << 135.0;
|
||||
QTest::newRow("Arc 135 degree, radius 900000") << 900000.0 << 0.0 << 135.0;
|
||||
|
||||
QTest::newRow("Arc less than 180 degree, radius 100") << 100.0 << 0.0 << 160.7;
|
||||
QTest::newRow("Arc less than 180 degree, radius 150") << 150.0 << 0.0 << 160.7;
|
||||
QTest::newRow("Arc less than 180 degree, radius 1500") << 1500.0 << 0.0 << 160.7;
|
||||
QTest::newRow("Arc less than 180 degree, radius 50000") << 50000.0 << 0.0 << 160.7;
|
||||
QTest::newRow("Arc less than 180 degree, radius 90000") << 90000.0 << 0.0 << 160.7;
|
||||
QTest::newRow("Arc less than 180 degree, radius 900000") << 900000.0 << 0.0 << 160.7;
|
||||
|
||||
QTest::newRow("Arc 180 degree, radius 100") << 100.0 << 0.0 << 180.0;
|
||||
QTest::newRow("Arc 180 degree, radius 150") << 150.0 << 0.0 << 180.0;
|
||||
QTest::newRow("Arc 180 degree, radius 1500") << 1500.0 << 0.0 << 180.0;
|
||||
QTest::newRow("Arc 180 degree, radius 50000") << 50000.0 << 0.0 << 180.0;
|
||||
QTest::newRow("Arc 180 degree, radius 90000") << 90000.0 << 0.0 << 180.0;
|
||||
QTest::newRow("Arc 180 degree, radius 900000") << 900000.0 << 0.0 << 180.0;
|
||||
|
||||
QTest::newRow("Arc less than 270 degree, radius 100") << 100.0 << 0.0 << 150.3;
|
||||
QTest::newRow("Arc less than 270 degree, radius 150") << 150.0 << 0.0 << 150.3;
|
||||
QTest::newRow("Arc less than 270 degree, radius 1500") << 1500.0 << 0.0 << 150.3;
|
||||
QTest::newRow("Arc less than 270 degree, radius 50000") << 50000.0 << 0.0 << 150.3;
|
||||
QTest::newRow("Arc less than 270 degree, radius 90000") << 90000.0 << 0.0 << 150.3;
|
||||
QTest::newRow("Arc less than 270 degree, radius 900000") << 900000.0 << 0.0 << 150.3;
|
||||
|
||||
QTest::newRow("Arc 270 degree, radius 100") << 100.0 << 0.0 << 270.0;
|
||||
QTest::newRow("Arc 270 degree, radius 150") << 150.0 << 0.0 << 270.0;
|
||||
QTest::newRow("Arc 270 degree, radius 1500") << 1500.0 << 0.0 << 270.0;
|
||||
QTest::newRow("Arc 270 degree, radius 50000") << 50000.0 << 0.0 << 270.0;
|
||||
QTest::newRow("Arc 270 degree, radius 90000") << 90000.0 << 0.0 << 270.0;
|
||||
QTest::newRow("Arc 270 degree, radius 900000") << 900000.0 << 0.0 << 270.0;
|
||||
|
||||
QTest::newRow("Arc less than 360 degree, radius 100") << 100.0 << 0.0 << 340.0;
|
||||
QTest::newRow("Arc less than 360 degree, radius 150") << 150.0 << 0.0 << 340.0;
|
||||
QTest::newRow("Arc less than 360 degree, radius 1500") << 1500.0 << 0.0 << 340.0;
|
||||
QTest::newRow("Arc less than 360 degree, radius 50000") << 50000.0 << 0.0 << 340.0;
|
||||
QTest::newRow("Arc less than 360 degree, radius 90000") << 90000.0 << 0.0 << 340.0;
|
||||
QTest::newRow("Arc less than 360 degree, radius 900000") << 900000.0 << 0.0 << 340.0;
|
||||
|
||||
QTest::newRow("Arc start 90 degree, angle 45 degree, radius 100") << 100.0 << 90.0 << 135.0;
|
||||
QTest::newRow("Arc start 90 degree, angle 45 degree, radius 150") << 150.0 << 90.0 << 135.0;
|
||||
QTest::newRow("Arc start 90 degree, angle 45 degree, radius 1500") << 1500.0 << 90.0 << 135.0;
|
||||
QTest::newRow("Arc start 90 degree, angle 45 degree, radius 50000") << 50000.0 << 90.0 << 135.0;
|
||||
QTest::newRow("Arc start 90 degree, angle 45 degree, radius 90000") << 90000.0 << 90.0 << 135.0;
|
||||
QTest::newRow("Arc start 90 degree, angle 45 degree, radius 900000") << 900000.0 << 90.0 << 135.0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -190,13 +177,15 @@ void TST_VArc::TestGetPoints()
|
|||
QVector<QPointF> points = arc.GetPoints();
|
||||
|
||||
{
|
||||
const qreal epsRadius = 1.0; // computing error
|
||||
const qreal epsRadius = 1.5; // computing error
|
||||
|
||||
for (int i=0; i < points.size(); ++i)
|
||||
{
|
||||
QLineF rLine(center.toQPointF(), points.at(i));
|
||||
QVERIFY2(qAbs(rLine.length() - radius) <= epsRadius,
|
||||
"Broken the first rule. All points should be on the same distance from the center.");
|
||||
const qreal value = qAbs(rLine.length() - radius);
|
||||
const QString errorMsg = QString("Broken the first rule. All points should be on the same distance from "
|
||||
"the center. Error ='%1'.").arg(value);
|
||||
QVERIFY2(value <= epsRadius, qUtf8Printable(errorMsg));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -214,11 +203,11 @@ void TST_VArc::TestGetPoints()
|
|||
}
|
||||
|
||||
// calculated squere
|
||||
qreal cSquare = qAbs(VAbstractDetail::SumTrapezoids(points)/2.0);
|
||||
const qreal cSquare = qAbs(VAbstractDetail::SumTrapezoids(points)/2.0);
|
||||
const qreal value = qAbs(gSquere - cSquare);
|
||||
const QString errorMsg =
|
||||
QString("Broken the second rule. Interpolation has too big computing error. Error ='%1'.").arg(value);
|
||||
const qreal epsSquere = 1.0; // computing error
|
||||
const qreal epsSquere = gSquere * 0.24 / 100; // computing error 0.24 % from origin squere
|
||||
QVERIFY2(value <= epsSquere, qUtf8Printable(errorMsg));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user