グラデーション作成2
dx=0のときとdy=0のときは別処理にして、
それぞれマイナスのときは、スワップしてフラグを立て、最後に反転させることで対応しました〜。
// 汎用グラデーション作成(開始座標取得ポインタ) int (*GetStartX1)(float a, float b, int j, int x); int GetStartX1_Y0(float a, float b, int j, int x) { return x; } int GetStartX1_X0(float a, float b, int j, int x) { return 0; } int GetStartX1_Nomal(float a, float b, int j, int x) { return (int)((j - b) / a); } // 汎用グラデーション作成(終了座標取得ポインタ) int (*GetStartX2)(float a, float b, int j, int x); int GetStartX2_Y0(float a, float b, int j, int x) { return x - 1; } int GetStartX2_X0(float a, float b, int j, int x) { return -1; } int GetStartX2_Nomal(float a, float b, int j, int x) { return (int)((j - b) / a); } // ============================================================================ // 汎用グラデーション作成 // @param *bitmap ビットマップ構造体 // @param x1, y1 開始点 // @param y2, y2 終了点 // @param *fromColor 24ビットRGB構造体(開始色) // @param *toColor 24ビットRGB構造体(終了色) // ============================================================================ void gradation::MakeGradation(BITMAP *bitmap, int x1, int y1, int x2, int y2, COLOR24 *fromColor, COLOR24 *toColor) { int dx = x2 - x1; int dy = y2 - y1; float rateColor; float a1 = 0; float b1 = 0; float a2 = 0; float b2 = 0; bool flgRevSide = false; // 左右反転フラグ bool flgRevInverse = false; // 上下反転フラグ if(x1 > x2) { flgRevSide = true; SWAP(&x1, &x2); } if(y1 > y2) { flgRevInverse = true; SWAP(&y1, &y2); } if(dy == 0) { GetStartX1 = GetStartX1_Y0; GetStartX2 = GetStartX2_Y0; rateColor = (float)(x2 - x1); } else if(dx == 0) { GetStartX1 = GetStartX1_X0; GetStartX2 = GetStartX2_X0; rateColor = (float)(y2 - y1); } else { GetStartX1 = GetStartX1_Nomal; GetStartX2 = GetStartX2_Nomal; float rate = (float)dy / dx; // x方向への開始直線 y1 = a1 * x1 + b1となる式を求める a1 = -1 / rate; // 傾き b1 = y1 - (a1 * x1); // 切片 // x方向への終了直線 y2 = a2 * x2 + b2となる式を求める a2 = a1; b2 = y2 - (a2 * x2); // x方向への色の増加率を求める rateColor = (b2 - b1) * rate; } if(rateColor < 0) rateColor *= -1; // 正の値に変換 COLOR24_F colorF = { (toColor->r - fromColor->r) / rateColor, (toColor->g - fromColor->g) / rateColor, (toColor->b - fromColor->b) / rateColor }; for(int j = 0; j < bitmap->info_header.biHeight; j++) { // x座標のグラデーション開始点と終了点を求める // y = a * x + b を x = (b - y) / a に変形 int startX = GetStartX1(a1, b1, j, x1); int endX = GetStartX2(a2, b2, j, x2); COLOR24_F tmpColorF = { fromColor->r, fromColor->g, fromColor->b }; if(startX < 0) { for(int i = 0; i > startX; i--) { if(startX < i && i <= endX) { tmpColorF.r += colorF.r; tmpColorF.g += colorF.g; tmpColorF.b += colorF.b; } } } if(dx == 0) { if(y1 < j && j <= y2) { for(int k = 0; k < j - y1; k++) { tmpColorF.r += colorF.r; tmpColorF.g += colorF.g; tmpColorF.b += colorF.b; } } else if(j > y2) { tmpColorF.r = toColor->r; tmpColorF.g = toColor->g; tmpColorF.b = toColor->b; } } for(int i = 0; i < bitmap->info_header.biWidth; i++) { if(startX < i && i <= endX) { // グラデーションする範囲 tmpColorF.r += colorF.r; tmpColorF.g += colorF.g; tmpColorF.b += colorF.b; } bitmap->pixel_data[j][i][0] = (unsigned char)tmpColorF.r; bitmap->pixel_data[j][i][1] = (unsigned char)tmpColorF.g; bitmap->pixel_data[j][i][2] = (unsigned char)tmpColorF.b; } } if(flgRevSide) ReverseRightToLeftPixel(bitmap); if(flgRevInverse) ReverseTopToBottomPixel(bitmap); }
しかし、香ばしいコードですね…(´Д`;