Engauge Digitizer  2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Public Slots | Signals | Public Member Functions | List of all members
Segment Class Reference

Selectable piecewise-defined line that follows a filtered line in the image. More...

#include <Segment.h>

Inheritance diagram for Segment:
Inheritance graph
Collaboration diagram for Segment:
Collaboration graph

Public Slots

void slotHover (bool hover)
 Slot for hover enter/leave events in the associated SegmentLines. More...
 

Signals

void signalMouseClickOnSegment (QPointF posSegmentStart)
 Pass mouse press event, with coordinates of first point in the Segment since that info uniquely identifies the owning Segment. More...
 

Public Member Functions

 Segment (QGraphicsScene &scene, int yLast, bool isGnuplot)
 Single constructor. More...
 
 ~Segment ()
 
void appendColumn (int x, int y, const DocumentModelSegments &modelSegments)
 Add some more pixels in a new column to an active segment. More...
 
QList< QPoint > fillPoints (const DocumentModelSegments &modelSegments)
 Create evenly spaced points along the segment. More...
 
QPointF firstPoint () const
 Coordinates of first point in Segment. More...
 
void forwardMousePress ()
 Forward mouse press event from a component SegmentLine that was just clicked on. More...
 
double length () const
 Get method for length in pixels. More...
 
int lineCount () const
 Get method for number of lines. More...
 
void removeUnneededLines (int *foldedLines)
 Try to compress a segment that was just completed, by folding together line from point i to point i+1, with the line from i+1 to i+2, then the line from i+2 to i+3, until one of the points is more than a half pixel from the folded line. More...
 
void updateModelSegment (const DocumentModelSegments &modelSegments)
 Update this segment given the new settings. More...
 

Detailed Description

Selectable piecewise-defined line that follows a filtered line in the image.

Clicking on a Segment results in the immediate creation of multiple Points along that Segment.

Definition at line 21 of file Segment.h.

Constructor & Destructor Documentation

Segment::Segment ( QGraphicsScene &  scene,
int  yLast,
bool  isGnuplot 
)

Single constructor.

Definition at line 22 of file Segment.cpp.

24  :
25  m_scene (scene),
26  m_yLast (y),
27  m_length (0),
28  m_isGnuplot (isGnuplot)
29 {
30 }
Segment::~Segment ( )

Definition at line 32 of file Segment.cpp.

33 {
34  QList<SegmentLine*>::iterator itr;
35  for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
36 
37  SegmentLine *segmentLine = *itr;
38  m_scene.removeItem (segmentLine);
39  }
40 }
This class is a special case of the standard QGraphicsLineItem for segments.
Definition: SegmentLine.h:17

Member Function Documentation

void Segment::appendColumn ( int  x,
int  y,
const DocumentModelSegments modelSegments 
)

Add some more pixels in a new column to an active segment.

Definition at line 42 of file Segment.cpp.

45 {
46  int xOld = x - 1;
47  int yOld = m_yLast;
48  int xNew = x;
49  int yNew = y;
50 
51  LOG4CPP_DEBUG_S ((*mainCat)) << "Segment::appendColumn"
52  << " segment=0x" << std::hex << static_cast<void*> (this) << std::dec
53  << " adding ("
54  << xOld << "," << yOld << ") to ("
55  << xNew << "," << yNew << ")";
56 
57  SegmentLine* line = new SegmentLine(m_scene,
58  modelSegments,
59  this);
60  ENGAUGE_CHECK_PTR(line);
61  line->setLine(QLineF (xOld,
62  yOld,
63  xNew,
64  yNew));
65 
66  // Do not show this line or its segment. this is handled later
67 
68  m_lines.append(line);
69 
70  // Update total length using distance formula
71  m_length += qSqrt((1.0) * (1.0) + (y - m_yLast) * (y - m_yLast));
72 
73  m_yLast = y;
74 }
#define ENGAUGE_CHECK_PTR(ptr)
#endif
Definition: EngaugeAssert.h:27
log4cpp::Category * mainCat
Definition: Logger.cpp:14
This class is a special case of the standard QGraphicsLineItem for segments.
Definition: SegmentLine.h:17
#define LOG4CPP_DEBUG_S(logger)
Definition: convenience.h:20
QList< QPoint > Segment::fillPoints ( const DocumentModelSegments modelSegments)

Create evenly spaced points along the segment.

Definition at line 205 of file Segment.cpp.

206 {
207  LOG4CPP_INFO_S ((*mainCat)) << "Segment::fillPoints";
208 
209  if (modelSegments.fillCorners()) {
210  return fillPointsFillingCorners(modelSegments);
211  } else {
212  return fillPointsWithoutFillingCorners(modelSegments);
213  }
214 }
#define LOG4CPP_INFO_S(logger)
Definition: convenience.h:18
log4cpp::Category * mainCat
Definition: Logger.cpp:14
bool fillCorners() const
Get method for fill corners.
QPointF Segment::firstPoint ( ) const

