【问题标题】:Get Grid Cells Overlapping Parabola获取重叠抛物线的网格单元
【发布时间】:2021-09-16 08:27:25
【问题描述】:

如何在抛物线上的两个点定义的区间内有效地找到与抛物线(超级覆盖)重叠的所有像素?所有坐标都是整数,网格单元的大小为 1x1。 抛物线由 f(x) = ax^2 + bx 给出,其中 a 和 b 已知(假设 c = 0)

我发现了这种查找与一条线重叠的所有网格单元的实现。它如何适应使用抛物线? http://playtechs.blogspot.com/2007/03/raytracing-on-grid.html

【问题讨论】:

    标签: algorithm geometry


    【解决方案1】:

    从初始点开始,然后在每一步检查接下来将与哪个单元格相交。此任务假定像素不是无大小的点,而是定义大小的单元S。初始单元格具有坐标(0,0)

    使用抛物线方程我们计算抛物线与垂直线的交点x=S

    y = a * S * S + b * S
    y_index = floor(y/S)`
    

    所以我们遍历单元格(0,0), (0,1)...(0,y_index),然后直接进入(1,y_index)y_index 可能等于零)

    重复与第二级线y_index_1 = a * 2*S*2*S + b*2*S的交点,得到y_index1,标记单元格从(1,y_index)(1,y_index1)等等。

    Python 示例

    import math
    def markcells(a, b, S, xmax):
        newy = 0
        oldy = 0
        step = 0
        while step * S <= xmax:
            step += 1
            edgex = step * S
            newy = math.floor((a*edgex*edgex + b*edgex)/S)
            lst = []
            for y in range(oldy, newy + 1):
                lst.append([step - 1, y])
            print(lst)
            oldy = newy
    
    markcells2(0.05, 0.1, 1, 5)
    
    [[0, 0]]
    [[1, 0]]
    [[2, 0]]
    [[3, 0], [3, 1]]
    [[4, 1]]
    [[5, 1], [5, 2]]
    

    附言
    我省略了抛物线恰好穿过单元格角的情况(当y/S 是整数时) - 为这种情况选择想要的策略:要么标记单元格,要么不标记(例如,抛物线x=2x=2:我们应该标记@987654336 @ 和(4,3)?)

    【讨论】:

    • 如果抛物线太陡,那么抛物线可以在峰值所在的网格 x 坐标处以相同的步长在单元格中上下移动。在这种情况下,这段代码会遗漏一些网格单元格。
    • 值得计算抛物线顶点x坐标xv=-b/2a,对应y坐标yv=-b^2/4a+c,并分别计算抛物线的左右分支
    • 是的,但简单地调用标记单元两次是行不通的。一种方法是将循环移动到另一个函数。在 markcells 中,执行 xmax = min(xmax, xv) 的循环,然后执行 edgex = xv 的循环体,然后以实际 xmax 作为 xmax 执行循环。
    猜你喜欢
    • 2021-12-30
    • 1970-01-01
    • 1970-01-01
    • 2021-09-09
    • 2022-11-14
    • 2011-06-09
    • 1970-01-01
    • 2016-07-11
    • 1970-01-01
    相关资源
    最近更新 更多