7 #include "DocumentModelSegments.h" 8 #include "EngaugeAssert.h" 15 #include <QGraphicsScene> 17 #include <QTextStream> 18 #include "QtToString.h" 20 #include "SegmentLine.h" 28 m_isGnuplot (isGnuplot)
34 QList<SegmentLine*>::iterator itr;
35 for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
38 m_scene.removeItem (segmentLine);
51 LOG4CPP_DEBUG_S ((*mainCat)) <<
"Segment::appendColumn" 52 <<
" segment=0x" << std::hex << (quintptr)
this << std::dec
54 << xOld <<
"," << yOld <<
") to (" 55 << xNew <<
"," << yNew <<
")";
60 ENGAUGE_CHECK_PTR(line);
61 line->setLine(QLineF (xOld,
71 m_length += qSqrt((1.0) * (1.0) + (y - m_yLast) * (y - m_yLast));
76 void Segment::createAcceptablePoint(
bool *pFirst,
83 int iOld = (int) (*xPrev + 0.5);
84 int jOld = (int) (*yPrev + 0.5);
85 int i = (int) (x + 0.5);
86 int j = (int) (y + 0.5);
88 if (*pFirst || (iOld != i) || (jOld != j)) {
92 ENGAUGE_CHECK_PTR(pList);
93 pList->append(QPoint(i, j));
99 void Segment::dumpToGnuplot (QTextStream &strDump,
106 if (mainCat->
getPriority() == log4cpp::Priority::DEBUG) {
110 QString label = QString (
"Old: (%1,%2) to (%3,%4), New: (%5,%6) to (%7,%8)")
111 .arg (lineOld->line().x1())
112 .arg (lineOld->line().y1())
113 .arg (lineOld->line().x2())
114 .arg (lineOld->line().y2())
115 .arg (lineNew->line().x1())
116 .arg (lineNew->line().y1())
117 .arg (lineNew->line().x2())
118 .arg (lineNew->line().y2());
120 strDump <<
"unset label\n";
121 strDump <<
"set label \"" << label <<
"\" at graph 0, graph 0.02\n";
122 strDump <<
"set grid xtics\n";
123 strDump <<
"set grid ytics\n";
126 int rows = 0, cols = 0;
127 QList<SegmentLine*>::const_iterator itr;
128 for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
131 ENGAUGE_CHECK_PTR (line);
133 int x1 = line->line().x1();
134 int y1 = line->line().y1();
135 int x2 = line->line().x2();
136 int y2 = line->line().y2();
138 rows = qMax (rows, y1 + 1);
139 rows = qMax (rows, y2 + 1);
140 cols = qMax (cols, x1 + 1);
141 cols = qMax (cols, x2 + 1);
146 int halfWidthX = 1.5 * qMax (qAbs (lineOld->line().dx()),
147 qAbs (lineNew->line().dx()));
148 int halfWidthY = 1.5 * qMax (qAbs (lineOld->line().dy()),
149 qAbs (lineNew->line().dy()));
152 strDump <<
"set xrange [" << (xInt - halfWidthX - 1) <<
":" << (xInt + halfWidthX + 1) <<
"]\n";
153 strDump <<
"set yrange [" << (yInt - halfWidthY - 1) <<
":" << (yInt + halfWidthY + 1) <<
"]\n";
158 strDump <<
"plot \\\n" 159 <<
"\"-\" title \"\" with lines, \\\n" 160 <<
"\"-\" title \"\" with lines, \\\n" 161 <<
"\"-\" title \"Replacement\" with lines, \\\n" 162 <<
"\"-\" title \"Segment pixels Even\" with linespoints, \\\n" 163 <<
"\"-\" title \"Segment pixels Odd\" with linespoints\n" 164 << xInt <<
" " << (yInt - halfWidthY) <<
"\n" 165 << xInt <<
" " << (yInt + halfWidthY) <<
"\n" 167 << (xInt - halfWidthX) <<
" " << yInt <<
"\n" 168 << (xInt + halfWidthY) <<
" " << yInt <<
"\n" 170 << lineOld->line().x1() <<
" " << lineOld->line().y1() <<
"\n" 171 << lineNew->line().x2() <<
" " << lineNew->line().y2() <<
"\n" 176 QTextStream strEven (&even), strOdd (&odd);
177 for (
int index = 0; index < m_lines.count(); index++) {
180 int x1 = line->line().x1();
181 int y1 = line->line().y1();
182 int x2 = line->line().x2();
183 int y2 = line->line().y2();
185 if (index % 2 == 0) {
186 strEven << x1 <<
" " << y1 <<
"\n";
187 strEven << x2 <<
" " << y2 <<
"\n";
190 strOdd << x1 <<
" " << y1 <<
"\n";
191 strOdd << x2 <<
" " << y2 <<
"\n";
196 strDump << even <<
"\n";
198 strDump << odd <<
"\n";
200 strDump <<
"pause -1 \"Hit Enter to continue\"\n";
207 LOG4CPP_INFO_S ((*mainCat)) <<
"Segment::fillPoints";
210 return fillPointsFillingCorners(modelSegments);
212 return fillPointsWithoutFillingCorners(modelSegments);
220 if (m_lines.count() > 0) {
222 double xLast = m_lines.first()->line().x1();
223 double yLast = m_lines.first()->line().y1();
226 double distanceCompleted = 0.0;
230 double xPrev = m_lines.first()->line().x1();
231 double yPrev = m_lines.first()->line().y1();
233 QList<SegmentLine*>::iterator itr;
234 for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
238 ENGAUGE_CHECK_PTR(line);
239 xNext = (double) line->line().x2();
240 yNext = (double) line->line().y2();
242 double xStart = (double) line->line().x1();
243 double yStart = (double) line->line().y1();
244 if (isCorner (yPrev, yStart, yNext)) {
247 createAcceptablePoint(&
firstPoint, &list, &xPrev, &yPrev, xStart, yStart);
248 distanceCompleted = 0.0;
252 double segmentLength = sqrt((xNext - xLast) * (xNext - xLast) + (yNext - yLast) * (yNext - yLast));
253 if (segmentLength > 0.0) {
257 while (distanceCompleted <= segmentLength) {
259 double s = distanceCompleted / segmentLength;
262 x = (1.0 - s) * xLast + s * xNext;
263 y = (1.0 - s) * yLast + s * yNext;
265 createAcceptablePoint(&
firstPoint, &list, &xPrev, &yPrev, x, y);
270 distanceCompleted -= segmentLength;
283 LOG4CPP_INFO_S ((*mainCat)) <<
"Segment::firstPoint" 284 <<
" lineCount=" << m_lines.count();
287 ENGAUGE_ASSERT (m_lines.count () > 0);
290 QPointF pos = line->line().p1();
292 LOG4CPP_INFO_S ((*mainCat)) <<
"Segment::firstPoint" 293 <<
" pos=" << QPointFToString (pos).toLatin1().data();
300 LOG4CPP_INFO_S ((*mainCat)) <<
"Segment::forwardMousePress" 301 <<
" segmentLines=" << m_lines.count();
306 bool Segment::isCorner (
double yLast,
311 double deltaYBefore = yPrev - yLast;
312 double deltaYAfter = yNext - yPrev;
313 bool upThenAcrossOrDown = (deltaYBefore > 0) && (deltaYAfter <= 0);
314 bool downThenAcrossOrUp = (deltaYBefore < 0) && (deltaYAfter >= 0);
316 return upThenAcrossOrDown || downThenAcrossOrUp;
323 if (m_lines.count() > 0) {
325 double xLast = m_lines.first()->line().x1();
326 double yLast = m_lines.first()->line().y1();
329 double distanceCompleted = 0.0;
333 double xPrev = m_lines.first()->line().x1();
334 double yPrev = m_lines.first()->line().y1();
336 QList<SegmentLine*>::iterator itr;
337 for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
341 ENGAUGE_CHECK_PTR(line);
342 xNext = (double) line->line().x2();
343 yNext = (double) line->line().y2();
346 double segmentLength = sqrt((xNext - xLast) * (xNext - xLast) + (yNext - yLast) * (yNext - yLast));
347 if (segmentLength > 0.0) {
351 while (distanceCompleted <= segmentLength) {
353 double s = distanceCompleted / segmentLength;
356 x = (1.0 - s) * xLast + s * xNext;
357 y = (1.0 - s) * yLast + s * yNext;
359 createAcceptablePoint(&
firstPoint, &list, &xPrev, &yPrev, x, y);
364 distanceCompleted -= segmentLength;
382 return m_lines.count();
385 bool Segment::pointIsCloseToLine(
double xLeft,
392 double xProj, yProj, projectedDistanceOutsideLine, distanceToLine;
393 projectPointOntoLine(xInt, yInt, xLeft, yLeft, xRight, yRight, &xProj, &yProj, &projectedDistanceOutsideLine, &distanceToLine);
396 (xInt - xProj) * (xInt - xProj) +
397 (yInt - yProj) * (yInt - yProj) < 0.5 * 0.5);
400 bool Segment::pointsAreCloseToLine(
double xLeft,
402 QList<QPoint> removedPoints,
406 QList<QPoint>::iterator itr;
407 for (itr = removedPoints.begin(); itr != removedPoints.end(); ++itr) {
408 if (!pointIsCloseToLine(xLeft, yLeft, (
double) (*itr).x(), (double) (*itr).y(), xRight, yRight)) {
418 LOG4CPP_INFO_S ((*mainCat)) <<
"Segment::removeUnneededLines";
421 QTextStream *strDump = 0;
424 QString filename (
"segment.gnuplot");
426 std::cout << GNUPLOT_FILE_MESSAGE.toLatin1().data() << filename.toLatin1().data() <<
"\n";
428 fileDump =
new QFile (filename);
429 fileDump->open (QIODevice::WriteOnly | QIODevice::Text);
430 strDump =
new QTextStream (fileDump);
439 QList<SegmentLine*>::iterator itr, itrPrevious;
440 QList<QPoint> removedPoints;
441 for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
444 ENGAUGE_CHECK_PTR(line);
446 if (linePrevious != 0) {
448 double xLeft = linePrevious->line().x1();
449 double yLeft = linePrevious->line().y1();
450 double xInt = linePrevious->line().x2();
451 double yInt = linePrevious->line().y2();
455 if (linePrevious->line().p2() == line->line().p1()) {
457 double xRight = line->line().x2();
458 double yRight = line->line().y2();
460 if (pointIsCloseToLine(xLeft, yLeft, xInt, yInt, xRight, yRight) &&
461 pointsAreCloseToLine(xLeft, yLeft, removedPoints, xRight, yRight)) {
466 dumpToGnuplot (*strDump,
476 LOG4CPP_DEBUG_S ((*mainCat)) <<
"Segment::removeUnneededLines" 477 <<
" segment=0x" << std::hex << (quintptr)
this << std::dec
479 << linePrevious->line().x1() <<
"," << linePrevious->line().y1() <<
") to (" 480 << linePrevious->line().x2() <<
"," << linePrevious->line().y2() <<
") " 481 <<
" and modifying (" 482 << line->line().x1() <<
"," << line->line().y1() <<
") to (" 483 << line->line().x2() <<
"," << line->line().y2() <<
") into (" 484 << xLeft <<
"," << yLeft <<
") to (" 485 << xRight <<
"," << yRight <<
")";
487 removedPoints.append(QPoint((
int) xInt, (
int) yInt));
488 m_lines.erase (itrPrevious);
492 line->setLine (xLeft, yLeft, xRight, yRight);
497 removedPoints.clear();
506 if (itr == m_lines.end()) {
514 *strDump <<
"set terminal x11 persist\n";
524 LOG4CPP_INFO_S ((*mainCat)) <<
"Segment::slotHover";
526 QList<SegmentLine*>::iterator itr, itrPrevious;
527 for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
536 LOG4CPP_INFO_S ((*mainCat)) <<
"Segment::updateModelSegment";
538 QList<SegmentLine*>::iterator itr;
539 for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
double pointSeparation() const
Get method for point separation.
void updateModelSegment(const DocumentModelSegments &modelSegments)
Update this segment line with new settings.
void removeUnneededLines(int *foldedLines)
Try to compress a segment that was just completed, by folding together line from point i to point i+1...
bool fillCorners() const
Get method for fill corners.
Priority::Value getPriority() const
Returns unused priority.
void slotHover(bool hover)
Slot for hover enter/leave events in the associated SegmentLines.
void forwardMousePress()
Forward mouse press event from a component SegmentLine that was just clicked on.
void appendColumn(int x, int y, const DocumentModelSegments &modelSegments)
Add some more pixels in a new column to an active segment.
QList< QPoint > fillPoints(const DocumentModelSegments &modelSegments)
Create evenly spaced points along the segment.
void signalMouseClickOnSegment(QPointF posSegmentStart)
Pass mouse press event, with coordinates of first point in the Segment since that info uniquely ident...
void updateModelSegment(const DocumentModelSegments &modelSegments)
Update this segment given the new settings.
int lineCount() const
Get method for number of lines.
Model for DlgSettingsSegments and CmdSettingsSegments.
QPointF firstPoint() const
Coordinates of first point in Segment.
This class is a special case of the standard QGraphicsLineItem for segments.
void setHover(bool hover)
Apply/remove highlighting triggered by hover enter/leave.
Segment(QGraphicsScene &scene, int yLast, bool isGnuplot)
Single constructor.
double length() const
Get method for length in pixels.