16#include <QGraphicsScene>
29 m_isGnuplot (isGnuplot)
35 QList<SegmentLine*>::iterator itr;
36 for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
39 m_scene.removeItem (segmentLine);
53 <<
" segment=0x" << std::hex << static_cast<void*> (
this) << std::dec
55 << xOld <<
"," << yOld <<
") to ("
56 << xNew <<
"," << yNew <<
")";
62 line->setLine(QLineF (xOld,
72 m_length += qSqrt((1.0) * (1.0) + (y - m_yLast) * (y - m_yLast));
77void Segment::createAcceptablePoint(
bool *pFirst,
84 int iOld = qFloor (*xPrev + 0.5);
85 int jOld = qFloor (*yPrev + 0.5);
86 int i = qFloor (x + 0.5);
87 int j = qFloor (y + 0.5);
89 if (*pFirst || (iOld != i) || (jOld != j)) {
94 pList->append(QPoint(i, j));
100void Segment::dumpToGnuplot (QTextStream &strDump,
111 QString label = QString (
"Old: (%1,%2) to (%3,%4), New: (%5,%6) to (%7,%8)")
112 .arg (lineOld->line().x1())
113 .arg (lineOld->line().y1())
114 .arg (lineOld->line().x2())
115 .arg (lineOld->line().y2())
116 .arg (lineNew->line().x1())
117 .arg (lineNew->line().y1())
118 .arg (lineNew->line().x2())
119 .arg (lineNew->line().y2());
121 strDump <<
"unset label\n";
122 strDump <<
"set label \"" << label <<
"\" at graph 0, graph 0.02\n";
123 strDump <<
"set grid xtics\n";
124 strDump <<
"set grid ytics\n";
127 int rows = 0, cols = 0;
128 QList<SegmentLine*>::const_iterator itr;
129 for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
131 SegmentLine *line = *itr;
134 int x1 = qFloor (line->line().x1());
135 int y1 = qFloor (line->line().y1());
136 int x2 = qFloor (line->line().x2());
137 int y2 = qFloor (line->line().y2());
139 rows = qMax (rows, y1 + 1);
140 rows = qMax (rows, y2 + 1);
141 cols = qMax (cols, x1 + 1);
142 cols = qMax (cols, x2 + 1);
147 int halfWidthX = qFloor (1.5 * qMax (qAbs (lineOld->line().dx()),
148 qAbs (lineNew->line().dx())));
149 int halfWidthY = qFloor (1.5 * qMax (qAbs (lineOld->line().dy()),
150 qAbs (lineNew->line().dy())));
153 strDump <<
"set xrange [" << (xInt - halfWidthX - 1) <<
":" << (xInt + halfWidthX + 1) <<
"]\n";
154 strDump <<
"set yrange [" << (yInt - halfWidthY - 1) <<
":" << (yInt + halfWidthY + 1) <<
"]\n";
159 strDump <<
"plot \\\n"
160 <<
"\"-\" title \"\" with lines, \\\n"
161 <<
"\"-\" title \"\" with lines, \\\n"
162 <<
"\"-\" title \"Replacement\" with lines, \\\n"
163 <<
"\"-\" title \"Segment pixels Even\" with linespoints, \\\n"
164 <<
"\"-\" title \"Segment pixels Odd\" with linespoints\n"
165 << xInt <<
" " << (yInt - halfWidthY) <<
"\n"
166 << xInt <<
" " << (yInt + halfWidthY) <<
"\n"
168 << (xInt - halfWidthX) <<
" " << yInt <<
"\n"
169 << (xInt + halfWidthY) <<
" " << yInt <<
"\n"
171 << lineOld->line().x1() <<
" " << lineOld->line().y1() <<
"\n"
172 << lineNew->line().x2() <<
" " << lineNew->line().y2() <<
"\n"
177 QTextStream strEven (&even), strOdd (&odd);
178 for (
int index = 0; index < m_lines.count(); index++) {
180 SegmentLine *line = m_lines.at (index);
181 int x1 = qFloor (line->line().x1());
182 int y1 = qFloor (line->line().y1());
183 int x2 = qFloor (line->line().x2());
184 int y2 = qFloor (line->line().y2());
186 if (index % 2 == 0) {
187 strEven << x1 <<
" " << y1 <<
"\n";
188 strEven << x2 <<
" " << y2 <<
"\n";
191 strOdd << x1 <<
" " << y1 <<
"\n";
192 strOdd << x2 <<
" " << y2 <<
"\n";
197 strDump << even <<
"\n";
199 strDump << odd <<
"\n";
201 strDump <<
"pause -1 \"Hit Enter to continue\"\n";
211 return fillPointsFillingCorners(modelSegments);
213 return fillPointsWithoutFillingCorners(modelSegments);
221 if (m_lines.count() > 0) {
223 double xLast = m_lines.first()->line().x1();
224 double yLast = m_lines.first()->line().y1();
227 double distanceCompleted = 0.0;
231 double xPrev = m_lines.first()->line().x1();
232 double yPrev = m_lines.first()->line().y1();
234 QList<SegmentLine*>::iterator itr;
235 for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
240 xNext = double (line->line().x2());
241 yNext = double (line->line().y2());
243 double xStart = double (line->line().x1());
244 double yStart = double (line->line().y1());
245 if (isCorner (yPrev, yStart, yNext)) {
248 createAcceptablePoint(&
firstPoint, &list, &xPrev, &yPrev, xStart, yStart);
249 distanceCompleted = 0.0;
253 double segmentLength = sqrt((xNext - xLast) * (xNext - xLast) + (yNext - yLast) * (yNext - yLast));
254 if (segmentLength > 0.0) {
258 while (distanceCompleted <= segmentLength) {
260 double s = distanceCompleted / segmentLength;
263 x = (1.0 - s) * xLast + s * xNext;
264 y = (1.0 - s) * yLast + s * yNext;
266 createAcceptablePoint(&
firstPoint, &list, &xPrev, &yPrev, x, y);
271 distanceCompleted -= segmentLength;
285 <<
" lineCount=" << m_lines.count();
291 QPointF pos = line->line().p1();
302 <<
" segmentLines=" << m_lines.count();
307bool Segment::isCorner (
double yLast,
312 double deltaYBefore = yPrev - yLast;
313 double deltaYAfter = yNext - yPrev;
314 bool upThenAcrossOrDown = (deltaYBefore > 0) && (deltaYAfter <= 0);
315 bool downThenAcrossOrUp = (deltaYBefore < 0) && (deltaYAfter >= 0);
317 return upThenAcrossOrDown || downThenAcrossOrUp;
324 if (m_lines.count() > 0) {
326 double xLast = m_lines.first()->line().x1();
327 double yLast = m_lines.first()->line().y1();
330 double distanceCompleted = 0.0;
334 double xPrev = m_lines.first()->line().x1();
335 double yPrev = m_lines.first()->line().y1();
337 QList<SegmentLine*>::iterator itr;
338 for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
340 SegmentLine *line = *itr;
343 xNext = double (line->line().x2());
344 yNext = double (line->line().y2());
347 double segmentLength = sqrt((xNext - xLast) * (xNext - xLast) + (yNext - yLast) * (yNext - yLast));
348 if (segmentLength > 0.0) {
352 while (distanceCompleted <= segmentLength) {
354 double s = distanceCompleted / segmentLength;
357 x = (1.0 - s) * xLast + s * xNext;
358 y = (1.0 - s) * yLast + s * yNext;
360 createAcceptablePoint(&
firstPoint, &list, &xPrev, &yPrev, x, y);
365 distanceCompleted -= segmentLength;
383 return m_lines.count();
388 QList<SegmentLine*>::iterator itr;
389 for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
392 line->setAcceptHoverEvents (
false);
396bool Segment::pointIsCloseToLine(
double xLeft,
403 double xProj, yProj, projectedDistanceOutsideLine, distanceToLine;
404 projectPointOntoLine(xInt, yInt, xLeft, yLeft, xRight, yRight, &xProj, &yProj, &projectedDistanceOutsideLine, &distanceToLine);
407 (xInt - xProj) * (xInt - xProj) +
408 (yInt - yProj) * (yInt - yProj) < 0.5 * 0.5);
411bool Segment::pointsAreCloseToLine(
double xLeft,
413 QList<QPoint> removedPoints,
417 QList<QPoint>::iterator itr;
418 for (itr = removedPoints.begin(); itr != removedPoints.end(); ++itr) {
419 if (!pointIsCloseToLine(xLeft,
436 QFile *fileDump =
nullptr;
437 QTextStream *strDump =
nullptr;
440 QString filename (
"segment.gnuplot");
444 fileDump =
new QFile (filename);
445 fileDump->open (QIODevice::WriteOnly | QIODevice::Text);
446 strDump =
new QTextStream (fileDump);
455 QList<SegmentLine*>::iterator itr, itrPrevious;
456 QList<QPoint> removedPoints;
457 for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
462 if (linePrevious !=
nullptr) {
464 double xLeft = linePrevious->line().x1();
465 double yLeft = linePrevious->line().y1();
466 double xInt = linePrevious->line().x2();
467 double yInt = linePrevious->line().y2();
471 if (linePrevious->line().p2() == line->line().p1()) {
473 double xRight = line->line().x2();
474 double yRight = line->line().y2();
476 if (pointIsCloseToLine(xLeft, yLeft, xInt, yInt, xRight, yRight) &&
477 pointsAreCloseToLine(xLeft, yLeft, removedPoints, xRight, yRight)) {
482 dumpToGnuplot (*strDump,
493 <<
" segment=0x" << std::hex << static_cast<void*> (
this) << std::dec
495 << linePrevious->line().x1() <<
"," << linePrevious->line().y1() <<
") to ("
496 << linePrevious->line().x2() <<
"," << linePrevious->line().y2() <<
") "
497 <<
" and modifying ("
498 << line->line().x1() <<
"," << line->line().y1() <<
") to ("
499 << line->line().x2() <<
"," << line->line().y2() <<
") into ("
500 << xLeft <<
"," << yLeft <<
") to ("
501 << xRight <<
"," << yRight <<
")";
503 removedPoints.append(QPoint(qFloor (xInt),
505 m_lines.erase (itrPrevious);
509 line->setLine (xLeft, yLeft, xRight, yRight);
514 removedPoints.clear();
523 if (itr == m_lines.end()) {
528 if (strDump !=
nullptr) {
531 *strDump <<
"set terminal x11 persist\n";
543 QList<SegmentLine*>::iterator itr, itrPrevious;
544 for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
555 QList<SegmentLine*>::iterator itr;
556 for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
#define ENGAUGE_ASSERT(cond)
Drop in replacement for Q_ASSERT.
#define ENGAUGE_CHECK_PTR(ptr)
Drop in replacement for Q_CHECK_PTR.
log4cpp::Category * mainCat
QString QPointFToString(const QPointF &pos)
static QTextStream & flush(QTextStream &stream)
Flush.
Model for DlgSettingsSegments and CmdSettingsSegments.
bool fillCorners() const
Get method for fill corners.
double pointSeparation() const
Get method for point separation.
This class is a special case of the standard QGraphicsLineItem for segments.
void setHover(bool hover)
Apply/remove highlighting triggered by hover enter/leave.
void updateModelSegment(const DocumentModelSegments &modelSegments)
Update this segment line with new settings.
void lockHoverState()
Disable hover events. This is used only by DlgSettingsSegments to stop hover events in the preview wi...
void signalMouseClickOnSegment(QPointF posSegmentStart)
Pass mouse press event, with coordinates of first point in the Segment since that info uniquely ident...
double length() const
Get method for length in pixels.
int lineCount() const
Get method for number of lines.
QList< QPoint > fillPoints(const DocumentModelSegments &modelSegments)
Create evenly spaced points along the segment.
Segment(QGraphicsScene &scene, int yLast, bool isGnuplot)
Single constructor.
void forwardMousePress()
Forward mouse press event from a component SegmentLine that was just clicked on.
void slotHover(bool hover)
Slot for hover enter/leave events in the associated SegmentLines.
void updateModelSegment(const DocumentModelSegments &modelSegments)
Update this segment given the new settings.
void appendColumn(int x, int y, const DocumentModelSegments &modelSegments)
Add some more pixels in a new column to an active segment.
QPointF firstPoint() const
Coordinates of first point in Segment.
void removeUnneededLines(int *foldedLines)
Try to compress a segment that was just completed, by folding together line from point i to point i+1...
Priority::Value getPriority() const
Returns unused priority.
#define LOG4CPP_INFO_S(logger)
#define LOG4CPP_DEBUG_S(logger)
const QString GNUPLOT_FILE_MESSAGE
void projectPointOntoLine(double xToProject, double yToProject, double xStart, double yStart, double xStop, double yStop, double *xProjection, double *yProjection, double *projectedDistanceOutsideLine, double *distanceToLine)
Find the projection of a point onto a line segment such that the line through the point and its proje...