Coordinates of first point in Segment.

This info can be used to uniquely identify a Segment. This method relies on SegmentFactory::removeEmptySegments to guarantee every Segment has at least one line

Definition at line 281 of file Segment.cpp.

282 {
283  LOG4CPP_INFO_S ((*mainCat)) << "Segment::firstPoint"
284  << " lineCount=" << m_lines.count();
285 
286  // There has to be at least one SegmentLine since this only gets called when a SegmentLine is clicked on
287  ENGAUGE_ASSERT (m_lines.count () > 0);
288 
289  SegmentLine *line = m_lines.first();
290  QPointF pos = line->line().p1();
291 
292  LOG4CPP_INFO_S ((*mainCat)) << "Segment::firstPoint"
293  << " pos=" << QPointFToString (pos).toLatin1().data();
294 
295  return pos;
296 }
#define LOG4CPP_INFO_S(logger)
Definition: convenience.h:18
QString QPointFToString(const QPointF &pos)
Definition: QtToString.cpp:17
log4cpp::Category * mainCat
Definition: Logger.cpp:14
This class is a special case of the standard QGraphicsLineItem for segments.
Definition: SegmentLine.h:17
#define ENGAUGE_ASSERT(cond)
Drop in replacement for Q_ASSERT if defined(QT_NO_DEBUG) &amp;&amp; !defined(QT_FORCE_ASSERTS) define ENGAUGE...
Definition: EngaugeAssert.h:20
void Segment::forwardMousePress ( )

Forward mouse press event from a component SegmentLine that was just clicked on.

Definition at line 298 of file Segment.cpp.

299 {
300  LOG4CPP_INFO_S ((*mainCat)) << "Segment::forwardMousePress"
301  << " segmentLines=" << m_lines.count();
302 
304 }
#define LOG4CPP_INFO_S(logger)
Definition: convenience.h:18
log4cpp::Category * mainCat
Definition: Logger.cpp:14
void signalMouseClickOnSegment(QPointF posSegmentStart)
Pass mouse press event, with coordinates of first point in the Segment since that info uniquely ident...
QPointF firstPoint() const
Coordinates of first point in Segment.
Definition: Segment.cpp:281
double Segment::length ( ) const

Get method for length in pixels.

Definition at line 375 of file Segment.cpp.

376 {
377  return m_length;
378 }
int Segment::lineCount ( ) const

Get method for number of lines.

Definition at line 380 of file Segment.cpp.

381 {
382  return m_lines.count();
383 }
void Segment::removeUnneededLines ( int *  foldedLines)

Try to compress a segment that was just completed, by folding together line from point i to point i+1, with the line from i+1 to i+2, then the line from i+2 to i+3, until one of the points is more than a half pixel from the folded line.

this should save memory and improve user interface responsiveness

Definition at line 421 of file Segment.cpp.

