アンチエイリアス付きの自由線描画(2)・円の形状

円の形状
前回は、円の塗りつぶしにおいて、輪郭がアンチエイリアスされた通常の円を描画しました。
この場合、描画された線は、硬い感じになります。

もうちょっと柔らかい線が描きたい、という場合は、描画する円の形状を変えてみると、線の見え方を変えることができます。
スクリーンショット&ソースファイル


>> 026_aaline2.c
解説
今回は、円の描画部分を変更しました。

void drawpoint(double x,double y,double radius)
{
    int nx1,ny1,nx2,ny2,ix,iy,jx,jy;
    double xx,yy,rr,val,d;
    SPTK_PIX_RGBA col;
    
    /* 描画先の範囲 */
    
    nx1 = (int)floor(x - radius);
    ny1 = (int)floor(y - radius);
    nx2 = (int)floor(x + radius);
    ny2 = (int)floor(y + radius);
    
    /* 描画先ループ */
    
    rr = radius * radius;
    
    for(iy = ny1; iy <= ny2; iy++)
    {
        for(ix = nx1; ix <= nx2; ix++)
        {
            /* オーバーサンプリング */
            
            val = 0;
            
            for(jy = 0; jy < 8; jy++)
            {
                yy = iy - y + jy * (1.0 / 8);
            
                for(jx = 0; jx < 8; jx++)
                {
                    xx = ix - x + jx * (1.0 / 8);
                    
                    d = (xx * xx + yy * yy) / rr;
                    
                    if(d < 1.0) val += 1.0 - d;
                }
            }
            
            val = val / 64;
            
            /* 結果 */
            
            col = drawcol;
            col.a = (int)(drawcol.a * val);
            
            sptk_image32_setpixel_rgba(layerimg, ix, iy, &col);
        }
    }
}

柔らかい感じの円にするため、円の濃度を、中心にいくほど濃くなるようにしました。

円の内部の濃度を計算する方法として、今回は、「(xx * xx + yy * yy) / rr」で、円の中心を 0.0、円の外側を 1.0 とした値を使います。

この値が 1.0 以上なら円の範囲外なので、濃度にはカウントしません。
円の内部であれば、反転した値を濃度として加算します。
(値を反転するのは、円の中心を濃度 1.0 とするため)

サブピクセルのループが終わったら、「8x8=64」で割って、濃度の平均値を得ます。

結果として、val には 0.0〜1.0 の範囲で濃度率が入っているので、後はそれを描画濃度に適用します。

この、円の内部の濃度を計算する部分をカスタマイズすれば、「線の硬さ」などのパラメータ値を付けて、円の形状を変化させることもできます。