void ConvexHull(vector<PT> &pts) { sort(pts.begin(), pts.end()); pts.erase(unique(pts.begin(), pts.end()), pts.end()); vector<PT> up, dn; for (int i = 0; i < pts.size(); i++) { while (up.size() > 1 && area2(up[up.size()-2], up.back(), pts[i]) >= 0) up.pop_back(); while (dn.size() > 1 && area2(dn[dn.size()-2], dn.back(), pts[i]) <= 0) dn.pop_back(); up.push_back(pts[i]); dn.push_back(pts[i]); } pts = dn; for (int i = (int) up.size() - 2; i >= 1; i--) pts.push_back(up[i]); #ifdef REMOVE_REDUNDANT if (pts.size() <= 2) return; dn.clear(); dn.push_back(pts[0]); dn.push_back(pts[1]); for (int i = 2; i < pts.size(); i++) { if (between(dn[dn.size()-2], dn[dn.size()-1], pts[i])) dn.pop_back(); dn.push_back(pts[i]); } if (dn.size() >= 3 && between(dn.back(), dn[0], dn[1])) { dn[0] = dn.back(); dn.pop_back(); } pts = dn; #endif }
/* open_intersect: * Returns true iff segment ab intersects segment cd. * NB: segments are considered open sets */ static int open_intersect(Ppoint_t a,Ppoint_t b,Ppoint_t c,Ppoint_t d) { return (((area2(a,b,c) > 0 && area2(a,b,d) < 0) || (area2(a,b,c) < 0 && area2(a,b,d) > 0)) && ((area2(c,d,a) > 0 && area2(c,d,b) < 0 ) || (area2(c,d,a) < 0 && area2(c,d,b) > 0 ))); }
/* graham's algorithm for 2d convex hull, O(n log n) */ int convexhull(point *p,int n,point *h) { int i,j,m=0; /* find lowest point, swap it to pos 0 */ for(i=1;i<n;i++) if(p[i].y<p[m].y || (p[i].y==p[m].y && p[i].x<p[m].x)) m=i; for(i=0;i<n;i++) { p[i].del=0; p[i].id=i; } if(m) { i=p[0].x; p[0].x=p[m].x; p[m].x=i; i=p[0].y; p[0].y=p[m].y; p[m].y=i; } for(i=1;i<n;i++) if(p[i].y==p[0].y && p[i].x==p[0].x) p[i].del=1; /* leave pos 0 alone */ qsort(p+1,n-1,sizeof(point),compp); /* contract */ for(i=j=0;i<n;i++) if(!p[i].del) { if(i!=j) p[j]=p[i]; j++; } n=j; /* find convex hull */ h[0]=p[0]; h[1]=p[1]; hn=i=2; if(n<3) return n; while(i<n) { if(area2(h[hn-2],h[hn-1],p[i])>0) h[hn++]=p[i++]; else hn--; } return hn; }
/* private */ void Centroid::addTriangle(const Coordinate& p0, const Coordinate& p1, const Coordinate& p2, bool isPositiveArea) { double sign = (isPositiveArea) ? 1.0 : -1.0; centroid3( p0, p1, p2, triangleCent3 ); double a2 = area2( p0, p1, p2 ); cg3.x += sign * a2 * triangleCent3.x; cg3.y += sign * a2 * triangleCent3.y; areasum2 += sign * a2; }
/* requires external array p for access to p[0] */ int compp(point *pi,point *pj) { ll a=area2(p[0],*pi,*pj),x,y; if(a>0) return -1; else if(a<0) return 1; else { x=llabs((ll)pi->x-p[0].x)-llabs((ll)pj->x-p[0].x); y=llabs((ll)pi->y-p[0].y)-llabs((ll)pj->y-p[0].y); if(x<0 || y<0) { pi->del=1; return -1; } else if(x>0 || y>0) { pj->del=1; return 1; } else { if(pi->id>pj->id) pj->del=1; else pi->del=1; return 0; } } }
bool Wall::isInvalidMove(glm::vec2 start, glm::vec2 end) { float x1 = start.x; float y1 = start.y; float x2 = end.x; float y2 = end.y; float x3 = this->point1.x; float y3 = this->point1.y; float x4 = this->point2.x; float y4 = this->point2.y; float a1, a2, a3, a4; // deal with special cases if ((a1 = area2(x1, y1, x2, y2, x3, y3)) == 0.0f) { // check if p3 is between p1 and p2 OR // p4 is collinear also AND either between p1 and p2 OR at opposite ends if (between(x1, y1, x2, y2, x3, y3)) { return true; } else { if (area2(x1, y1, x2, y2, x4, y4) == 0.0f) { return between(x3, y3, x4, y4, x1, y1) || between (x3, y3, x4, y4, x2, y2); } else { return false; } } } else if ((a2 = area2(x1, y1, x2, y2, x4, y4)) == 0.0) { // check if p4 is between p1 and p2 (we already know p3 is not collinear return between(x1, y1, x2, y2, x4, y4); } if ((a3 = area2(x3, y3, x4, y4, x1, y1)) == 0.0) { // check if p1 is between p3 and p4 OR // p2 is collinear also AND either between p1 and p2 OR at opposite ends if (between(x3, y3, x4, y4, x1, y1)) { return true; } else { if (area2(x3, y3, x4, y4, x2, y2) == 0.0) { return between(x1, y1, x2, y2, x3, y3) || between (x1, y1, x2, y2, x4, y4); } else { return false; } } } else if ((a4 = area2(x3, y3, x4, y4, x2, y2)) == 0.0) { // check if p2 is between p3 and p4 (we already know p1 is not collinear return between(x3, y3, x4, y4, x2, y2); } else { //test for regular intersection return ((a1 > 0.0) ^ (a2 > 0.0)) && ((a3 > 0.0) ^ (a4 > 0.0)); } }
void fractal::draw_border( bool is_active ) { color_t color = is_active ? v->get_color(0, 255, 0) // green color : v->get_color(96, 128, 96); // green-gray color // top border drawing_area area0( off_x-1, off_y-1, size_x+2, 1, dm ); for (int i=-1; i<size_x+1; ++i) area0.put_pixel(color); // bottom border drawing_area area1( off_x-1, off_y+size_y, size_x+2, 1, dm ); for (int i=-1; i<size_x+1; ++i) area1.put_pixel(color); // left border drawing_area area2( off_x-1, off_y, 1, size_y+2, dm ); for (int i=0; i<size_y; ++i) area2.set_pixel(0, i, color); // right border drawing_area area3( size_x+off_x, off_y, 1, size_y+2, dm ); for (int i=0; i<size_y; ++i) area3.set_pixel(0, i, color); }
int area_poly2 ( ) /******************************************************************************/ /* Purpose: AREA_POLY2 returns the area of a polygon. Modified: 30 April 2007 Author: Joseph O'Rourke Parameters: Output, int AREA_POLY2, the area of the polygon. */ { tVertex a; tVertex p; int sum = 0; /* Keep P fixed, but allow A to move. */ p = vertices; a = p->next; do { sum = sum + area2 ( p->v, a->v, a->next->v ); a = a->next; } while ( a->next != vertices ); return sum; }
inline bool leftOn(const int* a, const int* b, const int* c) { return area2(a, b, c) <= 0; }
inline bool collinear(const int* a, const int* b, const int* c) { return area2(a, b, c) == 0; }
// p.29 // Returns true if point c is to the left of the line or colinear with the // line directed from a to b const bool Utility::leftOn(const point<int> &a, const point <int> &b, const point <int> &c) { return area2(a, b, c) >= 0; }
bool isCollinear( const SbVec3f& p1, const SbVec3f& p2, const SbVec3f& p3 ) { return isZero( area2( p1, p2, p3 ) ); }
// p.29 // Returns true if point c is collinear with the line directed form a to b const bool Utility::collinear(const point<int> &a, const point <int> &b, const point <int> &c) { return area2(a, b, c) == 0; }
int compare( const void *arg1, const void *arg2 ) { try { const I_MapItem *i1 = *reinterpret_cast<I_MapItem**>(const_cast<void*>(arg1)); const I_MapItem *i2 = *reinterpret_cast<I_MapItem**>(const_cast<void*>(arg2)); C_TextPtr text1(const_cast<I_MapItem*>(i1)); C_TextPtr text2(const_cast<I_MapItem*>(i2)); if (text1 && !text2) { return 1; } else if (text2 && !text1) { return -1; } C_PicturePtr pic1(const_cast<I_MapItem*>(i1)); C_PicturePtr pic2(const_cast<I_MapItem*>(i2)); if (pic1 && !pic2) { return 1; } else if (pic2 && !pic1) { return -1; } C_PositionPtr p1(const_cast<I_MapItem*>(i1)); C_PositionPtr p2(const_cast<I_MapItem*>(i2)); if (p1 && p2) { C_Area area1(p1.GetPoints()); C_Area area2(p2.GetPoints()); int n = 0; int cnt1 = area1.GetLength(); int cnt2 = area2.GetLength(); if (0 == cnt1) { return -1; } if (0 == cnt2) { return 1; } POINT3D *ptr1 = area1[cnt1 - 1]; POINT3D *ptr2 = area2[cnt2 - 1]; if (ptr1->x < 0 && ptr2->x > 0) { n = -1; } else if (ptr1->x > 0 && ptr2->x < 0) { n = 1; } else if (ptr1->y < ptr2->y) { n = -1; } else if (ptr1->y > ptr2->y) { n = 1; } if (0 == n) { if (cnt1 < cnt2) { n = -1; } else if (cnt1 > cnt2) { n = 1; } } if (0 != n) { return n; } } C_UniquePtr u1(const_cast<I_MapItem*>(i1)); C_UniquePtr u2(const_cast<I_MapItem*>(i2)); if (!u1 && !u2) { return 0; } else if (!u1) { return -1; } else if (!u2) { return 1; } else { BSTR bs1 = NULL; BSTR bs2 = NULL; u1->get_UID(&bs1); u2->get_UID(&bs2); int n = ::wcscmp(bs1, bs2); String::FreeBSTR(&bs1); String::FreeBSTR(&bs2); return n; } } catch (C_STLNonStackException const &exception) { exception.Log(_T("Exception in Items.cpp (compare)")); } return 0; }
bool between(const PT &a, const PT &b, const PT &c) { return (fabs(area2(a,b,c)) < EPS && (a.x-b.x)*(c.x-b.x) <= 0 && (a.y-b.y)*(c.y-b.y) <= 0); }
BM_INLINE int left(const float* a, const float* b, const float* c) { return area2(a, b, c) < 0; }
/* inCone: * Returns true iff q is in the convex cone a-b-c */ static int inCone (pointf a, pointf b, pointf c, pointf q) { return ((area2(q,a,b) >= NSMALL) && (area2(q,b,c) >= NSMALL)); }