-
even authored728a7172
blurredsegmentproto.cpp 6.63 KiB
#include "blurredsegmentproto.h"
BlurredSegmentProto::BlurredSegmentProto (int maxWidth, Pt2i pix)
{
this->maxWidth.set (maxWidth);
plist = new BiPtList (pix);
leftOK = false;
rightOK = false;
bsFlat = false;
bsOK = false;
convexhull = NULL;
chChanged = false;
dss = NULL;
}
BlurredSegmentProto::BlurredSegmentProto (int maxWidth, Pt2i center,
const vector<Pt2i> &leftPts, const vector<Pt2i> &rightPts)
{
this->maxWidth.set (maxWidth);
plist = new BiPtList (center);
leftOK = false;
rightOK = false;
bsFlat = false;
bsOK = false;
convexhull = NULL;
chChanged = false;
dss = NULL;
vector<Pt2i>::const_iterator itr = rightPts.begin ();
vector<Pt2i>::const_iterator itl = leftPts.begin ();
bool scanningRight = true;
bool scanningLeft = true;
while (scanningRight || scanningLeft)
{
if (scanningRight)
{
if (itr == rightPts.end ())
{
scanningRight = false;
rightOK = true;
}
else plist->addBack (*itr++);
}
if (scanningLeft)
{
if (itl == leftPts.end ()) scanningLeft = false;
else
{
plist->addFront (*itl++);
leftOK = true;
}
}
if (! bsOK && plist->size () > 2)
{
if (! plist->backPoint().colinearTo (plist->frontPoint (),
plist->initialPoint ()))
bsOK = true;
}
}
}
BlurredSegmentProto::~BlurredSegmentProto ()
{
if (convexhull != NULL) delete convexhull;
}
AbsRat BlurredSegmentProto::segmentRationalWidth () const
{
return (convexhull != NULL ? convexhull->rationalThickness ()
: AbsRat (0, 1));
}
DigitalStraightLine *BlurredSegmentProto::getLine () const
{
if (bsOK)
{
Pt2i s, e, v;
convexhull->antipodalEdgeAndVertex (s, e, v);
return (new DigitalStraightLine (s, e, v));
}
if (bsFlat) return (new DigitalStraightLine (getLastLeft (), getLastRight (),
DigitalStraightLine::DSL_THIN));
return (NULL);
}
bool BlurredSegmentProto::addLeft (Pt2i pix)
{
if (bsOK) // convexhull defined
{
bool res = addPoint (pix, true);
return (res);
}
else if (bsFlat) // leftOK && rightOK
{
AbsRat height = plist->heightToEnds (pix);
if (height.greaterThan (maxWidth)) return false;
if (height.numerator () != 0)
{
convexhull = new ConvexHull (pix, plist->frontPoint (),
plist->backPoint ());
bsOK = true;
}
plist->addFront (pix);
}
else if (leftOK) // thus ! rightOK
{
AbsRat height = plist->heightToEnds (pix);
if (height.greaterThan (maxWidth)) return false;
if (height.numerator () == 0) bsFlat = true;
else
{
convexhull = new ConvexHull (pix, plist->frontPoint (),
plist->backPoint ());
bsOK = true;
}
plist->addFront (pix);
}
else if (rightOK)
{
AbsRat height = plist->heightToEnds (pix);
if (height.greaterThan (maxWidth)) return false;
if (height.numerator () == 0) bsFlat = true;
else
{
convexhull = new ConvexHull (pix, plist->frontPoint (),
plist->backPoint ());
bsOK = true;
}
plist->addFront (pix);
}
else // only the central point is ok
{
plist->addFront (pix);
leftOK = true;
}
chChanged = true;
return true;
}
bool BlurredSegmentProto::addRight (Pt2i pix)
{
if (bsOK) // bs != NULL
{
bool res = addPoint (pix, false);
return (res);
}
else if (bsFlat) // leftOK && rightOK
{
AbsRat height = plist->heightToEnds (pix);
if (height.greaterThan (maxWidth)) return false;
if (height.numerator () != 0)
{
convexhull = new ConvexHull (plist->frontPoint (),
plist->backPoint (), pix);
bsOK = true;
}
plist->addBack (pix);
}
else if (rightOK) // thus ! leftOK
{
AbsRat height = plist->heightToEnds (pix);
if (height.greaterThan (maxWidth)) return false;
if (height.numerator () == 0) bsFlat = true;
else
{
convexhull = new ConvexHull (plist->frontPoint (),
plist->backPoint (), pix);
bsOK = true;
}
plist->addBack (pix);
}
else if (leftOK)
{
AbsRat height = plist->heightToEnds (pix);
if (height.greaterThan (maxWidth)) return false;
if (height.numerator () == 0) bsFlat = true;
else
{
convexhull = new ConvexHull (plist->frontPoint (),
plist->backPoint (), pix);
bsOK = true;
}
plist->addBack (pix);
}
else // only the central point is ok
{
plist->addBack (pix);
rightOK = true;
}
chChanged = true;
return true;
}
bool BlurredSegmentProto::addPoint (Pt2i p, bool onleft)
{
bool inserted = convexhull->addPointDS (p, onleft);
if ((segmentRationalWidth ()).greaterThan (maxWidth))
{
if (inserted) convexhull->restore ();
return false;
}
if (onleft) plist->addFront (p);
else plist->addBack (p);
chChanged = true;
return true;
}
void BlurredSegmentProto::removeLeft (int n)
{
if (bsOK) plist->removeFront (n);
}
void BlurredSegmentProto::removeRight (int n)
{
if (bsOK) plist->removeBack (n);
}
Vr2i BlurredSegmentProto::getSupportVector ()
{
if (bsOK)
{
Pt2i s, e, v;
convexhull->antipodalEdgeAndVertex (s, e, v);
return (s.vectorTo (e));
}
if (bsFlat || leftOK || rightOK)
return (getLastLeft().vectorTo (getLastRight ()));
return (Vr2i (1, 0)); // hardly better with only one point !
}
BlurredSegment *BlurredSegmentProto::endOfBirth ()
{
DigitalStraightSegment *seg = NULL;
if (bsOK)
{
int xmin, ymin, xmax, ymax;
plist->findExtrema (xmin, ymin, xmax, ymax);
Pt2i s, e, v;
convexhull->antipodalEdgeAndVertex (s, e, v);
seg = new DigitalStraightSegment (s, e, v, xmin, ymin, xmax, ymax);
}
else if (bsFlat || rightOK || leftOK)
{
Pt2i llast = plist->frontPoint ();
Pt2i rlast = plist->backPoint ();
int xmin = llast.x ();
if (rlast.x () < llast.x ()) xmin = rlast.x ();
int ymin = llast.y ();
if (rlast.y () < llast.y ()) ymin = rlast.y ();
int xmax = llast.x ();
if (rlast.x () > llast.x ()) xmax = rlast.x ();
int ymax = llast.y ();
if (rlast.y () > llast.y ()) ymax = rlast.y ();
seg = new DigitalStraightSegment (llast, rlast,
DigitalStraightLine::DSL_THIN,
xmin, ymin, xmax, ymax);
}
BlurredSegment *bbs = new BlurredSegment (plist, seg);
plist = NULL; // NECESSARY TO AVOID CONTENTS CLEARANCE !!!
return (bbs);
}