グラデーション作成3

keim_at_Siさんの助言を元に、改造しました。

  1. AB・AP<0の場合は開始色
  2. BA・BP<0の場合は終了色
  3. それ以外の場合は、n=(AB・AP)/(AB^2)⇒色=開始色*(1-n)+終了色*n

 
う〜む、恐ろしいほどスッキリしてしまいました。
線形代数すばらしや…。

// ============================================================================
// 汎用グラデーション作成2
// @param *bitmap 24ビットBitmap
// @param x1, y1 開始点
// @param y2, y2 終了点
// @param *fromColor 24ビットRGB構造体(開始色)
// @param *toColor 24ビットRGB構造体(終了色)
// ============================================================================
void gradation::MakeGradation2(CBitmap24 *bitmap, int x1, int y1, int x2, int y2, COLOR24 *fromColor, COLOR24 *toColor)
{
    // 開始点(x1,y1)をA、終了点(x2,y2)をB、現在の座標(i,j)をPとする。
    VECTOR2D AB(x2 - x1, y2 - y1);
    VECTOR2D BA(x1 - x2, y1 - y2);

    COLOR24 *ptr = (COLOR24 *)bitmap->GetPixelAddress(0, 0);
    for(int j = 0; j < bitmap->GetHeight(); j++)
    {
        for(int i = 0; i < bitmap->GetWidth(); i++)
        {
            VECTOR2D AP(i - x1, j - y1);
            VECTOR2D BP(i - x2, j - y2);
            if(AB * AP < 0) *ptr = *fromColor;
            else if(BA * BP < 0) *ptr = *toColor;
            else
            {
                float n = (float)(AB * AP)/(AB * AB);
                COLOR24 color;
                color.r = (fromColor->r * (1 - n)) + (toColor->r * n);
                color.g = (fromColor->g * (1 - n)) + (toColor->g * n);
                color.b = (fromColor->b * (1 - n)) + (toColor->b * n);
                *ptr = color;
            }
            ptr++;
        }
    }
}