C++ 扫描线算法
带示例的扫描线示例:校正后 代码包括3类:C++ 扫描线算法,c++,algorithm,computational-geometry,C++,Algorithm,Computational Geometry,带示例的扫描线示例:校正后 代码包括3类: 类行以表示水平线:参数: (x1,y1)----(x2,y2) 课程点: 用于扫描线算法的类段 我试图使用以下代码来计算水平线之间的交点,正如您可以从我的线是水平的坐标计算得到的那样: 坐标:x1,y1,x2,y2我有x1行].y1); last=活动。下限(行[e->行].y2); for(i=第一;i!=最后;++i) 反推(点(e->x,*i)); } 打破 } } 返回ans; } intmain() { 向量v; v、 向后推(线(0,5
课程点:
#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;
}
#如果ndef段
#定义段_H
#包括“h点”
#包括“Line.h”
#包括
#包括
#包括
使用名称空间std;
枚举事件类型{event_END,event_VERTICAL,event_START};
结构事件
{
事件类型;
int x;
int line;//索引到行列表中
事件(){}
事件(event_type type,intx,intline):类型(type),x(x),行(line){}
//先按X排序,然后按类型排序
布尔运算符行].y1];
打破
案例事件\u垂直:
{
//迭代相交水平线的所有y值
multiset::const_迭代器first,last,i;
first=活动的.u上限(行[e->行].y1);
last=活动。下限(行[e->行].y2);
for(i=第一;i!=最后;++i)
反推(点(e->x,*i));
}
打破
}
}
返回ans;
}
intmain()
{
向量v;
v、 向后推(线(0,5,10,5));
v、 向后推(线(5,0,5,10));
s段;
矢量p=s.hv\u交点(v);
cout代码是正确的(假设您有适当的#include
和main()
方法)。您提供的线没有交点。如果您添加任何垂直线,如800 100 800 2000
,您将得到交点的向量。平行线(在本例中为水平线)不要交叉,永远不要
这是您的全部代码吗?当我尝试编译它时,我遇到了一个错误:错误:“complex”没有命名类型
。事实上,您的数据中的行之间没有交叉点。我说“全部代码”时,期望得到什么,我指的是我可以复制、粘贴、编译、运行并查看您的问题的东西。我通常希望看到include
语句和main
方法,至少是这样。没有这些,就无法进行调试。我将向您展示@sergeyPlease您是否可以编写示例行坐标和预期结果。使用行(0,5,10,5)
和行(5,0,5,10);
预期结果为(5,5)
,此代码给出的结果正确。对于原始帖子中的数据-只有水平线-->没有交点。
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;
}