422 {
423  LOG4CPP_INFO_S ((*mainCat)) << "Segment::removeUnneededLines";
424 
425  QFile *fileDump = nullptr;
426  QTextStream *strDump = nullptr;
427  if (m_isGnuplot) {
428 
429  QString filename ("segment.gnuplot");
430 
431  std::cout << GNUPLOT_FILE_MESSAGE.toLatin1().data() << filename.toLatin1().data() << "\n";
432 
433  fileDump = new QFile (filename);
434  fileDump->open (QIODevice::WriteOnly | QIODevice::Text);
435  strDump = new QTextStream (fileDump);
436 
437  }
438 
439  // Pathological case is y=0.001*x*x, since the small slope can fool a naive algorithm
440  // into optimizing away all but one point at the origin and another point at the far right.
441  // From this we see that we cannot simply throw away points that were optimized away since they
442  // are needed later to see if we have diverged from the curve
443  SegmentLine *linePrevious = nullptr; // Previous line which corresponds to itrPrevious
444  QList<SegmentLine*>::iterator itr, itrPrevious;
445  QList<QPoint> removedPoints;
446  for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
447 
448  SegmentLine *line = *itr;
449  ENGAUGE_CHECK_PTR(line);
450 
451  if (linePrevious != nullptr) {
452 
453  double xLeft = linePrevious->line().x1();
454  double yLeft = linePrevious->line().y1();
455  double xInt = linePrevious->line().x2();
456  double yInt = linePrevious->line().y2();
457 
458  // If linePrevious is the last line of one Segment and line is the first line of another Segment then
459  // it makes no sense to remove any point so we continue the loop
460  if (linePrevious->line().p2() == line->line().p1()) {
461 
462  double xRight = line->line().x2();
463  double yRight = line->line().y2();
464 
465  if (pointIsCloseToLine(xLeft, yLeft, xInt, yInt, xRight, yRight) &&
466  pointsAreCloseToLine(xLeft, yLeft, removedPoints, xRight, yRight)) {
467 
468  if (m_isGnuplot) {
469 
470  // Dump
471  dumpToGnuplot (*strDump,
472  qFloor (xInt),
473  qFloor (yInt),
474  linePrevious,
475  line);
476  }
477 
478  // Remove intermediate point, by removing older line and stretching new line to first point
479  ++(*foldedLines);
480 
481  LOG4CPP_DEBUG_S ((*mainCat)) << "Segment::removeUnneededLines"
482  << " segment=0x" << std::hex << static_cast<void*> (this) << std::dec
483  << " removing ("
484  << linePrevious->line().x1() << "," << linePrevious->line().y1() << ") to ("
485  << linePrevious->line().x2() << "," << linePrevious->line().y2() << ") "
486  << " and modifying ("
487  << line->line().x1() << "," << line->line().y1() << ") to ("
488  << line->line().x2() << "," << line->line().y2() << ") into ("
489  << xLeft << "," << yLeft << ") to ("
490  << xRight << "," << yRight << ")";
491 
492  removedPoints.append(QPoint(qFloor (xInt),
493  qFloor (yInt)));
494  m_lines.erase (itrPrevious);
495  delete linePrevious;
496 
497  // New line
498  line->setLine (xLeft, yLeft, xRight, yRight);
499 
500  } else {
501 
502  // Keeping this intermediate point and clear out the removed points list
503  removedPoints.clear();
504  }
505  }
506  }
507 
508  linePrevious = line;
509  itrPrevious = itr;
510 
511  // This theoretically should not be needed, but for some reason modifying the last point triggers a segfault
512  if (itr == m_lines.end()) {
513  break;
514  }
515  }
516 
517  if (strDump != nullptr) {
518 
519  // Final gnuplot processing
520  *strDump << "set terminal x11 persist\n";
521  fileDump->close ();
522  delete strDump;
523  delete fileDump;
524 
525  }
526 }
#define LOG4CPP_INFO_S(logger)
Definition: convenience.h:18
const QString GNUPLOT_FILE_MESSAGE
#define ENGAUGE_CHECK_PTR(ptr)
#endif
Definition: EngaugeAssert.h:27
log4cpp::Category * mainCat
Definition: Logger.cpp:14
This class is a special case of the standard QGraphicsLineItem for segments.
Definition: SegmentLine.h:17
#define LOG4CPP_DEBUG_S(logger)
Definition: convenience.h:20
void Segment::signalMouseClickOnSegment ( QPointF  posSegmentStart)
signal

Pass mouse press event, with coordinates of first point in the Segment since that info uniquely identifies the owning Segment.

void Segment::slotHover ( bool  hover)
slot

Slot for hover enter/leave events in the associated SegmentLines.

Definition at line 528 of file Segment.cpp.

529 {
530  LOG4CPP_INFO_S ((*mainCat)) << "Segment::slotHover";
531 
532  QList<SegmentLine*>::iterator itr, itrPrevious;
533  for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
534 
535  SegmentLine *line = *itr;
536  line->setHover(hover);
537  }
538 }
#define LOG4CPP_INFO_S(logger)
Definition: convenience.h:18
log4cpp::Category * mainCat
Definition: Logger.cpp:14
This class is a special case of the standard QGraphicsLineItem for segments.
Definition: SegmentLine.h:17
void setHover(bool hover)
Apply/remove highlighting triggered by hover enter/leave.
Definition: SegmentLine.cpp:72
void Segment::updateModelSegment ( const DocumentModelSegments modelSegments)

Update this segment given the new settings.

Definition at line 540 of file Segment.cpp.

541 {
542  LOG4CPP_INFO_S ((*mainCat)) << "Segment::updateModelSegment";
543 
544  QList<SegmentLine*>::iterator itr;
545  for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
546 
547  SegmentLine *line = *itr;
548  line->updateModelSegment (modelSegments);
549  }
550 }
void updateModelSegment(const DocumentModelSegments &modelSegments)
Update this segment line with new settings.
Definition: SegmentLine.cpp:88
#define LOG4CPP_INFO_S(logger)
Definition: convenience.h:18
log4cpp::Category * mainCat
Definition: Logger.cpp:14
This class is a special case of the standard QGraphicsLineItem for segments.
Definition: SegmentLine.h:17

The documentation for this class was generated from the following files: