扫描线算法

时间:2013-10-25 12:03:30

标签: c++ algorithm computational-geometry

SWEEP LINE示例与示例:更正后

代码包含3个类:

  1. Class Line表示水平线:参数: (x1,y1)----------(x2,y2)
  2. 分类点:
  3. 扫描线算法的类段
  4. 我正在尝试使用以下代码来计算水平线之间的交叉点,正如您可以从My lines为Horizo​​ntal的坐标: 坐标: x1,y1,x2,y2 我有x1< x2,和y1 = y


    分类点:

    #ifndef POINT_H
    #define POINT_H
    
    
    class Point
    {
        public:
            Point(float, float);
            float x;
            float y;
    
    };
    
    #endif // POINT_H
    
    #include "Point.h"
    
    Point::Point(float xi, float yi):x(xi),y(yi)
    {
    
    }
    

    分类线

    #ifndef LINE_H
    #define LINE_H
    
    
    class Line
    {
        public:
            Line(int,int,int,int);
            int x1, y1, x2, y2;
    };
    
    #endif // LINE_H
    
    #include "Line.h"
    
    Line::Line(int x_1, int y_1, int x_2,int y_2):x1(x_1),y1(y_1),x2(x_2),y2(y_2)
    {
        //ctor
    }
    

    类别细分:

    #ifndef SEGMENT_H
    #define SEGMENT_H
    
    #include "Point.h"
    #include "Line.h"
    
    #include <vector>
    #include <set>
    #include <algorithm>
    using namespace std;
    
    
        enum event_type { EVENT_END,EVENT_VERTICAL,EVENT_START};
        struct event
        {
            event_type type;
            int x;
            int line;        // index into list of lines
    
            event() {}
            event(event_type type, int x, int line) : type(type), x(x), line(line) {}
    
            // sort by X then by type
            bool operator <(const event &b) const
            {
                if (x != b.x) return x < b.x;
                else return type < b.type;
            }
        };
    
    class Segment
    {
    
        public:
            Segment();
            vector<Point> hv_intersections(const vector<Line> &);
    
    };
    
    #endif // SEGMENT_H
    
    
    #include "Segment.h"
    
    Segment::Segment()
    {
        //ctor
    }
    
        vector<Point> Segment::hv_intersections(const vector<Line> & lines)
        {
            int L = lines.size();
            vector<event> events;
            vector<Point> ans;
    
            // Y coordinates of active lines
            multiset<int> active;
    
            // Convert lines into events
            for (int i = 0; i < L; i++)
            {
                if (lines[i].y1 != lines[i].y2)
                    events.push_back(event(EVENT_VERTICAL, lines[i].x1, i));
                else if (lines[i].x1 != lines[i].x2)
                {
                    events.push_back(event(EVENT_START, lines[i].x1, i));
                    events.push_back(event(EVENT_END, lines[i].x2, i));
                }
            }
    
            // Sort events by X
            sort(events.begin(), events.end());
    
            // Returns all intersections between lines. The lines must all be either
            // horizontal and vertical, and only horizontal-vertical intersections are
            // counted (i.e. not overlaps). Lines are considered to exclude their
            // endpoints. Also, each line must have x1 <= x2 and y1 <= y2.
            for (vector<event>::const_iterator e = events.begin(); e != events.end(); ++e)
            {
                switch (e->type)
                {
                    case EVENT_START:
                        active.insert(lines[e->line].y1);
                        break;
    
                    case EVENT_END:
                        active.erase(active.find(lines[e->line].y1));
                        break;
    
                    case EVENT_VERTICAL:
                    {
                        // Iterate over all y values for intersecting horizontal lines
                        multiset<int>::const_iterator first, last, i;
                        first = active.upper_bound(lines[e->line].y1);
                        last = active.lower_bound(lines[e->line].y2);
    
                        for (i = first; i != last; ++i)
                            ans.push_back(Point(e->x, *i));
                    }
                    break;
                }
            }
    
            return ans;
        }
    

    int main()
    {
         vector<Line> v;
        v.push_back(Line(0, 5, 10, 5));
        v.push_back(Line(5, 0, 5, 10));
           Segment s;
            vector<Point> p = s.hv_intersections(v);
            cout << p.size() << endl;
         return 0;
    }
    

2 个答案:

答案 0 :(得分:2)

代码是正确的(假设您有正确的#includemain()方法)。您提供的线路没有交叉点。如果您添加任何垂直线,例如800 100 800 2000,您将获得vector<pnt>个交叉点。

答案 1 :(得分:1)

平行线(在这种情况下为水平线)不相交。从不。

http://en.wikipedia.org/wiki/Parallel_(geometry)