Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef GRAHAM_SCAN_2D_CONVEX_HULL_H
00018 #define GRAHAM_SCAN_2D_CONVEX_HULL_H
00019
00020
00021 #include "btVector3.h"
00022 #include "btAlignedObjectArray.h"
00023
00024 struct GrahamVector2 : public btVector3
00025 {
00026 GrahamVector2(const btVector3& org, int orgIndex)
00027 :btVector3(org),
00028 m_orgIndex(orgIndex)
00029 {
00030 }
00031 btScalar m_angle;
00032 int m_orgIndex;
00033 };
00034
00035
00036 struct btAngleCompareFunc {
00037 btVector3 m_anchor;
00038 btAngleCompareFunc(const btVector3& anchor)
00039 : m_anchor(anchor)
00040 {
00041 }
00042 bool operator()(const GrahamVector2& a, const GrahamVector2& b) {
00043 if (a.m_angle != b.m_angle)
00044 return a.m_angle < b.m_angle;
00045 else
00046 {
00047 btScalar al = (a-m_anchor).length2();
00048 btScalar bl = (b-m_anchor).length2();
00049 if (al != bl)
00050 return al < bl;
00051 else
00052 {
00053 return a.m_orgIndex < b.m_orgIndex;
00054 }
00055 }
00056 }
00057 };
00058
00059 inline void GrahamScanConvexHull2D(btAlignedObjectArray<GrahamVector2>& originalPoints, btAlignedObjectArray<GrahamVector2>& hull)
00060 {
00061 if (originalPoints.size()<=1)
00062 {
00063 for (int i=0;i<originalPoints.size();i++)
00064 hull.push_back(originalPoints[0]);
00065 return;
00066 }
00067
00068
00069 for (int i=0;i<originalPoints.size();i++)
00070 {
00071 const btVector3& left = originalPoints[i];
00072 const btVector3& right = originalPoints[0];
00073 if (left.x() < right.x() || !(right.x() < left.x()) && left.y() < right.y())
00074 {
00075 originalPoints.swap(0,i);
00076 }
00077 }
00078
00079 for (int i=0;i<originalPoints.size();i++)
00080 {
00081 btVector3 xvec(1,0,0);
00082 btVector3 ar = originalPoints[i]-originalPoints[0];
00083 originalPoints[i].m_angle = btCross(xvec, ar).dot(btVector3(0,0,1)) / ar.length();
00084 }
00085
00086
00087 btAngleCompareFunc comp(originalPoints[0]);
00088 originalPoints.quickSortInternal(comp,1,originalPoints.size()-1);
00089
00090 int i;
00091 for (i = 0; i<2; i++)
00092 hull.push_back(originalPoints[i]);
00093
00094
00095 for (; i != originalPoints.size(); i++)
00096 {
00097 bool isConvex = false;
00098 while (!isConvex&& hull.size()>1) {
00099 btVector3& a = hull[hull.size()-2];
00100 btVector3& b = hull[hull.size()-1];
00101 isConvex = btCross(a-b,a-originalPoints[i]).dot(btVector3(0,0,1))> 0;
00102 if (!isConvex)
00103 hull.pop_back();
00104 else
00105 hull.push_back(originalPoints[i]);
00106 }
00107 }
00108 }
00109
00110 #endif //GRAHAM_SCAN_2D_CONVEX_HULL_H