Juceライブラリを使用してグラフィックを表示するプロジェクトに取り組んでいます。これまで、ライブラリのAPI関数を使用して線形および放射状のグラデーションを生成してきましたが、このライブラリがサポートするグラデーションのタイプは2つだけです。私は今、正多角形の形に従う別のタイプのグラデーションを生成する必要があります。ここでのキーワードはREGULARです。これは、すべてのエッジが同じ長さで、すべての頂点が1つの円上にあるポリゴンを意味します。
五角形の場合、これが私が取得したい結果をよりよく示すための写真です: http ://www.filterforge.com/wiki/index.php/Polygonal_Gradient
私のアプリケーションでは、任意の数のエッジを持つ多角形のグラデーションを指定できるようにしたいと思います。(五角形、六角形、八角形など...)
APIの制限を考えると、目的の結果を生成できる唯一の方法は、ピクセルごとにサーフェスマトリックスを塗りつぶし、各ピクセルのR、G、B、Aコンポーネントの値を数学的に計算することです。
これが私がこれまでに持っているコードです:
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
}
}
}
上記のコードは放射状のグラデーションを生成します。これは、1つのAPI関数を使用して生成できるのと同じタイプのグラデーションです。しかし、それは問題に取り組むための良い出発点のようです。
surface_data-赤、緑、青、およびアルファコンポーネントのピクセル強度を表す8ビット値のマトリックスです。
num_vertices-ポリゴングラデーションに必要な頂点(単一の円上に等間隔)の数です。
color1-グラデーションの開始色。
color2-グラデーションの終了色。
同じ方法でサーフェスを塗りつぶし、放射状ではなく多角形のグラデーションを作成する方法を知りたいです。
助けてくれてありがとう。
- ルイージ
この問題について少し考え直してください...座標系の原点をポリゴンの中心と見なすと、デカルト座標の任意の入力ポイントに対して、出力が最も近いものからの距離になるような方程式を見つけることになります。ポリゴンの側面。
私の直感によると、次の理由から、ある種の閉じた形の解が必要であることがわかります。
サークルの場合、
rho = sqrt(dx*dx + dy*dy);
円の中心からの半径方向の距離を示します。これは、無限の辺を持つ多角形と見なすことができます。
正方形の場合、
fmax(fabs(dx), fabs(dy));
正方形の最も近い辺からのチェビシェフ距離を示します。これは、4辺の多角形と見なすことができます。
ですから、2つの式のある種の組み合わせが中間のケースを与えるはずであり、それが最初の問題を解決するだろうと私は考えています。
私はこれらの線に沿って考えることを完全にやめていますか?
- ルイージ