7 #include "DocumentModelSegments.h" 8 #include "EngaugeAssert.h" 14 #include <QGraphicsScene> 16 #include <QTextStream> 17 #include "QtToString.h" 19 #include "SegmentLine.h" 27 m_isGnuplot (isGnuplot)
29 LOG4CPP_INFO_S ((*mainCat)) <<
"Segment::Segment" 30 <<
" address=0x" << hex << (quintptr)
this;
35 LOG4CPP_INFO_S ((*mainCat)) <<
"Segment::~Segment" 36 <<
" address=0x" << hex << (quintptr)
this;
38 QList<SegmentLine*>::iterator itr;
39 for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
42 m_scene.removeItem (segmentLine);
55 LOG4CPP_DEBUG_S ((*mainCat)) <<
"Segment::appendColumn" 56 <<
" segment=0x" << std::hex << (quintptr)
this << std::dec
58 << xOld <<
"," << yOld <<
") to (" 59 << xNew <<
"," << yNew <<
")";
64 ENGAUGE_CHECK_PTR(line);
65 line->setLine(QLineF (xOld,
75 m_length += qSqrt((1.0) * (1.0) + (y - m_yLast) * (y - m_yLast));
80 void Segment::createAcceptablePoint(
bool *pFirst,
87 int iOld = (int) (*xPrev + 0.5);
88 int jOld = (int) (*yPrev + 0.5);
89 int i = (int) (x + 0.5);
90 int j = (int) (y + 0.5);
92 if (*pFirst || (iOld != i) || (jOld != j)) {
96 ENGAUGE_CHECK_PTR(pList);
97 pList->append(QPoint(i, j));
103 void Segment::dumpToGnuplot (QTextStream &strDump,
110 if (mainCat->getPriority() == log4cpp::Priority::DEBUG) {
114 QString label = QString (
"Old: (%1,%2) to (%3,%4), New: (%5,%6) to (%7,%8)")
115 .arg (lineOld->line().x1())
116 .arg (lineOld->line().y1())
117 .arg (lineOld->line().x2())
118 .arg (lineOld->line().y2())
119 .arg (lineNew->line().x1())
120 .arg (lineNew->line().y1())
121 .arg (lineNew->line().x2())
122 .arg (lineNew->line().y2());
124 strDump <<
"unset label\n";
125 strDump <<
"set label \"" << label <<
"\" at graph 0, graph 0.02\n";
126 strDump <<
"set grid xtics\n";
127 strDump <<
"set grid ytics\n";
130 int rows = 0, cols = 0;
131 QList<SegmentLine*>::const_iterator itr;
132 for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
135 ENGAUGE_CHECK_PTR (line);
137 int x1 = line->line().x1();
138 int y1 = line->line().y1();
139 int x2 = line->line().x2();
140 int y2 = line->line().y2();
142 rows = qMax (rows, y1 + 1);
143 rows = qMax (rows, y2 + 1);
144 cols = qMax (cols, x1 + 1);
145 cols = qMax (cols, x2 + 1);
150 int halfWidthX = 1.5 * qMax (qAbs (lineOld->line().dx()),
151 qAbs (lineNew->line().dx()));
152 int halfWidthY = 1.5 * qMax (qAbs (lineOld->line().dy()),
153 qAbs (lineNew->line().dy()));
156 strDump <<
"set xrange [" << (xInt - halfWidthX - 1) <<
":" << (xInt + halfWidthX + 1) <<
"]\n";
157 strDump <<
"set yrange [" << (yInt - halfWidthY - 1) <<
":" << (yInt + halfWidthY + 1) <<
"]\n";
162 strDump <<
"plot \\\n" 163 <<
"\"-\" title \"\" with lines, \\\n" 164 <<
"\"-\" title \"\" with lines, \\\n" 165 <<
"\"-\" title \"Replacement\" with lines, \\\n" 166 <<
"\"-\" title \"Segment pixels Even\" with linespoints, \\\n" 167 <<
"\"-\" title \"Segment pixels Odd\" with linespoints\n" 168 << xInt <<
" " << (yInt - halfWidthY) <<
"\n" 169 << xInt <<
" " << (yInt + halfWidthY) <<
"\n" 171 << (xInt - halfWidthX) <<
" " << yInt <<
"\n" 172 << (xInt + halfWidthY) <<
" " << yInt <<
"\n" 174 << lineOld->line().x1() <<
" " << lineOld->line().y1() <<
"\n" 175 << lineNew->line().x2() <<
" " << lineNew->line().y2() <<
"\n" 180 QTextStream strEven (&even), strOdd (&odd);
181 for (
int index = 0; index < m_lines.count(); index++) {
184 int x1 = line->line().x1();
185 int y1 = line->line().y1();
186 int x2 = line->line().x2();
187 int y2 = line->line().y2();
189 if (index % 2 == 0) {
190 strEven << x1 <<
" " << y1 <<
"\n";
191 strEven << x2 <<
" " << y2 <<
"\n";
194 strOdd << x1 <<
" " << y1 <<
"\n";
195 strOdd << x2 <<
" " << y2 <<
"\n";
200 strDump << even <<
"\n";
202 strDump << odd <<
"\n";
204 strDump <<
"pause -1 \"Hit Enter to continue\"\n";
211 LOG4CPP_INFO_S ((*mainCat)) <<
"Segment::fillPoints";
214 return fillPointsFillingCorners(modelSegments);
216 return fillPointsWithoutFillingCorners(modelSegments);
224 if (m_lines.count() > 0) {
226 double xLast = m_lines.first()->line().x1();
227 double yLast = m_lines.first()->line().y1();
230 double distanceCompleted = 0.0;
234 double xPrev = m_lines.first()->line().x1();
235 double yPrev = m_lines.first()->line().y1();
237 QList<SegmentLine*>::iterator itr;
238 for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
242 ENGAUGE_CHECK_PTR(line);
243 xNext = (double) line->line().x2();
244 yNext = (double) line->line().y2();
246 double xStart = (double) line->line().x1();
247 double yStart = (double) line->line().y1();
248 if (isCorner (yPrev, yStart, yNext)) {
251 createAcceptablePoint(&firstPoint, &list, &xPrev, &yPrev, xStart, yStart);
252 distanceCompleted = 0.0;
256 double segmentLength = sqrt((xNext - xLast) * (xNext - xLast) + (yNext - yLast) * (yNext - yLast));
257 if (segmentLength > 0.0) {
261 while (distanceCompleted <= segmentLength) {
263 double s = distanceCompleted / segmentLength;
266 x = (1.0 - s) * xLast + s * xNext;
267 y = (1.0 - s) * yLast + s * yNext;
269 createAcceptablePoint(&firstPoint, &list, &xPrev, &yPrev, x, y);
274 distanceCompleted -= segmentLength;
287 LOG4CPP_INFO_S ((*mainCat)) <<
"Segment::firstPoint" 288 <<
" lineCount=" << m_lines.count();
291 ENGAUGE_ASSERT (m_lines.count () > 0);
294 QPointF pos = line->line().p1();
296 LOG4CPP_INFO_S ((*mainCat)) <<
"Segment::firstPoint" 297 <<
" pos=" << QPointFToString (pos).toLatin1().data();
304 LOG4CPP_INFO_S ((*mainCat)) <<
"Segment::forwardMousePress" 305 <<
" segmentLines=" << m_lines.count();
310 bool Segment::isCorner (
double yLast,
315 double deltaYBefore = yPrev - yLast;
316 double deltaYAfter = yNext - yPrev;
317 bool upThenAcrossOrDown = (deltaYBefore > 0) && (deltaYAfter <= 0);
318 bool downThenAcrossOrUp = (deltaYBefore < 0) && (deltaYAfter >= 0);
320 return upThenAcrossOrDown || downThenAcrossOrUp;
327 if (m_lines.count() > 0) {
329 double xLast = m_lines.first()->line().x1();
330 double yLast = m_lines.first()->line().y1();
333 double distanceCompleted = 0.0;
337 double xPrev = m_lines.first()->line().x1();
338 double yPrev = m_lines.first()->line().y1();
340 QList<SegmentLine*>::iterator itr;
341 for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
345 ENGAUGE_CHECK_PTR(line);
346 xNext = (double) line->line().x2();
347 yNext = (double) line->line().y2();
350 double segmentLength = sqrt((xNext - xLast) * (xNext - xLast) + (yNext - yLast) * (yNext - yLast));
351 if (segmentLength > 0.0) {
355 while (distanceCompleted <= segmentLength) {
357 double s = distanceCompleted / segmentLength;
360 x = (1.0 - s) * xLast + s * xNext;
361 y = (1.0 - s) * yLast + s * yNext;
363 createAcceptablePoint(&firstPoint, &list, &xPrev, &yPrev, x, y);
368 distanceCompleted -= segmentLength;
386 return m_lines.count();
389 bool Segment::pointIsCloseToLine(
double xLeft,
396 double xProj, yProj, projectedDistanceOutsideLine, distanceToLine;
397 projectPointOntoLine(xInt, yInt, xLeft, yLeft, xRight, yRight, &xProj, &yProj, &projectedDistanceOutsideLine, &distanceToLine);
400 (xInt - xProj) * (xInt - xProj) +
401 (yInt - yProj) * (yInt - yProj) < 0.5 * 0.5);
404 bool Segment::pointsAreCloseToLine(
double xLeft,
406 QList<QPoint> removedPoints,
410 QList<QPoint>::iterator itr;
411 for (itr = removedPoints.begin(); itr != removedPoints.end(); ++itr) {
412 if (!pointIsCloseToLine(xLeft, yLeft, (
double) (*itr).x(), (double) (*itr).y(), xRight, yRight)) {
422 LOG4CPP_INFO_S ((*mainCat)) <<
"Segment::removeUnneededLines";
425 QTextStream *strDump = 0;
428 QString filename (
"segment.gnuplot");
430 std::cout <<
"Writing gnuplot file: " << filename.toLatin1().data() <<
"\n";
432 fileDump =
new QFile (filename);
433 fileDump->open (QIODevice::WriteOnly | QIODevice::Text);
434 strDump =
new QTextStream (fileDump);
443 QList<SegmentLine*>::iterator itr, itrPrevious;
444 QList<QPoint> removedPoints;
445 for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
448 ENGAUGE_CHECK_PTR(line);
450 if (linePrevious != 0) {
452 double xLeft = linePrevious->line().x1();
453 double yLeft = linePrevious->line().y1();
454 double xInt = linePrevious->line().x2();
455 double yInt = linePrevious->line().y2();
459 if (linePrevious->line().p2() == line->line().p1()) {
461 double xRight = line->line().x2();
462 double yRight = line->line().y2();
464 if (pointIsCloseToLine(xLeft, yLeft, xInt, yInt, xRight, yRight) &&
465 pointsAreCloseToLine(xLeft, yLeft, removedPoints, xRight, yRight)) {
470 dumpToGnuplot (*strDump,
480 LOG4CPP_DEBUG_S ((*mainCat)) <<
"Segment::removeUnneededLines" 481 <<
" segment=0x" << std::hex << (quintptr)
this << std::dec
483 << linePrevious->line().x1() <<
"," << linePrevious->line().y1() <<
") to (" 484 << linePrevious->line().x2() <<
"," << linePrevious->line().y2() <<
") " 485 <<
" and modifying (" 486 << line->line().x1() <<
"," << line->line().y1() <<
") to (" 487 << line->line().x2() <<
"," << line->line().y2() <<
") into (" 488 << xLeft <<
"," << yLeft <<
") to (" 489 << xRight <<
"," << yRight <<
")";
491 removedPoints.append(QPoint((
int) xInt, (
int) yInt));
492 m_lines.erase (itrPrevious);
496 line->setLine (xLeft, yLeft, xRight, yRight);
501 removedPoints.clear();
510 if (itr == m_lines.end()) {
518 *strDump <<
"set terminal x11 persist\n";
528 LOG4CPP_INFO_S ((*mainCat)) <<
"Segment::slotHover";
530 QList<SegmentLine*>::iterator itr, itrPrevious;
531 for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
540 LOG4CPP_INFO_S ((*mainCat)) <<
"Segment::updateModelSegment";
542 QList<SegmentLine*>::iterator itr;
543 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.
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.