生成基于像素的螺旋渐变

Generating a pixel-based spiral gradient

我有一个程序可以创建基于像素的渐变(这意味着它计算每个像素的渐变步骤,然后计算该步骤的颜色,然后为像素赋予该颜色)。

我想实现螺旋渐变(如下所示)。

我的程序可以创建圆锥渐变(如下所示),其中每个像素根据它与中点之间的角度(有效地映射中点像素角度 [0...2PI])在渐变中分配一个步骤到 [0...1]).

在我看来,螺旋渐变是应用了一些附加函数的圆锥渐变,其中给定像素的渐变步长不仅取决于角度, 但在应用于中点和像素之间的欧氏距离的一些附加非线性函数上。

我设想一个解决方案将采用原始 (x, y) 像素坐标并将其在 x 和 y 轴上移动一定量,从而产生新坐标 (x2, y2)。然后,对于每个像素,我只需计算中点与其新的位移坐标 (x2, y2) 之间的角度,并将此角度用作该像素的渐变步长。但我需要帮助的正是这个位移函数。 ..当然,可能还有其他更好的方法。

下面是一个简单的白到黑的圆锥渐变。我展示了我想象的位移是如何工作的,但它是关于这个函数的细节(非线性),我无法实现。

我的圆锥渐变代码:

public void conicGradient(Gradient gradient, PVector midPoint, float angle) {
    
    float rise, run;
    double t = 0;

    for (int y = 0, x; y < imageHeight; ++y) {
        rise = midPoint.y - y;
        run = midPoint.x;
        for (x = 0; x < imageWidth; ++x) {

            t = Functions.fastAtan2(rise, run) + Math.PI - angle;

            // Ensure a positive value if angle is negative.
            t = Functions.floorMod(t, PConstants.TWO_PI);

            // Divide by TWO_PI to get value in range 0...1
            step = t *= INV_TWO_PI;

            pixels[imageWidth * y + x] = gradient.ColorAt(step); // pixels is 1D pixel array

            run -= 1;
        }
    }
}

肉眼看来,t = ... fastAtan2...之后,你只需要:

t += PConstants.TWO_PI * Math.sqrt( (rise*rise + run*run) / (imageWidth * imageWidth + imageHeight * imageHeight) )

这只是将中心的距离与角度相加,并进行适当的缩放。