我班上有以下数据结构:
typedef vector< vector<int> > MxInt2d;
typedef vector< vector<double> > MxDouble2d;
class QSweep{
public:
....
static MxDouble2d myPoints_;
MxDouble2d myEdges_;
}
其中: 每个点有3个分量,因此由索引,x和y坐标给出; 每个边由其源索引边[0]和其目标索引边[1]给出,其中edge [0],edge [1]是myPoints数据结构的索引。 我在变量myEdges _中有这个边缘。
问题如下:如何安排此边缘以应用扫描算法并获得良好的结果和良好的结果(即边缘的所有交叉点)。 到目前为止,我有两个不同的标准来安排边缘,但没有一个给我良好的结果,只有良好的结果(要么我没有获得所有的交叉点,要么我得到交叉点加上其他一些不是交叉点的点)
以下是我的标准:
标准1(想法):
通过其边[0]坐标的x坐标(如果2个边的x不同)
通过其边[0]坐标的y坐标(如果2个边的x相等)
通过相应的斜率(如果边缘的x和边缘的y相等)。
标准1(代码):
class QSweep{
public:
....
static MxDouble2d myPoints_;
MxDouble2d myEdges_;
class order{
public:
bool operator() (const vector<int>& edge1, const vector<int>& edge2){
//std::cout<<"inside sort"<<endl;
//3 sort criteria
return (myPoints_[edge1[0]][0]<myPoints_[edge2[0]][0])||
(myPoints_[edge1[0]][0]==myPoints_[edge2[0]][0]&&
myPoints_[edge1[0]][1]<myPoints_[edge2[0]][1])
||
(myPoints_[edge1[0]][0]==myPoints_[edge2[0]][0]&&
myPoints_[edge1[0]][1]==myPoints_[edge2[0]][1]&&
getSlope(myPoints_[edge1[0]][0],myPoints_[edge1[0][1],
myPoints_[edge1[1]][0],myPoints_[edge1[1]][0])
<
getSlope(myPoints_[edge2[0][0],myPoints_[edge2[0][1],
myPoints_[edge2[1]][0],myPoints_[edge2[1]][0]));
}
};
static double getSlope(double a, double b, double c, double d);
};
标准2(想法):
通过其边[0]坐标的x坐标(如果2个边的x不同)
以相应的斜率(如果2条边的x相等)
通过其边[1]坐标的y坐标(如果边缘的x和边的斜率相等)。
标准2(代码):
class QSweep{
public:
....
static MxDouble2d myPoints_;
MxDouble2d myEdges_;
class order{
public:
bool operator() (const vector<int>& edge1, const vector<int>& edge2){
return ((myPoints_[edge1[0]][0]<myPoints_[edge2[0]][0])||
((myPoints_[edge1[0]][0]==myPoints_[edge2[0[0])&&
(getSlope(myPoints_[edge1[0]][0],myPoints_[edge1[0]][1],
myPoints_[edge1[1]][0],myPoints_[edge1[1]][1])
<getSlope(myPoints_[edge2[0]][0],myPoints_[edge2[0]][1],
myPoints_[edge2[1]][0],myPoints_[edge2[1]][1]) ))||
((myPoints_[edge1[0]][0]==myPoints_[edge2[0]][0])&&(
getSlope(myPoints_[edge1[0]][0],myPoints_[edge1[0]][1],
myPoints_[edge1[1[0],myPoints_[edge1[1]][1])==
getSlope(myPoints_[edge2[0]][0],myPoints_[edge2[0]][1],
myPoints_[edge2[1]][0],myPoints_[edge2[1]][1]) )
&&(myPoints_[edge1[1]][1]<myPoints_[edge2[1]][1]))
);
}
};
是的,这看起来很复杂,我在我的算法上尝试了这些标准,但我没有获得所有的交叉点。所以我猜测扫描算法的边缘排序标准并不好,因为我检测到了一些交叉点而不是其他交叉点。 感谢您提前的建议(或小意见), madalina
答案 0 :(得分:2)
没有什么与我们的问题直接相关,但如果您使用简单的Point结构来表示XY坐标,我是否可以建议您的代码会更加可读?类似的东西:
template <typename T> struct Point {
Point( const T & ax, const T & ay ) : x( ax ), y( ay ) {}
T x, y;
};
将是一个开始。然后,您可以创建Point的1-demensioned向量,并使用名称x&amp; y而不是数组索引。
只是一个建议 - 随意忽略......
答案 1 :(得分:0)
对于扫描线算法,您通常会在点数上使用词典排序:
但是,我怀疑排序是你问题的根源(错误和错过的交叉点)。
扫描线算法非常对舍入误差敏感。除非您绝对确保数学保持足够的精度以获得有效结果,否则无法使用浮点运算。
请查看此网页,了解有关此类问题的更多详细信息(和解决方案):
祝你好运。 是的 - 你正在写一个Bentley-Ottmann交叉扫描,不是吗?这些比其他扫描线算法更敏感,因为插入交叉点会因浮动的有限精度而略微改变交叉边缘的斜率。