优化简单的弹球解算器

时间:2014-02-18 14:37:35

标签: c performance algorithm optimization game-physics

我正在尝试解决编程挑战并且仅仅部分地成功完成了这项工作;我需要优化解决方案 - 这就是进来的地方。首先,参数:

  • 您会获得一些分段int x1, y1, x2, y2
  • 您的球有一个起点int px, py = INT_MAX
  • 你要模拟一个球从px, py直线向下“下降”(较小的y值)
    • 当它与一条线相交时,它会跟随该线直到其下端点
    • 当没有更多的线相交时,输出px

所以,我想:

  • 将行读入行元组列表int xtop, ytop, xbot, ybot
  • ybot排序。这允许我们跳过球已经过去的线,
  • 跟踪索引imin,使所有lines[i].ybot >= py i < imin,然后直到找不到交叉:
    • 最大化垂直交叉yi = kx + m
    • 设置px, py = lines[i].{x, y}bot

问题在于这个时间复杂度∈θ(n 2 ) - IOW,对于大输入来说很糟糕。

一个想法是使用类似k-d tree的东西,但问题是如果计算哪些线进入所谓的半空间是不是非常昂贵。

1 个答案:

答案 0 :(得分:0)

听起来好像你对point location in a planar subdivision感兴趣。我链接的slab分解方法是一个更简单的选项;简而言之,您从一个线段的每个端点延伸垂直线,使2n + 1个垂直。对于每个板,您计算一个二叉树,从上到下指示哪些段穿过板。然后,为了找到球击中的位置,确定它所在的哪个板块然后击中哪个段(如果有的话);这两个操作都是O(log n)-time。

要首先计算二叉树,请使用扫描线算法。从空二进制树开始,按x坐标的排序顺序处理端点。对于左端点,将段插入树中。对于右侧,将其从树中删除。假设段不交叉,则永远不需要在树中重新排序。天真地,我们必须在每一步之后复制树,但是从O(n ^ 2)将存储降低到O(n log n)的简单策略是使用纯功能的红黑树,从而无需副本。

此方法的总运行时间和空间为O(n log n)。