Engauge Digitizer 2
Loading...
Searching...
No Matches
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.

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.

Public Member Functions

 Segment (QGraphicsScene &scene, int yLast, bool isGnuplot)
 Single constructor.
 ~Segment ()
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.
QPointF firstPoint () const
 Coordinates of first point in Segment.
void forwardMousePress ()
 Forward mouse press event from a component SegmentLine that was just clicked on.
double length () const
 Get method for length in pixels.
int lineCount () const
 Get method for number of lines.
void lockHoverState ()
 Disable hover events. This is used only by DlgSettingsSegments to stop hover events in the preview window.
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.
void updateModelSegment (const DocumentModelSegments &modelSegments)
 Update this segment given the new settings.

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::Segment ( QGraphicsScene & scene,
int yLast,
bool isGnuplot )

Single constructor.

Definition at line 23 of file Segment.cpp.

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

◆ ~Segment()

Segment::~Segment ( )

Definition at line 33 of file Segment.cpp.

34{
35 QList<SegmentLine*>::iterator itr;
36 for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
37
38 SegmentLine *segmentLine = *itr;
39 m_scene.removeItem (segmentLine);
40 }
41}

Member Function Documentation

◆ appendColumn()

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 43 of file Segment.cpp.

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

◆ fillPoints()

QList< QPoint > Segment::fillPoints ( const DocumentModelSegments & modelSegments)

Create evenly spaced points along the segment.

Definition at line 206 of file Segment.cpp.

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

◆ firstPoint()

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 282 of file Segment.cpp.

283{
284 LOG4CPP_INFO_S ((*mainCat)) << "Segment::firstPoint"
285 << " lineCount=" << m_lines.count();
286
287 // There has to be at least one SegmentLine since this only gets called when a SegmentLine is clicked on
288 ENGAUGE_ASSERT (m_lines.count () > 0);
289
290 SegmentLine *line = m_lines.first();
291 QPointF pos = line->line().p1();
292
293 LOG4CPP_INFO_S ((*mainCat)) << "Segment::firstPoint"
294 << " pos=" << QPointFToString (pos).toLatin1().data();
295
296 return pos;
297}
#define ENGAUGE_ASSERT(cond)
Drop in replacement for Q_ASSERT.
QString QPointFToString(const QPointF &pos)

◆ forwardMousePress()

void Segment::forwardMousePress ( )

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

Definition at line 299 of file Segment.cpp.

300{
301 LOG4CPP_INFO_S ((*mainCat)) << "Segment::forwardMousePress"
302 << " segmentLines=" << m_lines.count();
303
305}
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:282

◆ length()

double Segment::length ( ) const

Get method for length in pixels.

Definition at line 376 of file Segment.cpp.

377{
378 return m_length;
379}

◆ lineCount()

int Segment::lineCount ( ) const

Get method for number of lines.

Definition at line 381 of file Segment.cpp.

382{
383 return m_lines.count();
384}

◆ lockHoverState()

void Segment::lockHoverState ( )

Disable hover events. This is used only by DlgSettingsSegments to stop hover events in the preview window.

Definition at line 386 of file Segment.cpp.

387{
388 QList<SegmentLine*>::iterator itr;
389 for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
390
391 SegmentLine *line = *itr;
392 line->setAcceptHoverEvents (false);
393 }
394}

◆ removeUnneededLines()

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 432 of file Segment.cpp.

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

◆ signalMouseClickOnSegment

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.

◆ slotHover

void Segment::slotHover ( bool hover)
slot

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

Definition at line 539 of file Segment.cpp.

540{
541 LOG4CPP_INFO_S ((*mainCat)) << "Segment::slotHover";
542
543 QList<SegmentLine*>::iterator itr, itrPrevious;
544 for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
545
546 SegmentLine *line = *itr;
547 line->setHover(hover);
548 }
549}
void setHover(bool hover)
Apply/remove highlighting triggered by hover enter/leave.

◆ updateModelSegment()

void Segment::updateModelSegment ( const DocumentModelSegments & modelSegments)

Update this segment given the new settings.

Definition at line 551 of file Segment.cpp.

552{
553 LOG4CPP_INFO_S ((*mainCat)) << "Segment::updateModelSegment";
554
555 QList<SegmentLine*>::iterator itr;
556 for (itr = m_lines.begin(); itr != m_lines.end(); itr++) {
557
558 SegmentLine *line = *itr;
559 line->updateModelSegment (modelSegments);
560 }
561}
void updateModelSegment(const DocumentModelSegments &modelSegments)
Update this segment line with new settings.

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