CvContourPolygon *cvPolygonContourConvexHull(CvContourPolygon const *p) { CV_FUNCNAME("cvPolygonContourConvexHull"); __CV_BEGIN__; { CV_ASSERT(p!=NULL); if (p->size()<=3) { return new CvContourPolygon(p->begin(), p->end()); } deque<CvPoint> dq; if (cvCrossProductPoints((*p)[0], (*p)[1], (*p)[2])>0) { dq.push_back((*p)[0]); dq.push_back((*p)[1]); } else { dq.push_back((*p)[1]); dq.push_back((*p)[0]); } dq.push_back((*p)[2]); dq.push_front((*p)[2]); for (unsigned int i=3; i<p->size(); i++) { int s = dq.size(); if ((cvCrossProductPoints((*p)[i], dq.at(0), dq.at(1))>=0) && (cvCrossProductPoints(dq.at(s-2), dq.at(s-1), (*p)[i])>=0)) continue; // TODO Optimize. while (cvCrossProductPoints(dq.at(s-2), dq.at(s-1), (*p)[i])<0) { dq.pop_back(); s = dq.size(); } dq.push_back((*p)[i]); while (cvCrossProductPoints((*p)[i], dq.at(0), dq.at(1))<0) dq.pop_front(); dq.push_front((*p)[i]); } return new CvContourPolygon(dq.begin(), dq.end()); } __CV_END__; }
double cvDistanceLinePoint(CvPoint const &a, CvPoint const &b, CvPoint const &c, bool isSegment) { if (isSegment) { double dot1 = cvDotProductPoints(a, b, c); if (dot1>0) return cvDistancePointPoint(b, c); double dot2 = cvDotProductPoints(b, a, c); if(dot2>0) return cvDistancePointPoint(a, c); } return fabs(cvCrossProductPoints(a,b,c)/cvDistancePointPoint(a,b)); }