Fixed issue #412. Error in Detail using 'Segment a Simple Curve' tool.

--HG--
branch : develop
This commit is contained in:
Roman Telezhynskyi 2015-12-03 21:56:40 +02:00
parent b431f65ff2
commit ae43c66bd9
6 changed files with 53 additions and 9 deletions

View File

@ -76,7 +76,7 @@ QVector<QPointF> VAbstractCurve::FromBegin(const QVector<QPointF> &points, const
{ {
if (theBegin == false) if (theBegin == false)
{ {
if (IsPointOnLineSegment(begin, points.at(i), points.at(i+1))) if (IsPointOnLineSegment(begin.toPoint(), points.at(i).toPoint(), points.at(i+1).toPoint()))
{ {
theBegin = true; theBegin = true;
segment.append(begin); segment.append(begin);

View File

@ -418,7 +418,7 @@ void VGObject::LineCoefficients(const QLineF &line, qreal *a, qreal *b, qreal *c
* *
* Original idea http://www.sunshine2k.de/coding/java/PointOnLine/PointOnLine.html * Original idea http://www.sunshine2k.de/coding/java/PointOnLine/PointOnLine.html
*/ */
bool VGObject::IsPointOnLineSegment(const QPointF &t, const QPointF &p1, const QPointF &p2) bool VGObject::IsPointOnLineSegment(const QPoint &t, const QPoint &p1, const QPoint &p2)
{ {
// The test point must lie inside the bounding box spanned by the two line points. // The test point must lie inside the bounding box spanned by the two line points.
if (not ( (p1.x() <= t.x() && t.x() <= p2.x()) || (p2.x() <= t.x() && t.x() <= p1.x()) )) if (not ( (p1.x() <= t.x() && t.x() <= p2.x()) || (p2.x() <= t.x() && t.x() <= p1.x()) ))
@ -443,7 +443,7 @@ bool VGObject::IsPointOnLineSegment(const QPointF &t, const QPointF &p1, const Q
* *
* The pdp is zero only if the t lies on the line e1 = vector from p1 to p2. * The pdp is zero only if the t lies on the line e1 = vector from p1 to p2.
*/ */
bool VGObject::IsPointOnLineviaPDP(const QPointF &t, const QPointF &p1, const QPointF &p2) bool VGObject::IsPointOnLineviaPDP(const QPoint &t, const QPoint &p1, const QPoint &p2)
{ {
return ( qAbs(PerpDotProduct(p1, p2, t) < GetEpsilon(p1, p2)) ); return ( qAbs(PerpDotProduct(p1, p2, t) < GetEpsilon(p1, p2)) );
} }
@ -454,7 +454,7 @@ bool VGObject::IsPointOnLineviaPDP(const QPointF &t, const QPointF &p1, const QP
* This is actually the same as the area of the triangle defined by the three points, multiplied by 2. * This is actually the same as the area of the triangle defined by the three points, multiplied by 2.
* @return 2 * triangleArea(a,b,c) * @return 2 * triangleArea(a,b,c)
*/ */
double VGObject::PerpDotProduct(const QPointF &t, const QPointF &p1, const QPointF &p2) double VGObject::PerpDotProduct(const QPoint &t, const QPoint &p1, const QPoint &p2)
{ {
return (p1.x() - t.x()) * (p2.y() - t.y()) - (p1.y() - t.y()) * (p2.x() - t.x()); return (p1.x() - t.x()) * (p2.y() - t.y()) - (p1.y() - t.y()) * (p2.x() - t.x());
} }

View File

@ -37,6 +37,7 @@
class VGObjectData; class VGObjectData;
class QLineF; class QLineF;
class QPoint;
class QPointF; class QPointF;
class QRectF; class QRectF;
@ -81,15 +82,15 @@ public:
static QPointF ClosestPoint(const QLineF &line, const QPointF &point); static QPointF ClosestPoint(const QLineF &line, const QPointF &point);
static QPointF addVector (const QPointF &p, const QPointF &p1, const QPointF &p2, qreal k); static QPointF addVector (const QPointF &p, const QPointF &p1, const QPointF &p2, qreal k);
static void LineCoefficients(const QLineF &line, qreal *a, qreal *b, qreal *c); static void LineCoefficients(const QLineF &line, qreal *a, qreal *b, qreal *c);
static bool IsPointOnLineSegment (const QPointF &t, const QPointF &p1, const QPointF &p2); static bool IsPointOnLineSegment (const QPoint &t, const QPoint &p1, const QPoint &p2);
static QVector<QPointF> GetReversePoints(const QVector<QPointF> &points); static QVector<QPointF> GetReversePoints(const QVector<QPointF> &points);
static int GetLengthContour(const QVector<QPointF> &contour, const QVector<QPointF> &newPoints); static int GetLengthContour(const QVector<QPointF> &contour, const QVector<QPointF> &newPoints);
private: private:
QSharedDataPointer<VGObjectData> d; QSharedDataPointer<VGObjectData> d;
static bool IsPointOnLineviaPDP(const QPointF &t, const QPointF &p1, const QPointF &p2); static bool IsPointOnLineviaPDP(const QPoint &t, const QPoint &p1, const QPoint &p2);
static double PerpDotProduct(const QPointF &t, const QPointF &p1, const QPointF &p2); static double PerpDotProduct(const QPoint &t, const QPoint &p1, const QPoint &p2);
static double GetEpsilon(const QPointF &p1, const QPointF &p2); static double GetEpsilon(const QPointF &p1, const QPointF &p2);
static int PointInCircle (const QPointF &p, const QPointF &center, qreal radius); static int PointInCircle (const QPointF &p, const QPointF &center, qreal radius);

View File

@ -101,8 +101,10 @@ QPointF VToolPointOfContact::FindPoint(const qreal &radius, const QPointF &cente
break; break;
case 2: case 2:
{ {
const bool flagP1 = VGObject::IsPointOnLineSegment (p1, firstPoint, secondPoint); const bool flagP1 = VGObject::IsPointOnLineSegment (p1.toPoint(), firstPoint.toPoint(),
const bool flagP2 = VGObject::IsPointOnLineSegment (p2, firstPoint, secondPoint); secondPoint.toPoint());
const bool flagP2 = VGObject::IsPointOnLineSegment (p2.toPoint(), firstPoint.toPoint(),
secondPoint.toPoint());
if ((flagP1 == true && flagP2 == true) || if ((flagP1 == true && flagP2 == true) ||
(flagP1 == false && flagP2 == false)/*In case we have something wrong*/) (flagP1 == false && flagP2 == false)/*In case we have something wrong*/)
{ {

View File

@ -88,3 +88,43 @@ void TST_VSpline::GetSegmentPoints()
// Begin comparison // Begin comparison
Comparison(points, origPoints); Comparison(points, origPoints);
} }
//---------------------------------------------------------------------------------------------------------------------
void TST_VSpline::GetSegmentPoints_issue412()
{
// Input data taken from real case
// See issue #412 https://bitbucket.org/dismine/valentina/issues/412/error-in-detail-using-segment-a-simple
VPointF p1(869.11748031496063, -61.117228346456692, "p1", 5.0000125984251973, 9.9999874015748045);
VPointF p4(491.16472440944887, 316.83552755905515, "p4", 5.0000125984251973, 9.9999874015748045);
VSpline spl(p1, p4, 270, 0, 1, 1, 1);
QPointF begin(869.11748031496063, -61.117228346456692);
QPointF end(758.41768107838425, 206.13572832247544);
QVector<QPointF> points;
points << spl.GetSegmentPoints(begin, end, false);
QVector<QPointF> origPoints;
origPoints.append(QPointF(869.117480315, -61.1172283465));
origPoints.append(QPointF(869.034855699, -51.3519540199));
origPoints.append(QPointF(868.055234051, -32.0262592346));
origPoints.append(QPointF(866.119738229, -12.967761819));
origPoints.append(QPointF(863.252115711, 5.79979075097));
origPoints.append(QPointF(859.476113972, 24.2526509993));
origPoints.append(QPointF(854.815480488, 42.36707145));
origPoints.append(QPointF(849.293962735, 60.1193046272));
origPoints.append(QPointF(842.93530819, 77.4856030548));
origPoints.append(QPointF(835.763264327, 94.4422192569));
origPoints.append(QPointF(827.801578624, 110.965405758));
origPoints.append(QPointF(819.073998555, 127.031415081));
origPoints.append(QPointF(809.604271597, 142.616499751));
origPoints.append(QPointF(799.416145227, 157.696912291));
origPoints.append(QPointF(788.533366919, 172.248905226));
origPoints.append(QPointF(776.97968415, 186.24873108));
origPoints.append(QPointF(764.778844396, 199.672642377));
origPoints.append(QPointF(758.417681078, 206.135728322));
// Begin comparison
Comparison(points, origPoints);
}

View File

@ -41,6 +41,7 @@ signals:
private slots: private slots:
void GetSegmentPoints(); void GetSegmentPoints();
void GetSegmentPoints_issue412();
}; };