生成基于像素的螺旋渐变
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) )
这只是将中心的距离与角度相加,并进行适当的缩放。
我有一个程序可以创建基于像素的渐变(这意味着它计算每个像素的渐变步骤,然后计算该步骤的颜色,然后为像素赋予该颜色)。
我想实现螺旋渐变(如下所示)。
我的程序可以创建圆锥渐变(如下所示),其中每个像素根据它与中点之间的角度(有效地映射中点像素角度 [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) )
这只是将中心的距离与角度相加,并进行适当的缩放。