Exemple #1
0
polygon convex_intersect(const polygon &P, const polygon &Q) {
  const int n = P.size(), m = Q.size();
  int a = 0, b = 0, aa = 0, ba = 0;
  enum { Pin, Qin, Unknown } in = Unknown;
  polygon R;
  do {
    int a1 = (a+n-1) % n, b1 = (b+m-1) % m;
    number C = cross(P[a] - P[a1], Q[b] - Q[b1]);
    number A = cross(P[a1] - Q[b], P[a] - Q[b]);
    number B = cross(Q[b1] - P[a], Q[b] - P[a]);
    point r;
    if (intersect_1pt(P[a1], P[a], Q[b1], Q[b], r)) {
      if (in == Unknown) aa = ba = 0;
      R.push_back( r );
      in = B > number(0) ? Pin : A > number(0) ? Qin : in;
    }
    if (C == number(0) && B == number(0) && A == number(0)) {
      if (in == Pin) { b = (b + 1) % m; ++ba; }
      else           { a = (a + 1) % m; ++aa; }
    } else if (C >= number(0)) {
      if (A > number(0)) { if (in == Pin) R.push_back(P[a]); a = (a+1)%n; ++aa; }
      else       { if (in == Qin) R.push_back(Q[b]); b = (b+1)%m; ++ba; }
    } else {
      if (B > number(0)) { if (in == Qin) R.push_back(Q[b]); b = (b+1)%m; ++ba; }
      else       { if (in == Pin) R.push_back(P[a]); a = (a+1)%n; ++aa; }
    }
  } while ( (aa < n || ba < m) && aa < 2*n && ba < 2*m );
  if (in == Unknown) {
    if (contains(Q, P[0])) return P;
    if (contains(P, Q[0])) return Q;
  }
  return R;
}
double perimeter(polygon p){
	double per = 0.0;
	for(int i = 0; i < p.size(); i++){
		per += dist(p[i], p[(i+1)%p.size()]);
	}
	return per;
}
double area(polygon& poly){
	double ret = 0.0;
	for(int i = 0; i < poly.size(); i++){
		ret += trap(poly[i], poly[(i+1)%poly.size()]);
	}
	return fabs(ret);
}
//testa se o ponto esta dentro de um poligono (nao necessariamente convexo)
bool inside_poly(pt p, polygon poly){
	poly.push_back(poly[0]);
	
	for(int i = 0; i < poly.size()-1; i++)
		if(point_and_seg(poly[i], poly[i+1], p)) return true; //na borda
	
	for(int i = 0; i < poly.size()-1; i++) poly[i] = poly[i] - p;
	p = pt(0, 0);
	
	double theta, y;
	
	while(true){
		theta = (double)rand()/10000.0;
		
		bool inter = false;
		//evita que um ponto fique no eixo x
		for(int i = 0; i < poly.size()-1; i++){
			poly[i] = rotate(poly[i], theta);
			if( !cmp(poly[i].x) ) inter = true;
		}
		
		if( !inter ){
			poly[poly.size()-1] = poly[0];
			//testa as possiveis intersecoes
			for(int i = 0; i < poly.size()-1; i++){
				if( cmp( poly[i].x * poly[i+1].x ) < 0 ){
					y = poly[i+1].y - poly[i+1].x * (poly[i].y - poly[i+1].y) / (poly[i].x - poly[i+1].x);
					if( cmp(y) > 0 ) inter = !inter; //se interecao valida
				}
			}
			return inter; //testa a paridade da semi-reta vertical partindo de p
		}
	}
	return true;
}
//testa se o ponto esta no poligono convexo 
bool inside_convex_poly(pt p, polygon& poly){
	int left = 0, right = 0, side;
	for(int i = 0; i < poly.size(); i++){
		side = side_sign(p, poly[i], poly[(i+1)%poly.size()]);
		if(side < 0) right++;
		if(side > 0) left++;
	}
	return !(left && right);
}
//Determina se o poligono simples eh convexo
bool is_convex(polygon& p){
	int left = 0, right = 0, side;
	for(int i = 0; i < p.size(); i++){
		side = side_sign(p[i], p[(i+1)%p.size()], p[(i+2)%p.size()]);
		if(side < 0) right++;
		if(side > 0) left++;
	}
	return !(left && right);
}
Exemple #7
0
double dist(const polygon &a, const polygon &b) {
	double ret = 1e100;
	for (int i = 0; i < (int)a.size() - 1; ++ i)
		for (int j = 0; j < (int)b.size() - 1; ++ j) {
			ret = min(ret, dist(a[i], b[j], b[j + 1]));
			ret = min(ret, dist(b[j], a[i], a[i + 1]));
		}
	return ret;
}
bool positiveArea(polygon p) {
    for (int i = 0; i < p.size(); ++i) {
        for (int j = i + 1; j < p.size(); ++j) {
            for (int k = j + 1; k < p.size(); ++k) {
                if (collineal(p[0], p[1], p[2])) return false;
            }
        }
    }
    return true;
}
Exemple #9
0
bool polygonintersect(const polygon &a, const polygon &b) {
	for (int i = 0; i < (int)a.size() - 1; ++ i)
		if (inside(a[i], b)) return true;
	for (int i = 0; i < (int)b.size() - 1; ++ i)
		if (inside(b[i], a)) return true;
	for (int i = 0; i < (int)a.size() - 1; ++ i)
		for (int j = 0; j < (int)b.size() - 1; ++ j)
			if (intersect(a[i], a[i + 1], b[j], b[j + 1]))
				return true;
	return false;
}
Exemple #10
0
// 두 다각형이 서로 닿거나 겹치는지 여부를 반환한다.
// 한 점이라도 겹친다면 true 를 반환한다.
bool polygonIntersects(const polygon& p, const polygon& q) {
    int n = p.size(), m = q.size();
    // 우선 한 다각형이 다른 다각형에 포함되어 있는 경우를 확인하자
    if(isInside(p[0], q) || isInside(q[0], p)) return true;
    // 이외의 경우, 두 다각형이 서로 겹친다면 서로 닿는 두 변이 반드시 존재한다
    for(int i = 0; i < n; i++)
        for(int j = 0; j < m; j++)
            if(segmentIntersects(p[i], p[(i+1)%n], q[j], q[(j+1)%m]))
                return true;
    return false;
}
pt centroid(polygon p){
	double a = area(p);
	double xc = 0.0, yc = 0.0;
	
	for(int i = 0; i < p.size(); i++){
		int next = (i+1)%p.size();
		xc += (p[i].x + p[next].x)*(p[i].x*p[next].y - p[next].x*p[i].y);
		yc += (p[i].y + p[next].y)*(p[i].x*p[next].y - p[next].x*p[i].y);
	}
	
	return pt(xc/(6.0*a), yc/(6.0*a));
}
Exemple #12
0
int isPointInPolygon(point p, polygon &pg)
{
    bool in = false;
    for (int i = 0; i < pg.size(); i++)
    {
        point a = pg[i] - p, b = pg[(i + 1) % pg.size()] - p;
        if (abs(cross(a, b)) < EPSILON && dot(a, b) < EPSILON) return ON;
        if (a.y > b.y) swap(a, b);
        if (a.y < EPSILON && EPSILON < b.y && cross(a, b) > EPSILON) in = !in;
    }
    return in ? IN : OUT;
}
Exemple #13
0
      inline void draw(const polygon<T,2>& polygon)
      {
         if (polygon.size() < 3) return;

         std::size_t j = polygon.size() - 1;

         for (std::size_t i = 0; i < polygon.size(); ++i)
         {
            draw_segment(polygon[i],polygon[j]);
            j = i;
         }
      }
