我正在使用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