Browse files

Made the Convex Hull calculation abstract.

  • Loading branch information...
1 parent 18df022 commit 092e7749549a3bc3ec35535de82dc213c46fc566 @mdfeist committed Jun 6, 2013
Showing with 85 additions and 74 deletions.
  1. +71 −65 BlinkAnalysis/EyeCalibration.cpp
  2. +14 −9 BlinkAnalysis/EyeCalibration.h
View
136 BlinkAnalysis/EyeCalibration.cpp
@@ -127,6 +127,68 @@ int EyeCalibration::isLeft(Segment segment, CalibrationPoint r) {
return 0;
}
+std::vector<EyeCalibration::Segment> EyeCalibration::calculateConvexHull(std::vector<CalibrationPoint> processingPoints) {
+ // Edges
+ std::vector<Segment> segments;
+
+ // Ordered Point
+ std::vector<CalibrationPoint> orderedPoints(processingPoints);
+
+ // Sort Points
+ std::sort (orderedPoints.begin(), orderedPoints.end(), ComparePoints(this));
+
+ // Create segments
+ for (unsigned int i = 0; i < orderedPoints.size(); i++) {
+ CalibrationPoint from = orderedPoints.at(i);
+
+ for (unsigned int k = 0; k < orderedPoints.size(); k++) {
+ if (i == k)
+ continue;
+
+ CalibrationPoint to = orderedPoints.at(k);
+
+ Segment segment(from, to);
+ segments.push_back(segment);
+ }
+ }
+
+ unsigned int i = 0;
+ unsigned int j = 0;
+ while ( i < segments.size() )
+ {
+ //ProcessingPoints will be the points that are not in the current segment
+ std::vector<CalibrationPoint> processingPoints(orderedPoints);
+ Segment segment = segments.at(i);
+
+ //this loop prepares the ProcessingPoints list for each segment
+ while ( j < processingPoints.size() )
+ {
+ CalibrationPoint point = processingPoints.at(j);
+ if((segment.x1() == point.x() && segment.y1() == point.y()) ||
+ (segment.x2() == point.x() && segment.y2() == point.y()))
+ {
+ //eliminating the points that are already in the current segment...
+ //we don't need them
+ processingPoints.erase(processingPoints.begin()+j);
+ j = 0;
+ } else {
+ j++;
+ }
+ }
+
+ //checking if the current segment is an edge or notBy calling isEdge function
+ if( !isEdge(processingPoints, segments.at(i)) )
+ {
+ segments.erase(segments.begin()+i);
+ i = 0;
+ } else {
+ i++;
+ }
+ }
+
+ return segments;
+}
+
bool EyeCalibration::calibrate() {
char buf[512];
@@ -201,71 +263,15 @@ bool EyeCalibration::calibrate() {
// Ordered Point
std::vector<CalibrationPoint> orderedPoints(calibrationPoints);
-
// Sort Points
- EyeCalibrationWizardFormController::getInstance()->calibrationOutputLog("Ordering Points ...\n");
std::sort (orderedPoints.begin(), orderedPoints.end(), ComparePoints(this));
- EyeCalibrationWizardFormController::getInstance()->calibrationOutputLog("Ordered Points\n");
- // Clearing previous segments
- segments.clear();
- EyeCalibrationWizardFormController::getInstance()->calibrationOutputLog("Cleared Previous Convex Hull\n");
-
- // Create segments
- for (unsigned int i = 0; i < orderedPoints.size(); i++) {
- CalibrationPoint from = orderedPoints.at(i);
-
- for (unsigned int k = 0; k < orderedPoints.size(); k++) {
- if (i == k)
- continue;
-
- CalibrationPoint to = orderedPoints.at(k);
-
- Segment segment(from, to);
- segments.push_back(segment);
- }
- }
-
// Calculate Convex Hull
- {
- unsigned int i = 0;
- unsigned int j = 0;
- while ( i < segments.size() )
- {
- //ProcessingPoints will be the points that are not in the current segment
- std::vector<CalibrationPoint> processingPoints(orderedPoints);
- Segment segment = segments.at(i);
-
- //this loop prepares the ProcessingPoints list for each segment
- while ( j < processingPoints.size() )
- {
- CalibrationPoint point = processingPoints.at(j);
- if((segment.x1() == point.x() && segment.y1() == point.y()) ||
- (segment.x2() == point.x() && segment.y2() == point.y()))
- {
- //eliminating the points that are already in the current segment...
- //we don't need them
- processingPoints.erase(processingPoints.begin()+j);
- j = 0;
- } else {
- j++;
- }
- }
-
- //checking if the current segment is an edge or notBy calling isEdge function
- if( !isEdge(processingPoints, segments.at(i)) )
- {
- segments.erase(segments.begin()+i);
- i = 0;
- } else {
- i++;
- }
- }
- }
+ this->convexHull = calculateConvexHull(calibrationPoints);
// Print each segment information
- for (unsigned int i = 0; i < segments.size(); i++) {
- Segment segment = segments.at(i);
+ for (unsigned int i = 0; i < convexHull.size(); i++) {
+ Segment segment = convexHull.at(i);
sprintf_s(buf, "Edge %d: From (%d, %d) to (%d, %d)\n",
i + 1,
segment.x1(), segment.y1(),
@@ -282,7 +288,7 @@ bool EyeCalibration::calibrate() {
for (unsigned int i = 0; i < orderedPoints.size(); i++) {
CalibrationPoint point = orderedPoints.at(i);
- if (pointInPolygon(point))
+ if (pointInPolygon(convexHull, point))
innerPoints.push_back(point);
else
convexHullPoints.push_back(point);
@@ -331,7 +337,7 @@ bool EyeCalibration::calibrate() {
if (!alreadyKnown) {
// Check if point is inside the convex hull
- if (pointInPolygon(point)) {
+ if (pointInPolygon(convexHull, point)) {
innerUnknownPoints.push_back(point);
} else {
outerUnknownPoints.push_back(point);
@@ -353,17 +359,17 @@ bool EyeCalibration::calibrate() {
return true;
}
-bool EyeCalibration::pointInPolygon(CalibrationPoint point) {
+bool EyeCalibration::pointInPolygon(std::vector<Segment> hull, CalibrationPoint point) {
- unsigned int n = segments.size();
+ unsigned int n = hull.size();
if (n < 3)
false;
// loop through all edges of the polygon
for (unsigned int i = 0; i < n; i++)
{
- Segment segment = segments.at(i);
+ Segment segment = hull.at(i);
if(isLeft(segment, point) >= 0)
return false;
@@ -375,7 +381,7 @@ bool EyeCalibration::pointInPolygon(CalibrationPoint point) {
void EyeCalibration::testPointInPolygon(CalibrationPoint point) {
char buf[512];
- if (pointInPolygon(point)) {
+ if (pointInPolygon(convexHull, point)) {
sprintf_s(buf, "Point (%d, %d) is inside.\n", point.x(), point.y());
EyeCalibrationWizardFormController::getInstance()->calibrationOutputLog(buf);
} else {
View
23 BlinkAnalysis/EyeCalibration.h
@@ -26,18 +26,21 @@ class EyeCalibration {
class Segment {
private:
- CalibrationPoint p1, p2;
+ CalibrationPoint _p1, _p2;
public:
Segment() {}
Segment(CalibrationPoint from, CalibrationPoint to) {
- this->p1 = from;
- this->p2 = to;
+ _p1 = from;
+ _p2 = to;
}
- int x1() { return this->p1.x(); }
- int y1() { return this->p1.y(); }
- int x2() { return this->p2.x(); }
- int y2() { return this->p2.y(); }
+ CalibrationPoint p1() { return _p1; }
+ CalibrationPoint p2() { return _p2; }
+
+ int x1() { return _p1.x(); }
+ int y1() { return _p1.y(); }
+ int x2() { return _p2.x(); }
+ int y2() { return _p2.y(); }
};
int rbHeadId;
@@ -47,14 +50,16 @@ class EyeCalibration {
char* getNameById(int id);
std::vector<CalibrationPoint> calibrationPoints;
- std::vector<Segment> segments;
+ std::vector<Segment> convexHull;
int center_x, center_y;
bool isLess(CalibrationPoint a, CalibrationPoint b);
bool isEdge(std::vector<CalibrationPoint> processingPoints, Segment edge);
int isLeft(Segment segment, CalibrationPoint r);
+ std::vector<Segment> calculateConvexHull(std::vector<CalibrationPoint> processingPoints);
+
struct ComparePoints : std::binary_function<CalibrationPoint, CalibrationPoint, bool> {
ComparePoints(EyeCalibration * cal) : _cal(cal) {}
bool operator() (CalibrationPoint a, CalibrationPoint b) const {
@@ -94,7 +99,7 @@ class EyeCalibration {
bool addPoint();
bool calibrate();
- bool pointInPolygon(CalibrationPoint point);
+ bool pointInPolygon(std::vector<Segment> hull, CalibrationPoint point);
void testPointInPolygon(CalibrationPoint point);
void createTestData();

0 comments on commit 092e774

Please sign in to comment.