Exemple #14
0
bool isugly(const polygon <float> & pol)
{
	if (pol.size() < 3)
		return true;
	//Add other ugly conditions
	return false;
}
Exemple #15
0
int in_poly(point p, polygon& T) { 
	double a = 0; int N = T.size();
	for (int i = 0; i < N; i++) {
		if (between(T[i], p, T[(i+1) % N])) return -1;
		a += angle(T[i], p, T[(i+1) % N]);
	}
	return cmp(a) != 0;
}
Exemple #16
0
/**
 * @brief Add a polygon to the mesh.
 * @param p
 */
void Mesh::add_polygon( polygon& p )
{
    polygons.push_back( p );

    if ( p.size() == 3 ) {
        tris.push_back( p.at(0) );
        tris.push_back( p.at(1) );
        tris.push_back( p.at(2) );
    }

    if ( p.size() == 4 ) {
        quads.push_back( p.at(0) );
        quads.push_back( p.at(1) );
        quads.push_back( p.at(2) );
        quads.push_back( p.at(3) );
    }
}
Exemple #17
0
bool inside(const point &a, const polygon &p) {
	double cnt = 0;
	for (int i = 0; i < (int)p.size() - 1; ++ i) {
		point x = p[i] - a, y = p[i + 1] - a;
		if (abs(x) == 0 || abs(y) == 0) return true;
		cnt += asin(cross(x, y) / abs(x) / abs(y));
	}
	return fabs(cnt) >= 2 * pi - eps;
}
Exemple #18
0
double getArea(polygon &pg)
{
    double area = 0.0;
    int n = pg.size();
    if (n < 3) return area;
    for (int i = 0, j = 1; i < n; i++, j = (i + 1) % n)
        area += (pg[i].x * pg[j].y - pg[j].x * pg[i].y);
    return fabs(area / 2.0);
}
Exemple #19
0
int contains(const polygon& P, const point& p) {
  bool in = false;
  for (int i = 0; i < P.size(); ++i) {
    point a = curr(P,i) - p, b = next(P,i) - p;
    if (imag(a) > imag(b)) swap(a, b);
    if (imag(a) <= number(0) && number(0) < imag(b))
      if (cross(a, b) < number(0)) in = !in;
    if (cross(a, b) == number(0) && dot(a, b) <= number(0)) return ON;
  }
  return in ? IN : OUT;
}
Exemple #20
0
int contains(const polygon& G, const P& p) {
    bool in = false;
    for (int i = 0; i < G.size(); ++i) {
        P a = curr(G,i) - p, b = next(G,i) - p;
        if (imag(a) > imag(b)) swap(a, b);
        if (imag(a) <= 0 && 0 < imag(b))
            if (cross(a, b) < 0) in = !in;
        if (cross(a, b) == 0 && dot(a, b) <= 0) return ON;
    }
    return in ? IN : OUT;
}
Exemple #21
0
point center(const polygon& poly) {
	double x = 0.0; 
	double y = 0.0; 
	
	for (auto& p : poly) {
		x += p.x / poly.size(); 
		y += p.y / poly.size();
	} 
	
	return { x, y };
}
//Corta o poligono pela reta ab
//pol1 - poligono do lado esquerdo
//pol2 - poligono do lado direito
void cut_polygon(polygon pol, pt a, pt b, polygon& pol1, polygon& pol2){
	polygon pp, pn;
	pt p1, p2, r;
	
	for(int i = 0; i < pol.size(); i++){
		p1 = pol[i]; p2 = pol[(i+1)%pol.size()];
		int side = side_sign(a, b, p1);
		if(side >= 0) pp.push_back(p1);
		if(side <= 0) pn.push_back(p1);
		
		if(intersect(a, b, p1, p2, r) && (r == pt(INF, INF))){
			if(point_and_seg(p1, p2, r)){
				pp.push_back(r);
				pn.push_back(r);
			}
		}
		if(pp.size() > 2) convex_hull(pp, pol1);
		if(pn.size() > 2) convex_hull(pn, pol2);
	}
}
void convex_hull(polygon in, polygon& hull){
	hull.clear();
	
	if(in.size() < 3){ hull = in; return; }
	
	int pos = 0;
	for(int i = 1; i < in.size(); i++) if(in[i] < in[pos]) pos = i;
	swap(in[0], in[pos]);
	refer = in[0];
	
	sort(in.begin() + 1, in.end(), cmp_angle);
	in.resize(unique(in.begin(), in.end()) - in.begin());
	
	hull.push_back(in[0]); hull.push_back(in[1]);
	
	in.push_back(in[0]); //isto evita pontos colineares no final do poligono
	for(int i = 2; i < in.size(); ){
		if(hull.size() > 2 && side_sign(hull[hull.size() - 2], hull[hull.size() - 1], in[i]) <= 0){
			hull.pop_back();
		}
		else hull.push_back(in[i++]);
	}
	//tira a duplicata
	hull.pop_back();
}
Exemple #24
0
polygon poly_intersect(polygon &P, polygon &Q){
	int m = Q.size(), n = P.size();
	int a = 0, b = 0, aa = 0, ba = 0, inflag = 0;
	polygon R;
	while( (aa < n || ba < m) && aa < 2*n && ba < 2*m){
		Point p1 = P[a], p2 = P[(a+1) % n], q1 = Q[b], q2 = Q[(b+1) % m];
		Point A = p2 - p1, B = q2 - q1;
		int cross = cmp(A ^ B), ha = turn(p2, q2, p1), hb = turn(q2, p2, q1);
		if(cross == 0 && turn(p1, q1, p2) == 0 && cmp(A * B) < 0){
			if(between(p1, q1, p2)) R.push_back(q1);
			if(between(p1, q2, p2)) R.push_back(q2);
			if(between(q1, p1, q2)) R.push_back(p1);
			if(between(q1, p2, q2)) R.push_back(p2);
			if(R.size() < 2) return polygon();
			inflag = 1; break;
		}else if(cross != 0 && seg_intersect(p1, p2, q1, q2)) {
			if(inflag == 0) aa = ba = 0;
			R.push_back(intersection(p1, p2, q1, q2));
			inflag = (hb > 0) ? 1 : -1;
		}
		if(cross == 0 && hb < 0 && ha < 0) return R;
		bool t = cross == 0 && hb == 0 && ha == 0;
		if(t ? (inflag == 1) : (cross >= 0) ? (ha <= 0) : (hb > 0)){
			if(inflag == -1) R.push_back(q2);
			ba++; b++; b %= m;
		}else{
			if(inflag == 1) R.push_back(p2);
			aa++; a++; a %= n;
		}
	}

	if(inflag == 0){
		if (in_polygon(P[0], Q)) return P;
		if (in_polygon(Q[0], P)) return Q;
	}
	R.erase(unique(R.begin(), R.end()), R.end());
	if(R.size() > 1 && R.front() == R.back()) R.pop_back();
	return R;
}
Exemple #25
0
point getCentroid1(polygon &pg)
{
    double areaOfPolygon = 0, areaOfTriangle = 0, px = 0, py = 0;

    for (int i = 2; i < pg.size(); i++)
    {
        areaOfTriangle = cross(pg[i - 1] - pg[0], pg[i] - pg[0]);
        areaOfPolygon += areaOfTriangle;
        px += areaOfTriangle * (pg[0].x + pg[i - 1].x + pg[i].x);
        py += areaOfTriangle * (pg[0].y + pg[i - 1].y + pg[i].y);
    }

    return point(px / (3.0 * areaOfPolygon), py / (3.0 * areaOfPolygon));
}
bool polygonsIntersect(const polygon &a, const polygon &b) {
    int na = a.size(), nb = b.size();
    for (int i = 0; i < na; ++i) {
        if (pointInPoly(a[i], b)) return true;
    }
    for (int i = 0; i < nb; ++i) {
        if (pointInPoly(b[i], a)) return true;
    }
    
    for (int i = 0; i < na; ++i) {
        for (int j = 0; j < nb; ++j) {
            int xa1 = a[i].first, ya1 = a[i].second;
            int xa2 = a[(i + 1) % na].first, ya2 = a[(i + 1) % na].second;
            int xb1 = b[j].first, yb1 = b[j].second;
            int xb2 = b[(j + 1) % nb].first, yb2 = b[(j + 1) % nb].second;
            if (segment_segment_intersection(xa1, ya1,    xa2, ya2,               xb1, yb1, xb2, yb2)) {
                return true;
            }
        }
    }
    
    
    return false;
}
Exemple #27
0
point getCentroid2(polygon &pg)
{
    double areaOfPolygon = 0, areaOfTriangle = 0, px = 0, py = 0;

    int n = pg.size();
    for (int i = 0; i < n; i++)
    {
        areaOfTriangle = cross(pg[i], pg[(i + 1) % n]);
        areaOfPolygon += areaOfTriangle;
        px += areaOfTriangle * (pg[i].x + pg[(i + 1) % n].x);
        py += areaOfTriangle * (pg[i].y + pg[(i + 1) % n].y);
    }

    return point(px / (3.0 * areaOfPolygon), py / (3.0 * areaOfPolygon));
}
result lineIntersectsPolygon(line & l, polygon & P) {
    result points;

    point prev = P[0];
    for (size_t i = 1; i < P.size(); i++) {
        point cur = P[i];
        segment s = {prev, cur};
        if (lineIntersectsSegment(l, s)) {
            points.insert(i - 1);
        }
        prev = cur;
    }

    return points;
}
// Returns a list of points on the convex hull in counter-clockwise order.
// NOTE: the last point in the returned list is the same as the first one.
void convex_hull_2(polygon P, polygon& hull) {
	hull.clear();
	
	// Sort points lexicographically
	sort(P.begin(), P.end());
	P.resize(unique(P.begin(), P.end()) - P.begin());
	
	// Build lower hull
	for (int i = 0; i < P.size(); i ++) {
		while (hull.size() >= 2 && side_sign(hull[hull.size() - 2], hull[hull.size() - 1], P[i]) <= 0)
			hull.pop_back();
		hull.push_back(P[i]);
	};
 
	// Build upper hull
	for (int i = P.size()-2, t = hull.size() + 1; i >= 0; i --) {
		while (hull.size() >= t && side_sign(hull[hull.size()-2], hull[hull.size()-1], P[i]) <= 0)
			hull.pop_back();
		hull.push_back(P[i]);
	};
}
Exemple #30
0
// (a,b) 를 포함하는 직선으로 다각형 p 를 자른 뒤, (a,b) 의 왼쪽에 있는 부분들을 반환한다
polygon cutPoly(const polygon& p, const vector2& a, const vector2& b) {
    int n = p.size();
    vector<bool> inside(n);
    for(int i = 0; i < n; ++i)
        inside[i] = ((b-a).cross(p[i]-a) >= 0);
    // 이외의 경우에는 일부는 직선 왼쪽에, 일부는 직선 오른쪽에 떨어진다
    polygon ret;
    for(int i = 0; i < n; ++i) {
        int j = (i + 1) % n;
        if(inside[i]) ret.push_back(p[i]);
        if(inside[i] != inside[j]) {
            vector2 intersection;
            assert(lineIntersection(p[i], p[j], a, b, intersection));
            ret.push_back(intersection);
        }
    }
    return ret;
}