三角塗りつぶし


三角塗りつぶし

任意の3点で作られる三角形をラインで塗りつぶすアルゴリズム。
手順としては、三点をY座標を小さい順にソートして上から各点を結ぶ直線を
辿って線を引いていく。
ソートは座標が3つしかないので、3項演算の組み合わせで実現しています。
そのため3回の比較と6回の代入だけでソートできます。
16ビット精度の固定小数でループ部分は加算のみで計算しています。C等で組む場合には
ある程度意味があるかな?SPALMでは演算一回のオーバーヘッドがでかすぎて
乗除と加減の速度差はほぼ皆無なので意味ないでしょう。

origin(120,120)
b=2
label 0
lock()
clear(-120,-120,240,240)
if(input(0)){end}

color((ox*b+100)*51/40,(ax*b+100)*51/40,(bx*b+100)*51/40)
for(ox=cos(t)/b,
oy=sin(t)/b,
ax=cos(t+120)/b,
ay=sin(t*3+120)/b,
bx=cos(t+240)/b,
by=sin(t*2+240)/b,
t=t+1,
oy<ay?oy<by?ax>bx?
(x1=ox,y1=oy,x2=bx,y2=by,x3=ax,y3=ay):
(x1=ox,y1=oy,x2=ax,y2=ay,x3=bx,y3=by);:
ax>ox?
(x1=bx,y1=by,x2=ox,y2=oy,x3=ax,y3=ay):
(x1=bx,y1=by,x2=ax,y2=ay,x3=ox,y3=oy);;
:ay<by?ox>bx?
(x1=ax,y1=ay,x2=bx,y2=by,x3=ox,y3=oy):
(x1=ax,y1=ay,x2=ox,y2=oy,x3=bx,y3=by);
:ax>ox?
(x1=bx,y1=by,x2=ox,y2=oy,x3=ax,y3=ay):
(x1=bx,y1=by,x2=ax,y2=ay,x3=ox,y3=oy);;;,
sx1=sx2=x1<<16,
y2==y1?sx1=x2<<16:dx1=(x2-x1<<16)/(y2-y1);,
y3==y1?sx2=x3<<16:dx2=(x3-x1<<16)/(y3-y1);,
ch=0,
y2>y3&&(ty=y2,y2=y3,y3=ty,ch=1),i=y1;i<y2;sx1=sx1+dx1,sx2=sx2+dx2,i++){
line(sx1>>16,i,sx2>>16,i)
}
for(ch?(sx2=x3<<16,dx2=y3==y2?x3-x2<<16:(x3-x2<<16)/(y2-y3);):
(sx1=x2<<16,dx1=y3==y2?x3-x2<<16:(x3-x2<<16)/(y3-y2););;i<=y3;sx1=sx1+dx1,sx2=sx2+dx2,i++){
line(sx1>>16,i,sx2>>16,i)
}
unlock(1)
goto 0