●球
OPTION ARITHMETIC NATIVE !CPUパワー
SET COLOR MODE "NATIVE"
GLOAD "c:\BASICw32\SAMPLE\ZENKOUJI.JPG" !画像を読み込む
ASK PIXEL SIZE (0,0; 1,1) w,h !画像の縦横の大きさ(ピクセル単位)を調べる
DIM p(w,h),q(w,h) !画像の大きさに対応する配列要素を用意する
ASK PIXEL ARRAY (0,1) p !画像の各点の色情報を配列に格納する
PRINT "画像の大きさ 縦:";h;" 横:";w
!SET BITMAP SIZE w,h !ウィンドウの大きさを画像に合わせる
LET Rx=100 !球の半径
LET Ry=100
LET Sx=150 !球の中心
LET Sy=150
LET Tx=w/2+50 !貼付け位置
LET Ty=h/2
DIM M1(3,3),M2(3,3),M3(3,3),M6(3,3),M7(3,3),M8(3,3)
MAT M1=IDN !中心の移動
LET M1(1,3)=-Sx
LET M1(2,3)=-Sy
MAT M2=IDN !比率の変換
LET M2(1,1)=1/Rx
LET M2(2,2)=1/Ry
MAT M7=IDN !INV(M2)
LET M7(1,1)=Rx
LET M7(2,2)=Ry
MAT M8=IDN !貼付け画像の移動
LET M8(1,3)=Tx
LET M8(2,3)=Ty
MAT q=ZER !黒色
!座標変換 f:(x,y)→(xx,yy)の逆変換を考える
DIM t(3)
FOR yy=1 TO h !変換後の画素位置で走査する
FOR xx=1 TO w
LET t(1)=xx !非線形変換前の線形変換
LET t(2)=yy
LET t(3)=1
MAT t=M1*t
MAT t=M2*t
LET tt=SQR(t(1)*t(1)+t(2)*t(2)) !(x,y)に応じて回転する
IF tt=0 THEN
LET co=0
LET si=0
ELSE
LET co=t(1)/tt
LET si=t(2)/tt
END IF
MAT M3=IDN
LET M3(1,1)=co !X軸上への写像
LET M3(1,2)=si
LET M3(2,1)=-si
LET M3(2,2)=co
MAT t=M3*t
!非線形変換
IF t(1)>=0 AND t(1)<1 THEN !球の内
LET t(1)=ASIN(t(1)) !凸
!LET t(1)=ATN(t(1))*1.5 !凹
LET op=1 !変換された座標を使う
ELSE !球の外
LET op=0 !計算誤差を避けるため元の値を使う
END IF
SELECT CASE op !元の画素を読み込んで書き込む
CASE 0
LET q(xx,yy)=p(xx,yy)
CASE 1
MAT M6=IDN !INV(M3) !非線形変換後の線形変換
LET M6(1,1)=co
LET M6(1,2)=-si
LET M6(2,1)=si
LET M6(2,2)=co
MAT t=M6*t
MAT t=M7*t
MAT t=M8*t
!PRINT xx;yy !debug
!MAT PRINT t;
LET x=INT(t(1)) !元の画素での位置
LET y=INT(t(2))
IF x<1 OR x>w OR y<1 OR y>h THEN !範囲内なら
ELSE
LET q(xx,yy)=p(x,y)
END IF
CASE ELSE !NOP
END SELECT
NEXT xx
NEXT yy
MAT PLOT CELLS, IN 0,1; 1,0 :q !画像を表示する
END
●モザイク
OPTION ARITHMETIC NATIVE !CPUパワー
SET COLOR MODE "NATIVE"
GLOAD "c:\BASICw32\SAMPLE\ZENKOUJI.JPG" !画像を読み込む
ASK PIXEL SIZE (0,0; 1,1) w,h !画像の縦横の大きさ(ピクセル単位)を調べる
DIM p(w,h),q(w,h) !画像の大きさに対応する配列要素を用意する
ASK PIXEL ARRAY (0,1) p !画像の各点の色情報を配列に格納する
PRINT "画像の大きさ 縦:";h;" 横:";w
!SET BITMAP SIZE w,h !ウィンドウの大きさを画像に合わせる
LET Rx=10 !1辺の長さ
LET Ry=10
LET th=RAD(30) !方向
DIM M1(3,3),M2(3,3),M7(3,3),M8(3,3)
MAT M1=IDN !画像の中央を原点へ
LET M1(1,3)=-w/2
LET M1(2,3)=-h/2
MAT M2=IDN !方向をX軸に一致させ、半径を1とする
LET M2(1,1)=COS(th)/Rx
LET M2(1,2)=SIN(th)/Rx
LET M2(2,1)=-SIN(th)/Ry
LET M2(2,2)=COS(th)/Ry
MAT M7=IDN !INV(M2)
LET M7(1,1)=COS(th)*Rx
LET M7(1,2)=-SIN(th)*Rx
LET M7(2,1)=SIN(th)*Ry
LET M7(2,2)=COS(th)*Ry
MAT M8=IDN !INV(M1)
LET M8(1,3)=w/2
LET M8(2,3)=h/2
MAT q=ZER !黒色
!座標変換 f:(x,y)→(xx,yy)の逆変換を考える
DIM t(3)
FOR yy=1 TO h !変換後の画素位置で走査する
FOR xx=1 TO w
LET t(1)=xx !非線形変換前の線形変換
LET t(2)=yy
LET t(3)=1
MAT t=M1*t
MAT t=M2*t
!非線形変換
LET t(1)=INT(t(1))+0.5
LET t(2)=INT(t(2))+0.5
MAT t=M7*t !非線形変換後の線形変換
MAT t=M8*t
!PRINT xx;yy !debug
!MAT PRINT t;
LET x=INT(t(1)) !元の画素での位置
LET y=INT(t(2))
IF x<1 OR x>w OR y<1 OR y>h THEN !範囲内なら
ELSE
LET q(xx,yy)=p(x,y)
END IF
NEXT xx
NEXT yy
MAT PLOT CELLS, IN 0,1; 1,0 :q !画像を表示する
END