Example #1
0
        void clip_polygon_by_half_plane(
            const Polygon2d& P, 
            const vec2& q1,
            const vec2& q2,
            Polygon2d& result,
            bool invert
        ) {
            result.clear() ;

            if(P.size() == 0) {
                return ;
            }

            if(P.size() == 1) {
                if(point_is_in_half_plane(P[0], q1, q2, invert)) {
                    result.push_back(P[0]) ;
                }
                return ;
            }

            vec2 prev_p = P[P.size() - 1] ;
            Sign prev_status = point_is_in_half_plane(
                prev_p, q1, q2, invert
            ) ;

            for(unsigned int i=0; i<P.size(); i++) {
                vec2 p = P[i] ;
                Sign status = point_is_in_half_plane(
                    p, q1, q2, invert
                ) ;
                if(
                    status != prev_status &&
                    status != ZERO &&
                    prev_status != ZERO
                ) {
                    vec2 intersect ;
                    if(intersect_segments(prev_p, p, q1, q2, intersect)) {
                        result.push_back(intersect) ;
                    } else {
                    }
                }

                switch(status) {
                case NEGATIVE:
                    break ;
                case ZERO:
                    result.push_back(p) ;
                    break ;
                case POSITIVE:
                    result.push_back(p) ;
                    break ;
                }

                prev_p = p ;
                prev_status = status ;
            }
        }
Example #2
0
        void minimum_area_enclosing_rectangle(
            const Polygon2d& PP, 
            vec2& S, vec2& T
        ) {

            // Note: this implementation has O(n2) complexity :-(
            // (where n is the number of vertices in the convex hull)
            // If this appears to be a bottleneck, use a smarter
            // implementation with better complexity.

            Polygon2d P ;
            convex_hull(PP, P) ;

            int N = P.size() ;
            
            // Add the first vertex at the end of P
            P.push_back(P[0]) ;

            double min_area = Numeric::big_double ;

            for(int i=1; i<=N; i++) {
                vec2 Si = P[i] - P[i-1] ;

                if( ( Si.length2() ) < 1e-20) {
                    continue ;
                }

                vec2 Ti(-Si.y, Si.x) ;
                normalize(Si) ;
                normalize(Ti) ;
                double s0 =  Numeric::big_double ;
                double s1 = -Numeric::big_double ;
                double t0 =  Numeric::big_double ;
                double t1 = -Numeric::big_double ; 
                for(int j=1; j<N; j++) {
                    vec2 D = P[j] - P[0] ;
                    double s = dot(Si, D) ;
                    s0 = gx_min(s0, s) ;
                    s1 = gx_max(s1, s) ;
                    double t = dot(Ti, D) ;
                    t0 = gx_min(t0, t) ;
                    t1 = gx_max(t1, t) ;
                }
                double area = (s1 - s0) * (t1 - t0) ;
                if(area < min_area) {
                    min_area = area ;
                    if((s1 - s0) < (t1 - t0)) {
                        S = Si ;
                        T = Ti ;
                    } else {
                        S = Ti ;
                        T = Si ;
                    }
                }
            }
        }
Example #3
0
 void convex_hull(const Polygon2d& PP, Polygon2d& result) {
     result.clear() ;
     int n = PP.size() ;
     vec2* P = new vec2[n+1] ;
     { for(int i=0; i<n; i++) {
         P[i] = PP[i] ;
     }}
     int u = make_chain(P, n, cmpl);  
     P[n] = P[0];
     int ch = u+make_chain(P+u, n-u+1, cmph);  
     {for(int i=0; i<ch; i++) {
         result.push_back(P[i]) ;
     }}
     delete[] P ;
 }