1 #include "grahams_scan.h"
3 static const double Epsilon = 0.000001;
5 GrahamsScan::GrahamsScan()
10 GrahamsScan::~GrahamsScan()
15 std::vector< vector2f, std::allocator< vector2f > > GrahamsScan::run(vector< vector2f > points)
17 static const bool debug =
false;
18 vector<vector2f> convexPolygon;
19 convexPolygon.clear();
22 NumPoints = int(points.size());
28 if(debug) printf(
"\nGraham scan:\n");
29 for (
int k=1;k<NumPoints;k++){
31 printf(
"%d. %7.4f , %7.4f\n",k,V2COMP(points[k]));
32 if( (points[k].y==points[minPoint].y && points[k].x<points[minPoint].x) ||
33 (points[k].y<points[minPoint].y) )
37 if(debug) printf(
"%d points, minPoint:%d\n",NumPoints, minPoint);
44 for (
int i=0;i<NumPoints;i++){
46 p.angle = findAngle(points[minPoint],points[i]);
52 tempPtr=tempPtr->next;
53 }
while (tempPtr->next!=NULL);
55 tempPtr->next=firstPoint;
56 firstPoint->prev=tempPtr;
60 printf(
"Sorted list:\n");
62 printf(
"%d. %7.4f , %7.4f (%7.4f , %7.4f @ %.7f\u00b0)\n",k,V2COMP(tempPtr->loc),V2COMP(tempPtr->loc-firstPoint->loc), DEG((tempPtr->loc-firstPoint->loc).angle()));
63 tempPtr=tempPtr->next;
65 }
while (tempPtr!=firstPoint);
66 printf(
"Checking Convexity:\n");
68 grahamScan(firstPoint);
71 for (
int i=0;i<NumPoints;i++)
73 convexPolygon.push_back(tempPtr->loc);
74 tempPtr=tempPtr->next;
75 if(tempPtr==firstPoint)
84 static const bool debug =
false;
85 point *tempPrev, *tempNext;
88 while(P!=firstPoint && !isConvexPoint(P)){
89 if(P->prev==firstPoint){
92 tempPrev->next=tempNext;
93 tempNext->prev=tempPrev;
94 if(debug) printf(
"deleting colinear point %f,%f\n",V2COMP(P->loc));
100 tempPrev->next=tempNext;
101 tempNext->prev=tempPrev;
102 if(debug) printf(
"deleting non-convex point %f,%f\n",V2COMP(P->loc));
107 if(debug) printf(
"accepting convex point %f,%f\n",V2COMP(P->loc));
109 }
while(P != firstPoint);
115 return (P->loc - P->prev->loc).cross(P->next->loc - P->loc) > 0.0;
127 double d = delta.
length();
128 if(fabs(delta.x)<DBL_MIN){
133 }
else if(delta.x>0.0){
137 return 1.0 - delta.x/d;
139 return -1.0 + delta.x/d;
143 void GrahamsScan::addPoint(point& Point)
145 static const bool debug =
false;
146 point *tempPoint,*tempPointA,*tempPointB, *curPoint;
149 tempPoint =
new point;
150 tempPoint->loc = Point.loc;
151 tempPoint->angle=Point.angle;
152 tempPoint->next=NULL;
153 tempPoint->prev=NULL;
156 if (firstPoint==NULL){
157 firstPoint=tempPoint;
162 if (firstPoint->next==NULL && tempPoint->angle >= firstPoint->angle){
163 firstPoint->next=tempPoint;
164 tempPoint->prev=firstPoint;
171 while ((tempPoint->angle > curPoint->angle || (tempPoint->angle + Epsilon > curPoint->angle && tempPoint->loc.y > curPoint->loc.y) )&& curPoint->next!=NULL)
172 curPoint=curPoint->next;
175 if(curPoint->prev != NULL){
176 if(curPoint->prev->loc==tempPoint->loc)
181 if (curPoint==firstPoint){
182 if(debug) printf(
"Adding %f,%f at the front\n",V2COMP(tempPoint->loc));
183 firstPoint->prev=tempPoint;
184 tempPoint->next=firstPoint;
185 firstPoint=tempPoint;
187 }
else if(curPoint->next==NULL && tempPoint->angle >= curPoint->angle){
189 if(debug) printf(
"Adding %f,%f at the end\n",V2COMP(tempPoint->loc));
190 curPoint->next=tempPoint;
191 tempPoint->prev=curPoint;
194 tempPointA=curPoint->prev;
195 tempPointB=curPoint->prev->next;
196 if(debug) printf(
"Adding %f,%f after %f,%f\n",V2COMP(tempPoint->loc),V2COMP(tempPointA->loc));
197 tempPoint->next=tempPointB;
198 tempPoint->prev=tempPointA;
199 tempPoint->prev->next=tempPoint;
200 tempPoint->next->prev=tempPoint;
207 void GrahamsScan::deleteAllPoints()
209 point *curPtr = firstPoint;
210 point *nextPtr = curPtr->next;
212 while(curPtr != NULL){
213 nextPtr = curPtr->next;
216 if(curPtr==firstPoint)
220 mzero<GrahamsScan>(*this);
num length() const MustUseResult
calculate Euclidean length