Better round points if we want avoid errors. Correct way working with QMatrix in

methods translate and rotate.

--HG--
branch : feature
This commit is contained in:
dismine 2015-01-16 14:54:37 +02:00
parent 3d1100bc3d
commit ab2b894d69
4 changed files with 86 additions and 21 deletions

View File

@ -74,6 +74,8 @@ void VLayoutDetail::SetCountourPoints(const QVector<QPointF> &points)
{ {
d->contour.removeLast(); d->contour.removeLast();
} }
d->contour = RoundPoints(d->contour);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -91,6 +93,8 @@ void VLayoutDetail::SetSeamAllowencePoints(const QVector<QPointF> &points)
{ {
d->seamAllowence.removeLast(); d->seamAllowence.removeLast();
} }
d->seamAllowence = RoundPoints(d->seamAllowence);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -126,15 +130,19 @@ void VLayoutDetail::SetLayoutWidth(const qreal &value)
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VLayoutDetail::Translate(qreal dx, qreal dy) void VLayoutDetail::Translate(qreal dx, qreal dy)
{ {
d->matrix = d->matrix.translate(dx, dy); QMatrix m;
m.translate(dx, dy);
d->matrix *= m;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VLayoutDetail::Rotate(const QPointF &originPoint, qreal degrees) void VLayoutDetail::Rotate(const QPointF &originPoint, qreal degrees)
{ {
Translate(-originPoint.x(), -originPoint.y()); QMatrix m;
d->matrix = d->matrix.rotate(degrees); m.translate(originPoint.x(), originPoint.y());
Translate(originPoint.x(), originPoint.y()); m.rotate(-degrees);
m.translate(-originPoint.x(), -originPoint.y());
d->matrix *= m;
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -148,9 +156,9 @@ void VLayoutDetail::Mirror(const QLineF &edge)
QLineF axis = QLineF(edge.x1(), edge.y1(), 100, edge.y2()); // Ox axis QLineF axis = QLineF(edge.x1(), edge.y1(), 100, edge.y2()); // Ox axis
qreal angle = edge.angleTo(axis); qreal angle = edge.angleTo(axis);
Rotate(edge.p1(), angle); Rotate(edge.p1(), -angle);
d->matrix = d->matrix.scale(d->matrix.m11()*-1, d->matrix.m22()); d->matrix *= d->matrix.scale(d->matrix.m11()*-1, d->matrix.m22());
Rotate(edge.p1(), 360 - angle); Rotate(edge.p1(), 360 + angle);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -286,10 +294,18 @@ void VLayoutDetail::SetLayoutAllowencePoints()
if (getSeamAllowance()) if (getSeamAllowance())
{ {
d->layoutAllowence = Equidistant(d->seamAllowence, EquidistantType::CloseEquidistant, d->layoutWidth); d->layoutAllowence = Equidistant(d->seamAllowence, EquidistantType::CloseEquidistant, d->layoutWidth);
if (d->layoutAllowence.isEmpty() == false)
{
d->layoutAllowence.removeLast();
}
} }
else else
{ {
d->layoutAllowence = Equidistant(d->contour, EquidistantType::CloseEquidistant, d->layoutWidth); d->layoutAllowence = Equidistant(d->contour, EquidistantType::CloseEquidistant, d->layoutWidth);
if (d->layoutAllowence.isEmpty() == false)
{
d->layoutAllowence.removeLast();
}
} }
} }
else else
@ -319,6 +335,17 @@ QVector<QPointF> VLayoutDetail::Map(const QVector<QPointF> &points) const
return p; return p;
} }
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VLayoutDetail::RoundPoints(const QVector<QPointF> &points) const
{
QVector<QPointF> p;
for (int i=0; i < points.size(); ++i)
{
p.append(QPointF(qRound(points.at(i).x()), qRound(points.at(i).y())));
}
return p;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QPainterPath VLayoutDetail::ContourPath() const QPainterPath VLayoutDetail::ContourPath() const
{ {

View File

@ -79,6 +79,7 @@ private:
QSharedDataPointer<VLayoutDetailData> d; QSharedDataPointer<VLayoutDetailData> d;
QVector<QPointF> Map(const QVector<QPointF> &points) const; QVector<QPointF> Map(const QVector<QPointF> &points) const;
QVector<QPointF> RoundPoints(const QVector<QPointF> &points) const;
}; };
#endif // VLAYOUTDETAIL_H #endif // VLAYOUTDETAIL_H

View File

@ -36,6 +36,7 @@
#include <QDir> #include <QDir>
#include <QPainter> #include <QPainter>
#include <QGraphicsItem> #include <QGraphicsItem>
#include <QCoreApplication>
class BestResult class BestResult
{ {
@ -222,6 +223,8 @@ bool VLayoutPaper::AddToBlankSheet(const VLayoutDetail &detail)
{ {
for (int i=1; i<= detail.EdgesCount(); i++) for (int i=1; i<= detail.EdgesCount(); i++)
{ {
QCoreApplication::processEvents();
// We should use copy of the detail. // We should use copy of the detail.
VLayoutDetail workDetail = detail; VLayoutDetail workDetail = detail;
@ -237,8 +240,10 @@ bool VLayoutPaper::AddToBlankSheet(const VLayoutDetail &detail)
} }
d->frame = d->frame + 2; d->frame = d->frame + 2;
for (int angle = 0; angle < 360; ++angle) for (int angle = 0; angle <= 360; ++angle)
{ {
QCoreApplication::processEvents();
// We should use copy of the detail. // We should use copy of the detail.
VLayoutDetail workDetail = detail; VLayoutDetail workDetail = detail;
@ -271,6 +276,8 @@ bool VLayoutPaper::AddToSheet(const VLayoutDetail &detail)
for (int i=1; i<= workDetail.EdgesCount(); i++) for (int i=1; i<= workDetail.EdgesCount(); i++)
{ {
QCoreApplication::processEvents();
int dEdge = i;// For mirror detail edge will be different int dEdge = i;// For mirror detail edge will be different
if (CheckCombineEdges(workDetail, j, dEdge)) if (CheckCombineEdges(workDetail, j, dEdge))
{ {
@ -304,7 +311,7 @@ bool VLayoutPaper::CheckCombineEdges(VLayoutDetail &detail, int j, int &dEdge) c
CombineEdges(detail, globalEdge, dEdge); CombineEdges(detail, globalEdge, dEdge);
#ifdef LAYOUT_DEBUG #ifdef LAYOUT_DEBUG
DrawDebug(detail); DrawDebug(detail, d->frame);
#endif #endif
switch (Crossing(detail, j, dEdge)) switch (Crossing(detail, j, dEdge))
@ -338,6 +345,10 @@ bool VLayoutPaper::CheckCombineEdges(VLayoutDetail &detail, int j, int &dEdge) c
if (flagMirror) if (flagMirror)
{ {
#ifdef LAYOUT_DEBUG
DrawDebug(detail, d->frame+1);
#endif
dEdge = detail.EdgeByPoint(globalEdge.p2()); dEdge = detail.EdgeByPoint(globalEdge.p2());
if (dEdge <= 0) if (dEdge <= 0)
{ {
@ -383,7 +394,7 @@ bool VLayoutPaper::CheckRotationEdges(VLayoutDetail &detail, int j, int dEdge, i
RotateEdges(detail, globalEdge, dEdge, angle); RotateEdges(detail, globalEdge, dEdge, angle);
#ifdef LAYOUT_DEBUG #ifdef LAYOUT_DEBUG
DrawDebug(detail); DrawDebug(detail, d->frame);
#endif #endif
switch (Crossing(detail, j, dEdge)) switch (Crossing(detail, j, dEdge))
@ -536,13 +547,15 @@ void VLayoutPaper::CombineEdges(VLayoutDetail &detail, const QLineF &globalEdge,
const qreal dx = globalEdge.x2() - detailEdge.x2(); const qreal dx = globalEdge.x2() - detailEdge.x2();
const qreal dy = globalEdge.y2() - detailEdge.y2(); const qreal dy = globalEdge.y2() - detailEdge.y2();
// detailEdge = QLineF(detailEdge.x1()+dx, detailEdge.y1()+dy, detailEdge.x2()+dx, detailEdge.y2()+dy);
// angle = detailEdge.angle();
detailEdge.translate(dx, dy); // Use values for translate detail edge. detailEdge.translate(dx, dy); // Use values for translate detail edge.
const qreal angle_between = globalEdge.angleTo(detailEdge); // Seek angle between two edges. const qreal angle_between = globalEdge.angleTo(detailEdge); // Seek angle between two edges.
// Now we move detail to position near to global contour edge. // Now we move detail to position near to global contour edge.
detail.Translate(dx, dy); detail.Translate(dx, dy);
detail.Rotate(globalEdge.p2(), angle_between); detail.Rotate(detailEdge.p2(), -angle_between);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -760,34 +773,46 @@ bool VLayoutPaper::SaveResult(const BestResult &bestResult, const VLayoutDetail
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VLayoutPaper::DrawDebug(const VLayoutDetail &detail) const void VLayoutPaper::DrawDebug(const VLayoutDetail &detail, int frame) const
{ {
QImage frameImage ( d->paperWidth, d->paperHeight, QImage::Format_RGB32 ); QImage frameImage(d->paperWidth*3, d->paperHeight*3, QImage::Format_RGB32);
frameImage.fill(Qt::white); frameImage.fill(Qt::white);
QPainter paint; QPainter paint;
paint.setPen(QPen(Qt::black, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
paint.begin(&frameImage); paint.begin(&frameImage);
paint.setPen(QPen(Qt::darkRed, 3, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
paint.drawRect(QRectF(d->paperWidth, d->paperHeight, d->paperWidth, d->paperHeight));
paint.setPen(QPen(Qt::black, 3, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
QPainterPath p;
if (d->globalContour.isEmpty()) if (d->globalContour.isEmpty())
{ {
paint.drawPath(DrawContour(CutEdge(QLineF(0, 0, d->paperWidth, 0)))); p = DrawContour(CutEdge(QLineF(0, 0, d->paperWidth, 0)));
p.translate(d->paperWidth, d->paperHeight);
paint.drawPath(p);
} }
else else
{ {
paint.drawPath(DrawContour(d->globalContour)); p = DrawContour(d->globalContour);
p.translate(d->paperWidth, d->paperHeight);
paint.drawPath(p);
} }
paint.setPen(QPen(Qt::darkGreen, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin)); paint.setPen(QPen(Qt::darkGreen, 3, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
paint.drawPath(DrawContour(detail.GetLayoutAllowencePoints())); p = DrawContour(detail.GetLayoutAllowencePoints());
p.translate(d->paperWidth, d->paperHeight);
paint.drawPath(p);
#ifdef ARRANGED_DETAILS #ifdef ARRANGED_DETAILS
paint.setPen(QPen(Qt::blue, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin)); paint.setPen(QPen(Qt::blue, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
paint.drawPath(DrawDetails()); p = DrawDetails();
p.translate(d->paperWidth, d->paperHeight);
paint.drawPath(p);
#endif #endif
paint.end(); paint.end();
const QString path = QDir::homePath()+QStringLiteral("/LayoutDebug/")+QString("%1_%2.png").arg(d->paperIndex) const QString path = QDir::homePath()+QStringLiteral("/LayoutDebug/")+QString("%1_%2.png").arg(d->paperIndex)
.arg(d->frame); .arg(frame);
frameImage.save (path); frameImage.save (path);
} }
@ -844,6 +869,17 @@ QPainterPath VLayoutPaper::DrawContour(const QVector<QPointF> &points) const
return path; return path;
} }
//---------------------------------------------------------------------------------------------------------------------
QVector<QPointF> VLayoutPaper::TranslateContour(const QVector<QPointF> &points, qreal dx, qreal dy) const
{
QVector<QPointF> p;
for (qint32 i = 0; i < points.count(); ++i)
{
p.append(QPointF(points.at(i).x()+dx, points.at(i).y()+dy));
}
return p;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
QPainterPath VLayoutPaper::DrawDetails() const QPainterPath VLayoutPaper::DrawDetails() const
{ {

View File

@ -105,9 +105,10 @@ private:
bool SaveResult(const BestResult &bestResult, const VLayoutDetail &detail); bool SaveResult(const BestResult &bestResult, const VLayoutDetail &detail);
void DrawDebug(const VLayoutDetail &detail) const; void DrawDebug(const VLayoutDetail &detail, int frame) const;
QPainterPath ShowDirection(const QLineF &edge) const; QPainterPath ShowDirection(const QLineF &edge) const;
QPainterPath DrawContour(const QVector<QPointF> &points) const; QPainterPath DrawContour(const QVector<QPointF> &points) const;
QVector<QPointF> TranslateContour(const QVector<QPointF> &points, qreal dx, qreal dy) const;
QPainterPath DrawDetails() const; QPainterPath DrawDetails() const;
}; };