- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我在用 C# 正确实现 Bentley-Ottmann 算法时遇到了一些问题。我正在尝试根据伪代码 here 来实现它.我在下面发布了我的主要代码。假设我的 BST
和 PriorityQueue
类实现正确,您是否发现代码有任何问题?
没有错误,但不是所有的交点都找到了,只有一些。我的猜测是代码的 else
部分有错误(当当前事件是一个交点时)。我不确定交换 BST 中两个段的位置的伪代码是什么意思。我这样做的方式好吗?因为最后,这两者在 BST 中并没有真正交换。我也不能只改变他们的位置,因为这可能会破坏 BST 属性。
此外,我假设 BST 中的段按其左端点的 Y
坐标排序是否正确?
我注意到的另一个我似乎无法追踪的错误是有时 (0, 0)
点进入 eventList
。 (0, 0)
在没有交集的情况下由 Geometry.Intersects
输出,但在这种情况下 if
条件应该阻止它被添加。我不知道它是怎么进来的。如果我在添加一个点后打印 eventList
的内容,(0, 0)
永远不会出现。如果我在提取和弹出元素后打印内容,(0, 0)
有时会出现。这可能与混淆引用的 Pop()
方法有关,还是我的 PriorityQueue
实现中存在问题?
如果需要,我也可以展示我对 BST 和优先级队列的实现。
static class BentleyOttman
{
private static void AddIntersectionEvent(PriorityQueue eventList, Segment segEv, Segment segA, SegPoint i)
{
i.IntersectingSegments = new Tuple<Segment, Segment>(segEv, segA);
i.Type = SegmentPointType.IntersectionPoint;
eventList.Add(i);
}
public static void Solve(Panel surface, TextBox debug)
{
debug.Clear();
var segList = Generator.SegList;
PriorityQueue eventList = new PriorityQueue();
foreach (Segment s in segList)
{
eventList.Add(new SegPoint(s.A, s, SegmentPointType.LeftEndpoint));
eventList.Add(new SegPoint(s.B, s, SegmentPointType.RightEndpoint));
}
BST sweepLine = new BST();
while (!eventList.Empty)
{
SegPoint ev = eventList.Top();
eventList.Pop();
if (ev.Type == SegmentPointType.LeftEndpoint)
{
Segment segEv = ev.Segment;
sweepLine.Insert(segEv);
Segment segA = sweepLine.InorderPre(segEv);
Segment segB = sweepLine.InorderSuc(segEv);
SegPoint i = new SegPoint();
if (segA != null && Geometry.Intersects(segEv, segA, out i.Point))
{
AddIntersectionEvent(eventList, segA, segEv, i);
}
if (segB != null && Geometry.Intersects(segEv, segB, out i.Point))
{
AddIntersectionEvent(eventList, segEv, segB, i);
}
}
else if (ev.Type == SegmentPointType.RightEndpoint)
{
Segment segEv = ev.Segment;
Segment segA = sweepLine.InorderPre(segEv);
Segment segB = sweepLine.InorderSuc(segEv);
sweepLine.Remove(segEv);
SegPoint i = new SegPoint();
if (segA != null && segB != null && Geometry.Intersects(segA, segB, out i.Point))
{
AddIntersectionEvent(eventList, segA, segB, i);
}
}
else
{
Generator.DrawPoint(ev.Point, surface, Brushes.Red);
Segment seg1 = ev.IntersectingSegments.Item1;
Segment seg2 = ev.IntersectingSegments.Item2;
sweepLine.Remove(seg1);
sweepLine.Remove(seg2);
Segment t = new Segment(seg1);
seg1 = new Segment(seg2);
seg2 = new Segment(t);
sweepLine.Insert(seg1);
sweepLine.Insert(seg2);
Segment segA = sweepLine.InorderPre(seg2);
Segment segB = sweepLine.InorderSuc(seg1);
SegPoint i = new SegPoint();
if (segA != null && Geometry.Intersects(seg2, segA, out i.Point))
AddIntersectionEvent(eventList, segA, seg2, i);
if (segB != null && Geometry.Intersects(seg1, segB, out i.Point))
AddIntersectionEvent(eventList, seg1, segB, i);
}
}
}
}
最佳答案
如果不了解其他类的确切功能,我真的无法理解您的代码,但我可以回答您的其他一些问题。
线段在 BST 中按其与扫掠线相交的 Y 坐标排序。因此,当我们遇到左端点时,我们使用进入线段左端点的 y 坐标将线段添加到树中(将其与另一线段与扫掠线相交的 Y 坐标进行比较)。当我们遇到右端点时,我们从树中删除该段。当我们遇到一个交叉点时,这两个线段的交点顺序与扫描线交换,所以我们交换树中的两个线段。例如考虑两个部分
A = {(-1,1),(1,-1)} and
B = {(-1,-1),(1,1)}
当扫描线的 X 坐标小于 0 时,线段 A 与扫描线的交点大于线段 B 与扫描线的交点。如果扫描线大于 0,则相反。 (画一幅画。)
画一个简单的例子,一步一步地跟踪发生的事情,画出每个事件的扫描线,并在事件之间的列中标记段,然后跟踪 BST 并验证BST 与其有效区域中的段保持相同的顺序。 (很抱歉,如果这不是很清楚。)
注意:这假设您的线段处于“一般位置”,即没有线段是垂直的,不超过两个线段在给定点相交,等等。处理不在一般位置的线段在 wikipedia page
关于c# - 实现 Bentley-Ottmann 算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4490331/
谁能告诉我哪种数据结构最适合用于 Bentley Ottman 算法中的扫描线和事件队列?堆对事件队列有意义,但对扫描线没有意义,因为我们需要最后插入点的两个邻居。如何实现 log(n) 插入时间并在
Bentley-Ottmann 算法用于确定直线列表的交点。但是正如这里提到的in Wiki , 有一些缺点: The algorithm assumes that line segments are
C# 或 Java 中是否存在任何现有的 Bentley-Ottmann 算法实现/库? 最佳答案 这里至少有一个C++实现(包括描述): http://softsurfer.com/Archive/
下面是Hoare我编写的分区算法是根据给定的主元对数组进行分区(在这种情况下,它是数组的第一个元素,这是一个相当糟糕的选择!)。然而,Bentley-McIlroy 3-way partitionin
我正在实现 Bentley-Ottmann 算法找到一组线段交点, 不幸的是我不明白一些事情。 例如: 如何获取图像中片段 Sj 的邻居。 我正在为 sweepLine 状态使用平衡二叉搜索树,但在阅
我认为我对快速排序的工作原理有很好的理解,直到我在 http://code.google.com/edu/algorithms/index.html 上观看了视频。其中 Jon Bentley 介绍了
我在用 C# 正确实现 Bentley-Ottmann 算法时遇到了一些问题。我正在尝试根据伪代码 here 来实现它.我在下面发布了我的主要代码。假设我的 BST 和 PriorityQueue 类
Bentley-Ottmann 算法用于计算线段的交点。 但是,我不想找到所有直线之间的交点,而是想找到两组直线之间的交点。也就是说,对于行组 A 中的每一行,我想知道这些行与组 B 中的行之间的交点
我需要获取给定文档的物理文件路径。 在数据库中运行一些查询,我发现我可以获得一些表中的大部分信息: dms_stor 的 o_path,dms_proj 的 o_projectcode 和 [dms_
我要解决的问题是找到跨越给定矩形的线段之间的所有交点。线是随机生成的,直到给定数量,顺序为 1E3-1E4,并且所有端点都可以在矩形上找到。它基本上是在一个圆圈中生成随机和弦的矩形情况。在低密度系统
我正在 Lua 中实现 Bentley-Ottmann 算法,使用位于 here 的伪代码在多边形中查找相交点. 我对实现算法还比较陌生,所以我无法理解它的所有部分。到目前为止,这是我的代码: loc
已结束。此问题不符合 Stack Overflow guidelines .它目前不接受答案。 我们不允许提出有关书籍、工具、软件库等方面的建议的问题。您可以编辑问题,以便用事实和引用来回答它。 关闭
在他们的谈话中 "Quicksort is Optimal" , Sedgewick 和 Bentley 指的是快速排序分区步骤的修改版本,称为 Bentley-McIlroy 三路分区。这个版本的分
我正在尝试实现描述的 Bentley-Ottmann 算法 here在 C# 中。特别是,我在扫描线状态结构中为 Segment 类实现 IComparable 时遇到问题。下面列出了段类: publ
我想基于此描述,使用 STL 元素实现 Bentley-Ottmann 线段交叉算法。 Bentley-Ottmann Wikipedia 我正在苦苦挣扎的是优先队列的实现。描述要求我删除任何交叉点:
二分查找可以通过多种方式实现——递归、迭代、条件等。我从 Bentley 的书“Programming pearls: Writing correct programs”中获取了这个,这是一个迭代实现
对 C 完全陌生。只是想通过运行 John Bentley 的 Anagram(我相信是第 2 列)程序来掌握 linux 和 C 编程的窍门。我很确定我一字不差地复制了这段代码(必须添加标题等),但
我是一名优秀的程序员,十分优秀!