这是一个相当简单的算法问题,但我的实现使速度和简单性成为所希望的。我有两个Line对象,每个对象以{unsigned int x, unsigned int y}
的形式保存两个坐标结构。第一个坐标保持线的起点和第二个坐标的位置,即它的结尾。假设线条在网格上只能是垂直或水平,我如何检查两条线平行重叠或垂直相交。优选地,这被实现为行中的方法:
- (BOOL)intersectsLine:(Line)otherLine;
谢谢!
答案 0 :(得分:2)
由于我们只讨论水平线或垂直线,所以第一步我会检查线是否具有相同的方向。
typedef (NSUInteger, LineOrientation) {
HorizontalLine = 0,
VerticalLine = 1
};
所以,给出一条有两点的线......
LineOrientation line1orientation;
LineOrientation line2orientation;
if (a.x1 == a.x2) {
line1orientation = HorizontalLine;
} else {
line1orientation = VerticalLine;
}
if (b.x1 == b.x2) {
line2orientation = VerticalLine;
} else {
line2orientation = Horizontal;
}
现在我们需要检查它们是水平的,垂直的还是每个都是水平的,然后测试特定的值:
if (line1orientation == line2orientation) {
if (line1orientation == VerticalLine) {
if (a.x1 != b.x1) {
return false;
} else {
if (a.y1 < a.y2) {
return ((b.y1 > a.y1 && b.y1 < a.y2) ||
(b.y2 > a.y1 && b.y2 < a.y2));
} else {
return ((b.y1 > a.y2 && b.y1 < a.y1) ||
(b.y2 > a.y2 && b.y2 < a.y1));
}
}
} else {
if (a.y1 != b.y1) {
return false;
} else {
if (a.x1 < a.x2) {
return ((b.x1 > a.x1 && b.x1 < a.x2) ||
(b.x2 > a.x1 && b.x2 < a.x2));
} else {
return ((b.x1 > a.x2 && b.x1 < a.x1) ||
(b.x2 > a.x2 && b.x2 < a.x1));
}
}
}
} else {
if (line1orientation == VerticalLine) {
if (a.y1 < a.y2) {
return (((b.y1 > a.y1) && (b.y1 < a.y2)) && ((b.x1 > a.x1 && b.x2
< a.x1) || (b.x2 > a.x1 && b.x1 < a.x1)));
} else {
return (((b.y1 > a.y2) && (b.y1 < a.y1)) && ((b.x1 > a.x1 && b.x2
< a.x1) || (b.x2 > a.x1 && b.x1 < a.x1)))
}
} else {
if (a.x1 < a.x2) {
return (((b.x1 > a.x1) && (b.x1 < a.x2)) && ((b.y1 > a.y1 && b.y2
< a.y2) || (b.y2 > a.y1 && b.y1 < a.y1)));
} else {
return (((b.x1 > a.x2) && (b.x1 < a.x1)) && ((b.y1 > a.y1 && b.y2
< a.y2) || (b.y2 > a.y1 && b.y1 < a.y1)));
}
}
如果你开始检查以确保线条不是同一条线,这可能会更有效。