示例#1
0
文件: poly.c 项目: TidyHuang/vizgems
static int edgesIntersect(Point * P, Point * Q, int n, int m)
{
    int a = 0;
    int b = 0;
    int aa = 0;
    int ba = 0;
    int a1, b1;
    Point A, B;
    double cross;
    int bHA, aHB;
    Point p;
    int inflag = Unknown;
    /* int      i = 0; */
    /* int      Reset = 0; */

    do {
	a1 = (a + n - 1) % n;
	b1 = (b + m - 1) % m;

	subpt(&A, P[a], P[a1]);
	subpt(&B, Q[b], Q[b1]);

	cross = area_2(origin, A, B);
	bHA = leftOf(P[a1], P[a], Q[b]);
	aHB = leftOf(Q[b1], Q[b], P[a]);

	/* If A & B intersect, update inflag. */
	if (intersection(P[a1], P[a], Q[b1], Q[b], &p))
	    return 1;

	/* Advance rules. */
	if ((cross == 0) && !bHA && !aHB) {
	    if (inflag == Pin)
		advance(b, ba, m);
	    else
		advance(a, aa, n);
	} else if (cross >= 0)
	    if (bHA)
		advance(a, aa, n);
	    else {
		advance(b, ba, m);
	} else {		/* if ( cross < 0 ) */

	    if (aHB)
		advance(b, ba, m);
	    else
		advance(a, aa, n);
	}

    } while (((aa < n) || (ba < m)) && (aa < 2 * n) && (ba < 2 * m));

    return 0;

}
/* Intersection area */
  template<class K> typename K::FT intersection_area_two_slabs(const Rectangle_2<K>& a, const Rectangle_2<K> &b) {
    typedef typename K::Vector_2 Vector_2;
    typedef typename K::Line_2 Line_2;
    typedef typename K::Point_2 Point_2;
    typedef typename K::FT FT;
    Origin O;
    if(a.is_degenerate() || b.is_degenerate()) return 0;
    std::vector<Vector_2> v;
    std::vector<Line_2> l;
    for(unsigned int i=0; i<4; ++i)    { v.push_back(b[i]-O); l.push_back(b.line(i)); }
    const Vector_2& n = a.normal();
    FT r = a.ratio();
    FT n2 = n.squared_length();
    FT rn2 = r*r*n2;
    Vector_2 vc(a.center()-O);
    Vector_2 trn(-r*n.y(),r*n.x());
    FT ctrn = vc*trn;
    FT cn = vc*n;

    Vector_2 ln[] = {  n, trn };
    FT lc[] = { cn+n2, ctrn+rn2, cn-n2, ctrn-rn2 };

 // basically it is the iterative intersection of the convex polygon initialized with b
 // with the 2 slabs line0/line2 and line1/line3.
    for(unsigned int i=0; i<2; ++i)    {
        int begin0=-1, end0=-1;
        int begin1=-1, end1=-1;
        unsigned int n=v.size();
        for(unsigned int j=0; j<n; ++j) {
            FT dot = ln[i]*v[j];
            if( dot>lc[i]) {
                if(end0==-1 && begin0!=-1) end0=j;
                if(begin1<=end1) begin1=j;
            } else {
                if(begin0<=end0) begin0=j;
                if(dot<lc[i+2]) {
                    if(end1==-1 && begin1!=-1) end1=j;
                } else {
                    if(begin1<=end1) begin1=j;
                }
            }
        }
        if(begin0==-1 || begin1==-1 ) return 0; // outside the slab
        if(end0  ==-1) {
            if(begin0!=0) end0=0;
            else begin0=begin1;
        }
        if(end1  ==-1) {
            if(begin1!=0) end1=0;
            else {
                if(end0==-1) continue; // inside the slab
                begin1=begin0;
            }
        }

        std::vector<Vector_2> w;
        std::vector<Line_2> m;
        if(end0!=-1) {  // cut outside line(i+1)
            for(int j=begin1; j!=end0; j=(j+1)%n) {
                 w.push_back(v[j]);
                 m.push_back(l[j]);
            }
            Point_2 inter(O);
            Line_2 li(ln[i].x(),ln[i].y(),-lc[i]);
            intersection(l[(end0+n-1)%n],li).assign(inter);
            w.push_back(inter-O);
            m.push_back(li);
            m.push_back(l[(begin0+n-1)%n]);
            intersection(li,m.back()).assign(inter);
            w.push_back(inter-O);
        }
        if(end1!=-1) { // cut outside line(i+3)
            for(int j=begin0; j!=end1; j=(j+1)%n) {
                w.push_back(v[j]);
                m.push_back(l[j]);
            }
            Point_2 inter(O);
            Line_2 li(ln[i].x(),ln[i].y(),-lc[i+2]);
            intersection(l[(end1+n-1)%n],li).assign(inter);
            w.push_back(inter-O);
            m.push_back(li);
            m.push_back(l[(begin1+n-1)%n]);
            intersection(li,m.back()).assign(inter);
            w.push_back(inter-O);
        }
        std::swap(v,w);
        std::swap(l,m);
    }
    std::vector<Point_2> p;
    for(unsigned int i=0; i<v.size(); ++i)    { p.push_back(O+v[i]); }
    FT area;
    area_2(p.begin(),p.end(),area);
    return abs(area);
  }