-4

扫描线示例与示例:校正后

代码包含 3 个类:

  1. 类 Line 来表示水平线: 参数:(x1,y1)----------(x2,y2)
  2. 上课点:
  3. 扫描线算法的类段

我正在尝试使用以下代码来计算水平线之间的交点,正如您可以从我的线是水平的坐标中一样:坐标: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;
}
4

2 回答 2

2

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

于 2013-10-25T12:17:15.047 回答
1

平行线(在本例中为水平线)不相交。绝不。

http://en.wikipedia.org/wiki/Parallel_(几何)

于 2013-10-25T12:17:26.727 回答