一般问题
我需要创建一个任意半径的圆形渐变并将其映射到当前鼠标位置。该项目主要使用OpenGL和PySDL2,但由于遗留原因,也使用aggdraw(使用Pillow包装 PIL)。从广义上讲,SDL2 运行与 OpenGL 和大多数 UI 内容的交互,但 aggdraw 可以预见的是绘图。
我写了一个非常基本的函数。它的工作原理是鼠标运动和渐变绘制之间的延迟随着渐变半径而显着增长(请参阅我的代码;原因很明显)。
下面的代码使用了 aggdraw;aggdraw 对象在其他地方被转换为带有numpy的字节数组以传递给 OpenGL。
我对使用 SDL2 绘图库的解决方案持开放态度,但我从未使用过它,并且希望能像对待此类解决方案一样对待我。;)
特定上下文的注释
由于我提供的代码非常稀疏,出于礼貌,我应该提到这个接口与我已经编写了大约 1 年(KLIBS)的大型模块。所述模块在这里主要做了很多无关紧要的事情,但是,下面的函数确实插入了很多内部代码。唉,我还没有为模块编写文档,因为它(当前)是针对本地上下文的。
然而,这个函数是我的代码;并且库的其余部分已经过很好的测试;与其他任何事情相比,开销小于 10 毫秒。
我认为必须有可能比屏幕刷新率更快地做到这一点,延迟 容忍度约为 30 毫秒(项目的背景是视觉认知科学的研究生工作)。我知道这也取决于硬件;一般来说,我们谈论的是不超过 3 年的 iMac。
我确信这可以做得更好,但我已经超出了我的深度;我通常使用网络语言(javascript/PHP/html/css)!
def mouse_gradient(radius):
mp = mouse_pos() # custom function, just wraps fetching mouse coords from sdl2
mouse_grad = None
mouse_grad = aggdraw.Draw('RGBA', (radius, radius), (0, 0, 0, 0))
for n in range(radius):
n = float(n)
r = float(radius - n)
opacity = int(( 0.25 * n / radius) * 100)
brush = aggdraw.Brush((255, 0, 0), int(opacity))
tl = (radius - r) // 2 # ie. top-left
br = (radius - r) // 2 + r # ie. bottom-right
mouse_grad.ellipse((tl, tl, br, br), brush)
return mouse_grad # where it is subsequently blit to the screen