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 = RoundPoints(d->contour);
}
//---------------------------------------------------------------------------------------------------------------------
@ -91,6 +93,8 @@ void VLayoutDetail::SetSeamAllowencePoints(const QVector<QPointF> &points)
{
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)
{
d->matrix = d->matrix.translate(dx, dy);
QMatrix m;
m.translate(dx, dy);
d->matrix *= m;
}
//---------------------------------------------------------------------------------------------------------------------
void VLayoutDetail::Rotate(const QPointF &originPoint, qreal degrees)
{
Translate(-originPoint.x(), -originPoint.y());
d->matrix = d->matrix.rotate(degrees);
Translate(originPoint.x(), originPoint.y());
QMatrix m;
m.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
qreal angle = edge.angleTo(axis);
Rotate(edge.p1(), angle);
d->matrix = d->matrix.scale(d->matrix.m11()*-1, d->matrix.m22());
Rotate(edge.p1(), 360 - angle);
Rotate(edge.p1(), -angle);
d->matrix *= d->matrix.scale(d->matrix.m11()*-1, d->matrix.m22());
Rotate(edge.p1(), 360 + angle);
}
//---------------------------------------------------------------------------------------------------------------------
@ -286,10 +294,18 @@ void VLayoutDetail::SetLayoutAllowencePoints()
if (getSeamAllowance())
{
d->layoutAllowence = Equidistant(d->seamAllowence, EquidistantType::CloseEquidistant, d->layoutWidth);
if (d->layoutAllowence.isEmpty() == false)
{
d->layoutAllowence.removeLast();
}
}
else
{
d->layoutAllowence = Equidistant(d->contour, EquidistantType::CloseEquidistant, d->layoutWidth);
if (d->layoutAllowence.isEmpty() == false)
{
d->layoutAllowence.removeLast();
}
}
}
else
@ -319,6 +335,17 @@ QVector<QPointF> VLayoutDetail::Map(const QVector<QPointF> &points) const
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
{

View file

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

View file

@ -36,6 +36,7 @@
#include <QDir>
#include <QPainter>
#include <QGraphicsItem>
#include <QCoreApplication>
class BestResult
{
@ -222,6 +223,8 @@ bool VLayoutPaper::AddToBlankSheet(const VLayoutDetail &detail)
{
for (int i=1; i<= detail.EdgesCount(); i++)
{
QCoreApplication::processEvents();
// We should use copy of the detail.
VLayoutDetail workDetail = detail;
@ -237,8 +240,10 @@ bool VLayoutPaper::AddToBlankSheet(const VLayoutDetail &detail)
}
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.
VLayoutDetail workDetail = detail;
@ -271,6 +276,8 @@ bool VLayoutPaper::AddToSheet(const VLayoutDetail &detail)
for (int i=1; i<= workDetail.EdgesCount(); i++)
{
QCoreApplication::processEvents();
int dEdge = i;// For mirror detail edge will be different
if (CheckCombineEdges(workDetail, j, dEdge))
{
@ -304,7 +311,7 @@ bool VLayoutPaper::CheckCombineEdges(VLayoutDetail &detail, int j, int &dEdge) c
CombineEdges(detail, globalEdge, dEdge);
#ifdef LAYOUT_DEBUG
DrawDebug(detail);
DrawDebug(detail, d->frame);
#endif
switch (Crossing(detail, j, dEdge))
@ -338,6 +345,10 @@ bool VLayoutPaper::CheckCombineEdges(VLayoutDetail &detail, int j, int &dEdge) c
if (flagMirror)
{
#ifdef LAYOUT_DEBUG
DrawDebug(detail, d->frame+1);
#endif
dEdge = detail.EdgeByPoint(globalEdge.p2());
if (dEdge <= 0)
{
@ -383,7 +394,7 @@ bool VLayoutPaper::CheckRotationEdges(VLayoutDetail &detail, int j, int dEdge, i
RotateEdges(detail, globalEdge, dEdge, angle);
#ifdef LAYOUT_DEBUG
DrawDebug(detail);
DrawDebug(detail, d->frame);
#endif
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 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.
const qreal angle_between = globalEdge.angleTo(detailEdge); // Seek angle between two edges.
// Now we move detail to position near to global contour edge.
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);
QPainter paint;
paint.setPen(QPen(Qt::black, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
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())
{
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
{
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.drawPath(DrawContour(detail.GetLayoutAllowencePoints()));
paint.setPen(QPen(Qt::darkGreen, 3, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
p = DrawContour(detail.GetLayoutAllowencePoints());
p.translate(d->paperWidth, d->paperHeight);
paint.drawPath(p);
#ifdef ARRANGED_DETAILS
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
paint.end();
const QString path = QDir::homePath()+QStringLiteral("/LayoutDebug/")+QString("%1_%2.png").arg(d->paperIndex)
.arg(d->frame);
.arg(frame);
frameImage.save (path);
}
@ -844,6 +869,17 @@ QPainterPath VLayoutPaper::DrawContour(const QVector<QPointF> &points) const
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
{

View file

@ -105,9 +105,10 @@ private:
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 DrawContour(const QVector<QPointF> &points) const;
QVector<QPointF> TranslateContour(const QVector<QPointF> &points, qreal dx, qreal dy) const;
QPainterPath DrawDetails() const;
};