我正在使用Juce库来显示图形的项目。 到目前为止,我一直在使用库的API函数来生成线性和径向渐变,但是这是该库支持的唯一两种类型的渐变。我现在需要生成一种不同类型的渐变,它遵循规则凸多边形的形状。这里的关键词是REGULAR,意思是一个多边形,所有的边具有相同的长度,并且所有的顶点都位于一个圆上。多边形梯度
对于一个五边形的情况下,这里是一个图片,以更好地显示结果我想获得: http://www.filterforge.com/wiki/index.php/Polygonal_Gradient
对于我的申请,我希望能够与任意数量的指定多边形渐变边缘。 (五角形,六角形,八角形等)
由于API的限制,我能够产生所需结果的唯一方法是逐个像素填充表面矩阵,数学计算R的值, G,B,每个像素的分量。
下面是代码我迄今为止:
void render_surface(unsigned char *surface_data,
int width, int height, int linestride,
int num_vertices, t_rgba *color1, t_rgba *color2)
{
const double center_x = 0.5 * width;
const double center_y = 0.5 * height;
const double radius = 0.5 * MIN(width, height);
int x, y;
for (y = height; --y >= 0;) {
uint32_t *line = (uint32_t *)data;
data += linestride;
const double dy = y - center_y;
for (x = width; --x >= 0;) {
const double dx = x - center_x;
double rho = hypot(dx, dy);
rho /= radius; // normalize radius
// constrain
rho = CLIP(rho, 0.0, 1.0);
// interpolate
double a = color2->alpha + (color1->alpha - color2->alpha) * rho;
double r = color2->red + (color1->red - color2->red ) * rho;
double g = color2->green + (color1->green - color2->green) * rho;
double b = color2->blue + (color1->blue - color2->blue) * rho;
// premultiply alpha
r *= a;
g *= a;
b *= a;
#if LITTLE_ENDIAN
*line++ = ((unsigned int)((256.0 * (1.0 - DBL_EPSILON)) * a) << 24) // alpha
| ((unsigned int)((256.0 * (1.0 - DBL_EPSILON)) * r) << 16) // red
| ((unsigned int)((256.0 * (1.0 - DBL_EPSILON)) * g) << 8) // green
| (unsigned int)((256.0 * (1.0 - DBL_EPSILON)) * b); // blue
#else
*line++ = ((unsigned int)((256.0 * (1.0 - DBL_EPSILON)) * b) << 24) // blue
| ((unsigned int)((256.0 * (1.0 - DBL_EPSILON)) * g) << 16) // green
| ((unsigned int)((256.0 * (1.0 - DBL_EPSILON)) * r) << 8) // red
| (unsigned int)((256.0 * (1.0 - DBL_EPSILON)) * a); // alpha
#endif
}
}
}
以上代码生成的径向梯度,同一类型的梯度我可以产生利用一个API函数。不过,这似乎是解决问题的一个很好的起点。
surface_data - 是代表红色,绿色,蓝色和Alpha分量像素强度的8位值矩阵。
num_vertices - 是我们希望我们的多边形渐变具有的顶点数(在单个圆上等间距)。
color1 - 渐变的起始颜色。
color2 - 渐变的结束颜色。
我想知道如何以相同的方式填充曲面,创建多边形渐变而不是径向。
感谢您的任何帮助。
- 路易吉
再思考这个问题有点...... 如果我们考虑到我们的坐标系中的多边形的中心的原点,把它归结为找到一个方程使得对任意输入点以笛卡尔坐标表示,输出是距离多边形最近边的距离。
我的直觉告诉我,一定有某种封闭形式的解决方案,因为:
了一圈,
rho = sqrt(dx*dx + dy*dy);
让我们从圆的中心的径向距离,这可能是视为具有无限边的多边形。
对于方形,
fmax(fabs(dx), fabs(dy));
使我们从方形,这可以被视为具有4个边的多边形的最近侧的切比雪夫距离。
所以,我认为这两个公式的某种组合应该给中介案例,这将解决最初的问题。
我完全不考虑这些方面吗?
- 路易吉
是的,我没有试图直接实施你的解决方案,但至少在理论上它应该工作。但是它涉及相当多的计算。我希望得到某种封闭的形式方程,更简单,更简洁。等式的输入将是笛卡尔坐标中的一个点,输出是距最近一侧的距离。 – 2012-08-05 12:50:57
对于边数为偶数的多边形,只需计算多边形一半的像素,然后在中线上反射颜色,就可以显着加快这一速度。同样,对于具有4个边的倍数的多边形,只需计算多边形的四分之一像素,然后在水平和垂直中线上镜像像素颜色,就可以加快速度。 – 2012-08-05 12:57:36
是的,它看起来完全正确。谢谢。你介意分享你的实现吗?我会非常感兴趣的看到一些实际的代码。 (语言无所谓) – 2012-08-05 13:22:55