7 #include "DocumentModelSegments.h" 8 #include "EngaugeAssert.h" 14 #include <QGraphicsScene> 16 #include <QTextStream> 17 #include "QtToString.h" 19 #include "SegmentLine.h" 26 m_isGnuplot (isGnuplot)
28 LOG4CPP_INFO_S ((*mainCat)) <<
"Segment::Segment" 29 <<
" address=0x" << hex << (quintptr)
this;
34 LOG4CPP_INFO_S ((*mainCat)) <<
"Segment::~Segment" 35 <<
" address=0x" << hex << (quintptr)
this;
37 QList<SegmentLine*>::iterator itr;
38 for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
41 m_scene.removeItem (segmentLine);
54 LOG4CPP_DEBUG_S ((*mainCat)) <<
"Segment::appendColumn" 55 <<
" segment=0x" << std::hex << (quintptr)
this << std::dec
57 << xOld <<
"," << yOld <<
") to (" 58 << xNew <<
"," << yNew <<
")";
63 ENGAUGE_CHECK_PTR(line);
64 line->setLine(QLineF (xOld,
74 m_length += qSqrt((1.0) * (1.0) + (y - m_yLast) * (y - m_yLast));
79 void Segment::createAcceptablePoint(
bool *pFirst,
86 int iOld = (int) (*xPrev + 0.5);
87 int jOld = (int) (*yPrev + 0.5);
88 int i = (int) (x + 0.5);
89 int j = (int) (y + 0.5);
91 if (*pFirst || (iOld != i) || (jOld != j)) {
95 ENGAUGE_CHECK_PTR(pList);
96 pList->append(QPoint(i, j));
102 void Segment::dumpToGnuplot (QTextStream &strDump,
109 if (mainCat->getPriority() == log4cpp::Priority::DEBUG) {
113 QString label = QString (
"Old: (%1,%2) to (%3,%4), New: (%5,%6) to (%7,%8)")
114 .arg (lineOld->line().x1())
115 .arg (lineOld->line().y1())
116 .arg (lineOld->line().x2())
117 .arg (lineOld->line().y2())
118 .arg (lineNew->line().x1())
119 .arg (lineNew->line().y1())
120 .arg (lineNew->line().x2())
121 .arg (lineNew->line().y2());
123 strDump <<
"unset label\n";
124 strDump <<
"set label \"" << label <<
"\" at graph 0, graph 0.02\n";
125 strDump <<
"set grid xtics\n";
126 strDump <<
"set grid ytics\n";
129 int rows = 0, cols = 0;
130 QList<SegmentLine*>::const_iterator itr;
131 for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
134 ENGAUGE_CHECK_PTR (line);
136 int x1 = line->line().x1();
137 int y1 = line->line().y1();
138 int x2 = line->line().x2();
139 int y2 = line->line().y2();
141 rows = qMax (rows, y1 + 1);
142 rows = qMax (rows, y2 + 1);
143 cols = qMax (cols, x1 + 1);
144 cols = qMax (cols, x2 + 1);
149 int halfWidthX = 1.5 * qMax (qAbs (lineOld->line().dx()),
150 qAbs (lineNew->line().dx()));
151 int halfWidthY = 1.5 * qMax (qAbs (lineOld->line().dy()),
152 qAbs (lineNew->line().dy()));
155 strDump <<
"set xrange [" << (xInt - halfWidthX - 1) <<
":" << (xInt + halfWidthX + 1) <<
"]\n";
156 strDump <<
"set yrange [" << (yInt - halfWidthY - 1) <<
":" << (yInt + halfWidthY + 1) <<
"]\n";
161 strDump <<
"plot \\\n" 162 <<
"\"-\" title \"\" with lines, \\\n" 163 <<
"\"-\" title \"\" with lines, \\\n" 164 <<
"\"-\" title \"Replacement\" with lines, \\\n" 165 <<
"\"-\" title \"Segment pixels Even\" with linespoints, \\\n" 166 <<
"\"-\" title \"Segment pixels Odd\" with linespoints\n" 167 << xInt <<
" " << (yInt - halfWidthY) <<
"\n" 168 << xInt <<
" " << (yInt + halfWidthY) <<
"\n" 170 << (xInt - halfWidthX) <<
" " << yInt <<
"\n" 171 << (xInt + halfWidthY) <<
" " << yInt <<
"\n" 173 << lineOld->line().x1() <<
" " << lineOld->line().y1() <<
"\n" 174 << lineNew->line().x2() <<
" " << lineNew->line().y2() <<
"\n" 179 QTextStream strEven (&even), strOdd (&odd);
180 for (
int index = 0; index < m_lines.count(); index++) {
183 int x1 = line->line().x1();
184 int y1 = line->line().y1();
185 int x2 = line->line().x2();
186 int y2 = line->line().y2();
188 if (index % 2 == 0) {
189 strEven << x1 <<
" " << y1 <<
"\n";
190 strEven << x2 <<
" " << y2 <<
"\n";
193 strOdd << x1 <<
" " << y1 <<
"\n";
194 strOdd << x2 <<
" " << y2 <<
"\n";
199 strDump << even <<
"\n";
201 strDump << odd <<
"\n";
203 strDump <<
"pause -1 \"Hit Enter to continue\"\n";
210 LOG4CPP_INFO_S ((*mainCat)) <<
"Segment::fillPoints";
213 return fillPointsFillingCorners(modelSegments);
215 return fillPointsWithoutFillingCorners(modelSegments);
223 if (m_lines.count() > 0) {
225 double xLast = m_lines.first()->line().x1();
226 double yLast = m_lines.first()->line().y1();
229 double distanceCompleted = 0.0;
233 double xPrev = m_lines.first()->line().x1();
234 double yPrev = m_lines.first()->line().y1();
236 QList<SegmentLine*>::iterator itr;
237 for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
241 ENGAUGE_CHECK_PTR(line);
242 xNext = (double) line->line().x2();
243 yNext = (double) line->line().y2();
245 double xStart = (double) line->line().x1();
246 double yStart = (double) line->line().y1();
247 if (isCorner (yPrev, yStart, yNext)) {
250 createAcceptablePoint(&firstPoint, &list, &xPrev, &yPrev, xStart, yStart);
251 distanceCompleted = 0.0;
255 double segmentLength = sqrt((xNext - xLast) * (xNext - xLast) + (yNext - yLast) * (yNext - yLast));
256 if (segmentLength > 0.0) {
260 while (distanceCompleted <= segmentLength) {
262 double s = distanceCompleted / segmentLength;
265 x = (1.0 - s) * xLast + s * xNext;
266 y = (1.0 - s) * yLast + s * yNext;
268 createAcceptablePoint(&firstPoint, &list, &xPrev, &yPrev, x, y);
273 distanceCompleted -= segmentLength;
286 LOG4CPP_INFO_S ((*mainCat)) <<
"Segment::firstPoint" 287 <<
" lineCount=" << m_lines.count();
290 ENGAUGE_ASSERT (m_lines.count () > 0);
293 QPointF pos = line->line().p1();
295 LOG4CPP_INFO_S ((*mainCat)) <<
"Segment::firstPoint" 296 <<
" pos=" << QPointFToString (pos).toLatin1().data();
303 LOG4CPP_INFO_S ((*mainCat)) <<
"Segment::forwardMousePress" 304 <<
" segmentLines=" << m_lines.count();
309 bool Segment::isCorner (
double yLast,
314 double deltaYBefore = yPrev - yLast;
315 double deltaYAfter = yNext - yPrev;
316 bool upThenAcrossOrDown = (deltaYBefore > 0) && (deltaYAfter <= 0);
317 bool downThenAcrossOrUp = (deltaYBefore < 0) && (deltaYAfter >= 0);
319 return upThenAcrossOrDown || downThenAcrossOrUp;
326 if (m_lines.count() > 0) {
328 double xLast = m_lines.first()->line().x1();
329 double yLast = m_lines.first()->line().y1();
332 double distanceCompleted = 0.0;
336 double xPrev = m_lines.first()->line().x1();
337 double yPrev = m_lines.first()->line().y1();
339 QList<SegmentLine*>::iterator itr;
340 for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
344 ENGAUGE_CHECK_PTR(line);
345 xNext = (double) line->line().x2();
346 yNext = (double) line->line().y2();
349 double segmentLength = sqrt((xNext - xLast) * (xNext - xLast) + (yNext - yLast) * (yNext - yLast));
350 if (segmentLength > 0.0) {
354 while (distanceCompleted <= segmentLength) {
356 double s = distanceCompleted / segmentLength;
359 x = (1.0 - s) * xLast + s * xNext;
360 y = (1.0 - s) * yLast + s * yNext;
362 createAcceptablePoint(&firstPoint, &list, &xPrev, &yPrev, x, y);
367 distanceCompleted -= segmentLength;
385 return m_lines.count();
388 bool Segment::pointIsCloseToLine(
double xLeft,
395 double xProj, yProj, projectedDistanceOutsideLine, distanceToLine;
396 projectPointOntoLine(xInt, yInt, xLeft, yLeft, xRight, yRight, &xProj, &yProj, &projectedDistanceOutsideLine, &distanceToLine);
399 (xInt - xProj) * (xInt - xProj) +
400 (yInt - yProj) * (yInt - yProj) < 0.5 * 0.5);
403 bool Segment::pointsAreCloseToLine(
double xLeft,
405 QList<QPoint> removedPoints,
409 QList<QPoint>::iterator itr;
410 for (itr = removedPoints.begin(); itr != removedPoints.end(); ++itr) {
411 if (!pointIsCloseToLine(xLeft, yLeft, (
double) (*itr).x(), (double) (*itr).y(), xRight, yRight)) {
421 LOG4CPP_INFO_S ((*mainCat)) <<
"Segment::removeUnneededLines";
424 QTextStream *strDump = 0;
427 QString filename (
"segment.gnuplot");
429 std::cout <<
"Writing gnuplot file: " << filename.toLatin1().data() <<
"\n";
431 fileDump =
new QFile (filename);
432 fileDump->open (QIODevice::WriteOnly | QIODevice::Text);
433 strDump =
new QTextStream (fileDump);
442 QList<SegmentLine*>::iterator itr, itrPrevious;
443 QList<QPoint> removedPoints;
444 for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
447 ENGAUGE_CHECK_PTR(line);
449 if (linePrevious != 0) {
451 double xLeft = linePrevious->line().x1();
452 double yLeft = linePrevious->line().y1();
453 double xInt = linePrevious->line().x2();
454 double yInt = linePrevious->line().y2();
458 if (linePrevious->line().p2() == line->line().p1()) {
460 double xRight = line->line().x2();
461 double yRight = line->line().y2();
463 if (pointIsCloseToLine(xLeft, yLeft, xInt, yInt, xRight, yRight) &&
464 pointsAreCloseToLine(xLeft, yLeft, removedPoints, xRight, yRight)) {
469 dumpToGnuplot (*strDump,
479 LOG4CPP_DEBUG_S ((*mainCat)) <<
"Segment::removeUnneededLines" 480 <<
" segment=0x" << std::hex << (quintptr)
this << std::dec
482 << linePrevious->line().x1() <<
"," << linePrevious->line().y1() <<
") to (" 483 << linePrevious->line().x2() <<
"," << linePrevious->line().y2() <<
") " 484 <<
" and modifying (" 485 << line->line().x1() <<
"," << line->line().y1() <<
") to (" 486 << line->line().x2() <<
"," << line->line().y2() <<
") into (" 487 << xLeft <<
"," << yLeft <<
") to (" 488 << xRight <<
"," << yRight <<
")";
490 removedPoints.append(QPoint((
int) xInt, (
int) yInt));
491 m_lines.erase (itrPrevious);
495 line->setLine (xLeft, yLeft, xRight, yRight);
500 removedPoints.clear();
509 if (itr == m_lines.end()) {
517 *strDump <<
"set terminal x11 persist\n";
527 LOG4CPP_INFO_S ((*mainCat)) <<
"Segment::slotHover";
529 QList<SegmentLine*>::iterator itr, itrPrevious;
530 for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
539 LOG4CPP_INFO_S ((*mainCat)) <<
"Segment::updateModelSegment";
541 QList<SegmentLine*>::iterator itr;
542 for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
int lineCount() const
Get method for number of lines.
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...
double pointSeparation() const
Get method for point separation.
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.
double length() const
Get method for length in pixels.
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.
QPointF firstPoint() const
Coordinates of first point in Segment.
Model for DlgSettingsSegments and CmdSettingsSegments.
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.
bool fillCorners() const
Get method for fill corners.