新しく発言する EXIT インデックスへ
歪絵(アナモルフォーズ)の描き方

  歪絵(アナモルフォーズ)の描き方 ひでき 2007/10/20 16:20:47 
  たとえば、このようなものですか?(確認) 山中和義 2007/10/20 17:14:20 
   └山中さま ひでき 2007/10/20 17:56:47 
    └おそらく複素数を用いれば表現できる写像だ... 白石 和夫 2007/10/20 18:17:53 
     ├射影変換であればDRAW文を用いて簡単に実行... 白石 和夫 2007/10/20 18:36:21 
     │└泥臭いプログラムになる理由をもう少し説明... 白石 和夫 2007/10/20 21:04:25  (修正1回)
     │ └100OPTIONARITHMETICcomplex 白石 和夫 2007/10/21 11:34:08 
     │  └画面の下半分が変換元の平面,上半分が変換... 白石 和夫 2007/10/21 11:44:32 
     └!ゆがんだ絵(アナモルフォーシス)-机上に... 山中和義 2007/10/21 15:00:59  (修正1回)
      └続き(サブーチン) 山中和義 2007/10/21 15:02:14  (修正1回)
       └白石先生、山中さま ひでき 2007/10/21 16:23:37 
        ├円錐です。 白石 和夫 2007/10/21 21:18:23 
        │├座標系は変換先を基準にしています。 白石 和夫 2007/10/21 21:37:39 
        │└ゴミがでるので修正 白石 和夫 2007/10/26 08:34:02 
        ├リニア・アナモルフォーシスですが,リンク... 白石 和夫 2007/10/22 07:29:04 
        │└!平面へ射影する行列-影 山中和義 2007/10/22 17:46:32  (修正5回)
        │ └ありがとうございました。 ひでき 2007/10/23 23:40:42 
        │  ├処理の流れとその説明を付加しておきます。 山中和義 2007/10/24 14:20:36  (修正2回)
        │  └図学、幾何学による作図法の参考サイト 山中和義 2007/10/25 10:07:27 
        ├円柱の画像版 山中和義 2007/10/25 22:59:29  (修正1回)
        ├円錐と床、画像版 山中和義 2007/10/26 23:00:55 
        └いろいろとご教示いただき、ありがとうござ... ひでき 2007/10/27 13:06:02 
         └アナモルフォーズのページを作りました。 白石 和夫 2007/11/11 11:12:12 

  歪絵(アナモルフォーズ)の描き方 ひでき 2007/10/20 16:20:47  ツリーへ

歪絵(アナモルフォーズ)の描き方 返事を書く ノートメニュー
ひでき <jweuhhncel> 2007/10/20 16:20:47
歪絵(アナモルフォーズ、アナモルフォーシス)の
シミュレーション(原画と虚像)を描きたいのですが、
ご存知の方、お教え願えませんか。
宜しくお願いします。

  たとえば、このようなものですか?(確認) 山中和義 2007/10/20 17:14:20  ツリーへ

Re: 歪絵(アナモルフォーズ)の描き方 返事を書く ノートメニュー
山中和義 <drdlxujciw> 2007/10/20 17:14:20
たとえば、このようなものですか?(確認)

http://www.ngk.co.jp/site/no70/content.htm

   └山中さま ひでき 2007/10/20 17:56:47  ツリーへ

Re: たとえば、このようなものですか?(確認) 返事を書く ノートメニュー
ひでき <jweuhhncel> 2007/10/20 17:56:47
山中さま

早速調べていただきありがとうございます。

このHPの「工作と実験の手順」の6番の
ようなシミュレーションを描きたいのです。

具体的には、
左側の船の図を右側の極座標の下に書くと
右側の極座標の図が描かれるものと
その逆で、極座標に絵を描くと
その下に鏡に映る像を描く方法を知りたいのです。

アナモルフォーズは、この円筒型以外にも
円錐型、角錐型、ダイレクトタイプといろいろ
有るようですが、トライアンドエラーで
アナモルフォーズを作るのではなく、
シミュレーションできれば、非常に楽しいだろなと
思うわけです。

宜しくお願いします。

    └おそらく複素数を用いれば表現できる写像だ... 白石 和夫 2007/10/20 18:17:53  ツリーへ

Re: 山中さま 返事を書く ノートメニュー
白石 和夫 <fbdfvqwhki> 2007/10/20 18:17:53
おそらく複素数を用いれば表現できる写像だと思うので,(そうでないとしても,)
http://www.nikonet.or.jp/spring/s_rpt_2/s_rpt_2.htm
あたりが参考になると思います。

     ├射影変換であればDRAW文を用いて簡単に実行... 白石 和夫 2007/10/20 18:36:21  ツリーへ

Re: おそらく複素数を用いれば表現できる写像だ... 返事を書く ノートメニュー
白石 和夫 <fbdfvqwhki> 2007/10/20 18:36:21
射影変換であればDRAW文を用いて簡単に実行できるのですが,その枠をはみ出す写像の場合は,逆写像の利用など工夫はいろいろありますが,かなり泥臭いプログラムを書かないと実現できないと思います。
(線を描くのは比較的簡単ですが,面を描くのは面倒です。面を描くときは,逆変換が存在すれば,逆変換を利用して,画面上の各画素(ピクセル)に対応する元の点を求めて各点ごとに色を塗る手法が使えます)

     │└泥臭いプログラムになる理由をもう少し説明... 白石 和夫 2007/10/20 21:04:25  (修正1回) ツリーへ

Re: 射影変換であればDRAW文を用いて簡単に実行... 返事を書く ノートメニュー
白石 和夫 <fbdfvqwhki> 2007/10/20 21:04:25 ** この記事は1回修正されてます
泥臭いプログラムになる理由をもう少し説明すると,BASICではベクトル値を持つ関数を定義することができないので,平面から平面への写像(変換)を関数の形に書くことができません。なので,まさしく泥臭く書くか,せいぜい,変換を副プログラムにするくらいのことしかできません。
もし,その変換が複素数で定義できれば,変換を(BASICの)関数として記述できて,プログラムの記述が簡単になります。
ただし,極論すれば,平面から平面への写像はすべて複素数の写像として表せます(簡単な数式で表せるかどうかを問わなければ)。

     │ └100OPTIONARITHMETICcomplex 白石 和夫 2007/10/21 11:34:08  ツリーへ

Re: 泥臭いプログラムになる理由をもう少し説明... 返事を書く ノートメニュー
白石 和夫 <fbdfvqwhki> 2007/10/21 11:34:08
100 OPTION ARITHMETIC complex
110 DEF f(z)=IM(z)*EXP(complex(0,re(z)*PI/10))
120 DECLARE EXTERNAL SUB SRC.PenMove, SRC.PenUp, SRC.MousePoll
130 DECLARE EXTERNAL SUB DEST.PenMove, DEST.PenUp
140 ! 格子の横線を描く
150 FOR y=0 TO 10
160 FOR x=0 TO 10 STEP 0.1
170 LET z=complex(x,y)
180 CALL SRC.PenMove(z)
190 CALL DEST.PenMove(f(z))
200 NEXT x
210 CALL SRC.PenUp
220 CALL DEST.PenUp
230 NEXT y
240 ! 格子の縦線を描く
250 FOR x=0 TO 10
260 FOR y=0 TO 10 STEP 0.1
270 LET z=complex(x,y)
280 CALL SRC.PenMove(z)
290 CALL DEST.PenMove(f(z))
300 NEXT y
310 CALL SRC.PenUp
320 CALL DEST.PenUp
330 NEXT x
340 ! マウスで線を描く
350 DO
360 CALL SRC.MousePoll(z,l,r)
370 IF r<>0 THEN EXIT DO
380 IF l<>0 THEN
390 SET LINE COLOR 3
400 CALL SRC.PenMove(z)
410 SET LINE COLOR 4
420 CALL DEST.PenMove(f(z))
430 ELSE
440 CALL SRC.PenUp
450 CALL DEST.PenUp
460 END IF
470 LOOP
480 END
490
500 MODULE SRC
510 MODULE OPTION ARITHMETIC complex
520 PUBLIC SUB PenMove, PenUp, MousePoll
530 SHARE NUMERIC z0,pen
540 LET pen=0
550 EXTERNAL SUB PenMove(z)
560 SET VIEWPORT 0, 1, 0, 0.5
570 SET WINDOW -10, 10, 0, 10
580 IF pen=1 THEN
590 PLOT LINES:re(z0),im(z0); re(z),im(z)
600 ELSE
610 PLOT LINES:re(z),im(z); re(z),im(z)
620 END IF
630 LET pen=1
640 LET z0=z
650 END SUB
660 EXTERNAL SUB PenUp
670 LET pen=0
680 END SUB
690 EXTERNAL SUB MousePoll(z,l,r)
700 SET VIEWPORT 0, 1, 0, 0.5
710 SET WINDOW -10, 10, 0, 10
720 MOUSE POLL x,y,l,r
730 LET z=COMPLEX(x,y)
740 END SUB
750 END MODULE
760 MODULE DEST
770 MODULE OPTION ARITHMETIC complex
780 PUBLIC SUB PenMove, PenUp
790 SHARE NUMERIC z0,pen
800 LET pen=0
810 EXTERNAL SUB PenMove(z)
820 SET VIEWPORT 0, 1, 0.5, 1
830 SET WINDOW -10, 10, 0, 10
840 IF pen=1 THEN
850 PLOT LINES:re(z0),im(z0); re(z),im(z)
860 ELSE
870 PLOT LINES:re(z),im(z); re(z),im(z)
880 END IF
890 LET pen=1
900 LET z0=z
910 END SUB
920 EXTERNAL SUB PenUp
930 LET pen=0
940 END SUB
950 END MODULE

     │  └画面の下半分が変換元の平面,上半分が変換... 白石 和夫 2007/10/21 11:44:32  ツリーへ

Re: 100OPTIONARITHMETICcomplex 返事を書く ノートメニュー
白石 和夫 <fbdfvqwhki> 2007/10/21 11:44:32
画面の下半分が変換元の平面,上半分が変換先の平面です。
モジュール SRC (500行〜750行)が画面下半分の描画,モジュール DEST (760行以降) が画面上半分の描画を行います。
モジュール SRC とモジュールDESTの違いは,560行,700行,820行のSET ViewPortのパラメータだけです。0,1,0,0.5は画面下半分,0,1,0.5,1は画面上半分を意味します。

このプログラムは,画面下半分でマウス左ボタンを押しながら線を描くと,上半分に110行で定義された変換を行った結果を描きます。マウス右ボタンを押すと終了します。

     └!ゆがんだ絵(アナモルフォーシス)-机上に... 山中和義 2007/10/21 15:00:59  (修正1回) ツリーへ

Re: おそらく複素数を用いれば表現できる写像だ... 返事を書く ノートメニュー
山中和義 <drdlxujciw> 2007/10/21 15:00:59 ** この記事は1回修正されてます
!ゆがんだ絵(アナモルフォーシス)- 机上に絵を置き、円筒形の鏡を置いてながめる

!直交座標の平面(右下)に元の絵を描いて、極座標の平面(上)にゆがんだ絵を描く

OPTION ARITHMETIC complex

LET m=13 !格子の数 ※サブルーチン側と同じにする

FOR y=0 TO m !格子の横線を描く
CALL SRC.LINE(0,y,m,y)
CALL DEST.LINE(0,y,m,y)
NEXT y

FOR x=0 TO m !格子の縦線を描く
CALL SRC.LINE(x,0,x,m)
CALL DEST.LINE(x,0,x,m)
NEXT x


DIM xx(20),yy(20) !頂点
DATA 4,12, 2,12, 2,10, 4,10 !雲
FOR i=1 TO 4
READ xx(i),yy(i)
NEXT i
CALL SRC.AREA(4,xx,yy)
CALL DEST.AREA(4,xx,yy)

DATA 1,6, 3,4, 10,4, 11,6, 10,6, 10,7, 9,7, 9,8, 8,8, 8,10, 7,10, 7,8, 5,8, 5,7, 4,7, 4,6 !船
FOR i=1 TO 16
READ xx(i),yy(i)
NEXT i
CALL SRC.AREA(16,xx,yy)
CALL DEST.AREA(16,xx,yy)

END

      └続き(サブーチン) 山中和義 2007/10/21 15:02:14  (修正1回) ツリーへ

Re: !ゆがんだ絵(アナモルフォーシス)-机上に... 返事を書く ノートメニュー
山中和義 <drdlxujciw> 2007/10/21 15:02:14 ** この記事は1回修正されてます
続き(サブーチン)


MODULE SRC !元の図形を描く
MODULE OPTION ARITHMETIC complex
SHARE NUMERIC m
LET m=13 !格子の数 ※

EXTERNAL SUB LINE(x0,y0,x1,y1) !線分を描く ※PLOT LINES: x0,y0; x1,y1
SET VIEWPORT 0,1,0,0.5 !グラフィックス画面の下半分
SET WINDOW -m,m,0,m !直交座標
PLOT LINES: x0,y0; x1,y1
END SUB
EXTERNAL SUB AREA(N,x(),y()) !多角形を描く ※MAT PLOT AREA ,LIMIT n: x,y
SET VIEWPORT 0,1,0,0.5
SET WINDOW -m,m,0,m
MAT PLOT AREA ,LIMIT N: x,y
END SUB
END MODULE


MODULE DEST !変換された図形を描く
MODULE OPTION ARITHMETIC complex
SHARE NUMERIC m,DivN
LET m=13 !格子の数 ※
LET DivN=m*5 !分割数

EXTERNAL FUNCTION f(z) !複素変換
LET f=im(z)*EXP(complex(0,re(z)*PI/m))
END FUNCTION
EXTERNAL SUB LINE(x0,y0,x1,y1) !線分を描く ※PLOT LINES: x0,y0; x1,y1
SET VIEWPORT 0,1,0.5,1 !上半分
SET WINDOW -m,m,0,m !極座標

LET dx=(x1-x0)/DivN !増分
LET dy=(y1-y0)/DivN
FOR i=0 TO DivN !小刻みに
LET z=complex(x0+dx*i,y0+dy*i)
PLOT LINES: re(f(z)),im(f(z));
NEXT i
PLOT LINES
END SUB
EXTERNAL SUB AREA(N,x(),y()) !多角形を描く ※MAT PLOT AREA ,LIMIT n: x,y
SET VIEWPORT 0,1,0.5,1
SET WINDOW -m,m,0,m

DIM xx(0 TO 20*DivN),yy(0 TO 20*DivN) !作業用の頂点

FOR k=1 TO N-1 !各稜線を小刻みに描く
LET dx=(x(k+1)-x(k))/DivN
LET dy=(y(k+1)-y(k))/DivN
FOR i=0 TO DivN
LET z=complex(x(k)+dx*i,y(k)+dy*i)
LET xx(DivN*(k-1)+i)=re(f(z))
LET yy(DivN*(k-1)+i)=im(f(z))
NEXT i
NEXT k
LET dx=(x(1)-x(N))/DivN !終点と始点を結ぶ
LET dy=(y(1)-y(N))/DivN
FOR i=0 TO DivN
LET z=complex(x(N)+dx*i,y(N)+dy*i)
LET xx(DivN*(N-1)+i)=re(f(z))
LET yy(DivN*(N-1)+i)=im(f(z))
NEXT i

MAT PLOT AREA ,LIMIT N*DivN+1: xx,yy
END SUB
END MODULE

       └白石先生、山中さま ひでき 2007/10/21 16:23:37  ツリーへ

Re: 続き(サブーチン) 返事を書く ノートメニュー
ひでき <jweuhhncel> 2007/10/21 16:23:37
白石先生、山中さま 

ありがとうございました。

非常にわかりやすいグラフィックスで感激しております。
プログラムの中身が、まだ、理解できておりませんので
これから、勉強させていただきたいと思います。

アナモルフォーシスを通して、10進basicをさらに
活用させていただきたいと思いますので、次のことも
実際の事例で教えていただけるとありがたいです。

(1)円錐・角錐型の場合も複素数を使えばよいのでしょうか?
   参考資料「Anamorphosis(歪み絵)を作ろう」
   http://www.t3japan.gr.jp/pdf2003/onishi_e.pdf

(2)リニア・アナモルフォーシスの場合、どこから
   手をつければよいのでしょうか?
   参考資料「リニア・アナモルフォーシス(松田)」
   http://www.straycats.net/html/news229.html

お忙しい中、無理を言いますが、よろしくお願いいたします。

        ├円錐です。 白石 和夫 2007/10/21 21:18:23  ツリーへ

Re: 白石先生、山中さま 返事を書く ノートメニュー
白石 和夫 <fbdfvqwhki> 2007/10/21 21:18:23
円錐です。
逆変換を利用する例ですが,プログラム上,逆変換は紛れています。
ポイントは,極座標で表したときの偏角です。(200行)
視点は軸上の無限遠方にあると仮定しています。
視点を円錐の近くにおくときは,190行のrの計算式を変える必要があります。
120行はBASICのインストール先に合わせて変更してください。
100 LET alpha=1/2*PI ! 円錐の頂角
110 SET COLOR MODE "NATIVE"
120 GLOAD "C:\BASICw32\SAMPLE\zenkouji.jpg"
130 ASK PIXEL SIZE (1,0;0,1)a,b
140 SET bitmap SIZE a+801, 801
150 SET WINDOW -300-a,500,-400,400
160 SET POINT STYLE 1
170 FOR x=-300 TO 500
180 FOR y=-400 TO 400
190 LET r=SQR(x^2+y^2)*SIN(alpha/2)
200 IF r<>0 THEN LET t=ANGLE(x,y)/SIN(alpha/2)
210 IF ABS(t)<=PI THEN
220 CALL AskPixel(r*COS(t), r*SIN(t) , c)
230 IF c>=0 THEN
240 SET POINT COLOR c
250 PLOT POINTS:x,y
260 END IF
270 END IF
280 NEXT y
290 NEXT x
300
310 SUB AskPixel(x,y,col)
320 ASK PIXEL VALUE (x-300-a/2,y+400-b/2) col
330 END SUB
340 END

        │├座標系は変換先を基準にしています。 白石 和夫 2007/10/21 21:37:39  ツリーへ

Re: 円錐です。 返事を書く ノートメニュー
白石 和夫 <fbdfvqwhki> 2007/10/21 21:37:39
座標系は変換先を基準にしています。
元図形の座標は-a/2〜2/2,-b/2〜b/2ですが,プログラム上は変換先と共有しているため,320行で補正しています。

        │└ゴミがでるので修正 白石 和夫 2007/10/26 08:34:02  ツリーへ

Re: 円錐です。 返事を書く ノートメニュー
白石 和夫 <fbdfvqwhki> 2007/10/26 08:34:02
ゴミがでるので修正
100 LET alpha=1/2*PI ! 円錐の頂角
110 SET COLOR MODE "NATIVE"
120 GLOAD "C:\BASICw32\SAMPLE\zenkouji.jpg"
130 ASK PIXEL SIZE (1,0;0,1)a,b
140 SET bitmap SIZE a+801, 801
150 SET WINDOW -300-a,500,-400,400
160 SET POINT STYLE 1
170 FOR x=-300 TO 500
180 FOR y=-400 TO 400
190 LET r=SQR(x^2+y^2)*SIN(alpha/2)
200 IF r<>0 THEN LET t=ANGLE(x,y)/SIN(alpha/2)
210 IF ABS(t)<=PI THEN
220 CALL AskPixel(r*COS(t), r*SIN(t) , c)
230 IF c>=0 THEN
240 SET POINT COLOR c
250 PLOT POINTS:x,y
260 END IF
270 END IF
280 NEXT y
290 NEXT x
300
310 SUB AskPixel(x,y,col)
320 IF x<=a/2 AND y>=-b/2 THEN
330 ASK PIXEL VALUE (x-300-a/2,y+400-b/2) col
340 ELSE
350 LET col=-1
360 END IF
370 END SUB
380 END

        ├リニア・アナモルフォーシスですが,リンク... 白石 和夫 2007/10/22 07:29:04  ツリーへ

Re: 白石先生、山中さま 返事を書く ノートメニュー
白石 和夫 <fbdfvqwhki> 2007/10/22 07:29:04
リニア・アナモルフォーシスですが,リンク先を見る限りは,夜,街頭が作る影が歪むのと同じことのようなので,射影変換で表現できると思います。プログラムは,SAMPLEフォルダにあるTRANSFO9.BASと同型で,射影変換の行列を定めることが仕事になると思います。

        │└!平面へ射影する行列-影 山中和義 2007/10/22 17:46:32  (修正5回) ツリーへ

Re: リニア・アナモルフォーシスですが,リンク... 返事を書く ノートメニュー
山中和義 <drdlxujciw> 2007/10/22 17:46:32 ** この記事は5回修正されてます
!平面へ射影する行列 - 影

!グラフィックス画面に表示されるX軸を谷折りにする。

!DirectX D3DX
!http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/DirectX9_c/directx/graphics/reference/d3dx/functions/math/d3dxmatrixshadow.asp
!記述には、符号の誤りがある。



!画像を用意する。

SET COLOR MODE "NATIVE"

GLOAD "C:\BASICw32\SAMPLE\zenkouji.jpg" !元の画像を読み込む
ASK PIXEL SIZE (0,0; 1,1) a,b
DIM p(a,b) !図の大きさに対応する配列を用意して
ASK PIXEL ARRAY (0,1) p !各点の色情報を格納する


!十進BASICのグラフィックスを3次元で考えると、
!
!右手系 Y
!    │
!    ・─X
!   /
!  Z(画面手前)
!
!のXY平面への描画と解釈できます。
!たとえば、PLOT LINES: x0,y0; x1,y1 は、FullBASICの仕様が2次元のため、
!常にz=0として扱われます。(本当は文法上指定ができない)


!投影元の画像をXY平面に配置します。

PICTURE pict1 !XY平面に画像を描く ※1/100スケール
MAT PLOT CELLS,IN -a/200,b/100; a/200,0/100: p !X=[-a/2,a/2]、Y=[b,0]、Z=0
END PICTURE

SET bitmap SIZE 501,501 !表示領域
SET WINDOW -4,4,-5,3

CLEAR
DRAW grid

DRAW pict1 !元の絵を描く


!次に、光源を画面手前(Z軸正)に配置します。

LET Lx=0 !光源の位置 ※右手座標系
LET Ly=10
LET Lz=15
LET Lw=1 !0=平行光源、1=点光源


!光源位置Lと投影先の平面P(投影面)から変換行列Sを求めます。
!※一般式を提示したが、XZ平面なら簡潔になる。

LET Pa=0 !平面の方程式 aX+bY+cZ+d=0
LET Pb=1 !Y=0、すなわちXZ平面
LET Pc=0 !※Pa,Pb,Pcを正規化された法線ベクトル(nx,ny,nz)とする
LET Pd=0

LET d=Pa*Lx+Pb*Ly+Pc*Lz+Pd*Lw !内積P・L

DIM S(4,4) !平面へ射影する行列
LET S(1,1)=-Pa*Lx+d !※列ベクトル形式
LET S(2,1)=-Pb*Lx
LET S(3,1)=-Pc*Lx
LET S(4,1)=-Pd*Lx
LET S(1,2)=-Pa*Ly
LET S(2,2)=-Pb*Ly+d
LET S(3,2)=-Pc*Ly
LET S(4,2)=-Pd*Ly
LET S(1,3)=-Pa*Lz
LET S(2,3)=-Pb*Lz
LET S(3,3)=-Pc*Lz+d
LET S(4,3)=-Pd*Lz
LET S(1,4)=-Pa*Lw
LET S(2,4)=-Pb*Lw
LET S(3,4)=-Pc*Lw
LET S(4,4)=-Pd*Lw+d


!そうすると、影は、変換行列Sによって、画面奥(XZ平面Z軸負)にできます。
!視点位置はZ軸正上にあるので、このままだと直線しか表示しません。
!(確認は、DRAW pict1 WITH S )

!ここでは、XZ平面をXY平面へ変換して、XY平面へ結果を表示します。
!これはZ座標とY座標を入れ替えればいい訳です。

DIM XZ2XY(4,4) !XZ平面をXY平面へ
MAT READ XZ2XY !※十進BASICの描画機能を補助する
DATA 1,0,0,0
DATA 0,0,1,0 !基本行列による行の入れ替え
DATA 0,1,0,0
DATA 0,0,0,1

DRAW pict1 WITH S*XZ2XY !変換して描く

END

        │ └ありがとうございました。 ひでき 2007/10/23 23:40:42  ツリーへ

Re: !平面へ射影する行列-影 返事を書く ノートメニュー
ひでき <jweuhhncel> 2007/10/23 23:40:42
ありがとうございました。

これからの課題がいろいろと見つかりました。

平面への射影行列というものをはじめて知りました。
おもしろそうですね。これから、勉強したいと思います。
山中様に教えていただいたurlの記事は、簡潔に
書かれているのですが、わたしには、もう少し図と解説があると
ありがたい状態です。何か適当なわかりやすい
参考書があれば、教えていただけませんか。
お世話になりますが、よろしくお願いします。

        │  ├処理の流れとその説明を付加しておきます。 山中和義 2007/10/24 14:20:36  (修正2回) ツリーへ

Re: ありがとうございました。 返事を書く ノートメニュー
山中和義 <drdlxujciw> 2007/10/24 14:20:36 ** この記事は2回修正されてます
処理の流れとその説明を付加しておきます。
プログラムを更新しておきました。

参考サイトの記述に符号の誤りがあるようです。(MSDNには、よくあること)


平面投影する行列の導出
・DirectX9シェーダプログラミング  毎日コミュニケーションズ 3,800円+税 ISBN4-8399-1247-5
 294〜297ページ



●投影面がXZ平面(平面Y=0)の場合の導出

点光源(Lx,Ly,Lz)により、XY平面上の点(X,Y,0)がXZ平面上の点(Px,0,Pz)に投影されるとする。

相似三角形から(XZ平面を床としてY軸を高さとみる)

      Y
      │  ・光源(Lx,Ly,Lz)
      │ /│
      │/ │
物体(X,Y,0) ・──┤
     /│  │
    / │  │
───・──┴──┴───XZ平面
  影(Px,0,Pz)

(Px-Lx)/(X-Lx)=Ly/(Ly-Y)

ゆえに、Px=(Ly*X-Lx*Y)/(Ly-Y)

同様に、Pz=(Ly*Z-Lz*Y)/(Ly-Y)。


これを行列で表現すると

┌ Px ┐ ┌ Ly -Lx  0  0 ┐┌ X ┐
│ Py │=│ 0   0  0  0 ││ Y │
│ Pz │ │ 0 -Lz Ly  0 ││ Z │
└ Pw ┘ └ 0  -1  0 Ly ┘└ W ┘

となる。

本プログラムの行列Sは、簡略化すると、この行列になります。

        │  └図学、幾何学による作図法の参考サイト 山中和義 2007/10/25 10:07:27  ツリーへ

Re: ありがとうございました。 返事を書く ノートメニュー
山中和義 <drdlxujciw> 2007/10/25 10:07:27
図学、幾何学による作図法の参考サイト

http://www.geocities.jp/sakushiart/ana1.htm のページ下
 アナモルフォーズの作図法


http://math-info.criced.tsukuba.ac.jp/museum/MathematicalInstruments/macchine/lab_sez3.htm のページ下
 anamorfosi アナモルフォース゛(歪曲図形)への変換
  円錐を利用した鏡映によるアナモルフォース゛  cono
  円筒を利用した鏡映によるアナモルフォース゛  cilindro
  角錐を利用した鏡映によるアナモルフォース゛  piramide

        ├円柱の画像版 山中和義 2007/10/25 22:59:29  (修正1回) ツリーへ

Re: 白石先生、山中さま 返事を書く ノートメニュー
山中和義 <drdlxujciw> 2007/10/25 22:59:29 ** この記事は1回修正されてます
円柱の画像版



!画像を用意する

SET COLOR MODE "NATIVE"

GLOAD "C:\BASICw32\SAMPLE\zenkouji.jpg" !元の画像を読み込む
ASK PIXEL SIZE (0,0; 1,1) A,B
DIM p(A,B) !図の大きさに対応する配列を用意して
ASK PIXEL ARRAY (0,1) p !各点の色情報を格納する
PRINT A,B


!投影元の画像を直交座標系に配置する

PICTURE pict1 !画像を描く ※1/100スケール
MAT PLOT CELLS,IN 0/100,B/100; A/100,0/100: p !X=[0,A]、Y=[B,0]
END PICTURE

SET bitmap SIZE 501,501 !表示領域
SET WINDOW -4,4,-4,4

CLEAR
DRAW grid

DRAW pict1 WITH SHIFT(0.4,-3) !元の絵を描く


!投影先→元座標の変換で画素の疎の部分を補間する

ASK PIXEL SIZE (-4,0; 4,4) px,py !極座標系を構成する画素数を得る

SET POINT STYLE 1
FOR j=0 TO py !画素単位に
LET y=j
FOR i=0 TO px
LET x=i-px/2 !矩形に配列されているので

!極座標(床)
!   θ←
!     \  
!  ─┼─┴───r
LET r=SQR(x*x+y*y) !画素の本来の座標を得る
LET th=ANGLE(x,y)

!直交座標(円柱)
!  Y
!  │
!  │┌──┐
!  ││画像│
! 100├┼──┘ ※100は円柱を置くための余白
!  ┼┴──X
!   40
LET x0=INT(400*th/PI) !逆関数で対応する直交座標(円柱)へ
LET y0=INT(400*r/py)
!PRINT i;j,x0;y0

LET x0=x0-40
LET y0=y0-100
IF x0>=0 AND x0<A AND y0>=0 AND y0<B THEN !元の画像の範囲内なら
SET POINT COLOR p(x0+1,B-y0) !対応する画素の色を得る
PLOT POINTS: worldx(i),worldy(j+py) !塗る
END IF
NEXT i
NEXT j

END

        ├円錐と床、画像版 山中和義 2007/10/26 23:00:55  ツリーへ

Re: 白石先生、山中さま 返事を書く ノートメニュー
山中和義 <drdlxujciw> 2007/10/26 23:00:55
円錐と床、画像版


!画像を用意する

SET COLOR MODE "NATIVE"

GLOAD "C:\BASICw32\SAMPLE\zenkouji.jpg" !元の画像を読み込む
ASK PIXEL SIZE (0,0; 1,1) A,B
DIM p(A,B) !図の大きさに対応する配列を用意して
ASK PIXEL ARRAY (0,1) p !各点の色情報を格納する
PRINT A,B


!表示用の座標系を用意する

SET bitmap SIZE 501,501 !表示領域
!SET WINDOW -4,4,-4,4
SET WINDOW -5,5,-5,5
SET POINT STYLE 1

CLEAR
DRAW grid

LET alpha=PI/6 !円錐の頂角
LET R=SQR(A*A+B*B)/2 !円錐の底の半径
DRAW circle WITH SCALE(R/100) !上から見た円錐を描く ※1/100スケール

LET R0=2*R/(1-TAN(alpha/2)^2)
DRAW circle WITH SCALE(R0/100) !頂点の写像位置 ※1/100スケール


!投影元の画像を直交座標系に配置する

PICTURE pict1 !画像を描く ※1/100スケール
MAT PLOT CELLS,IN 0/100,B/100; A/100,0/100: p !X=[0,A]、Y=[B,0]
END PICTURE
DRAW pict1 WITH SHIFT(-A/200,-B/200) !元の絵を描く


!「投影先→元座標」の変換で画素の疎の部分を補間する

LET R2=pixelx(R/100)-pixelx(0) !円錐半径の画素数
LET R3=pixelx(R0/100)-pixelx(0) !円錐頂点の画素数

ASK PIXEL SIZE (-5,-5; 5,5) px,py !極座標系を構成する画素数を得る

FOR j=0 TO py !画素単位に
LET y=j-py/2
FOR i=0 TO px
LET x=i-px/2 !矩形に配列されているので

!極座標(床の画像)
!   θ←┐
!     │  
!  ─┼─┴───r
LET rr=SQR(x*x+y*y) !画素の本来の座標を得る
IF rr<>0 THEN LET th=ANGLE(x,y) ELSE LET th=0

IF rr<=R3 THEN !裏面を排除する
LET rho=R2+COS(alpha)*(R2-rr) !極座標(円錐に写る画像)へ

LET x0=INT(R*rho*COS(th)/R2)+A/2 !対応する画素へ
LET y0=INT(R*rho*SIN(th)/R2)+B/2
!PRINT i;j,x0;y0

IF x0>=0 AND x0<A AND y0>=0 AND y0<B THEN !元の画像の範囲内なら
SET POINT COLOR p(x0+1,B-y0) !対応する画素の色を得る
PLOT POINTS: worldx(i),worldy(j) !塗る
END IF
END IF
NEXT i
NEXT j

END

        └いろいろとご教示いただき、ありがとうござ... ひでき 2007/10/27 13:06:02  ツリーへ

Re: 白石先生、山中さま 返事を書く ノートメニュー
ひでき <jweuhhncel> 2007/10/27 13:06:02
いろいろとご教示いただき、ありがとうございました。

元はと言えば、ふと見た子供の中学の美術の教科書にあった
円柱状の「歪み絵」から関心を持ったものでした。

意識して回りを見渡すと、
(1)奈良の大仏を我々は斜め下から見上げているので
   ちょうど良い顔のサイズになっている。
   (正面から見ると、多分少し長細い?)
(2)道路に白線で書かれた長細い「停止」「30」という
   文字は、遠くから見ると見やすい(ちょうど良い)?
       速度の出ている車から見てちょうど良い?
(3)オペラハウスなどで見られるようなドーム状の円天井に
   書かれた壁画をわれわれは、下から平面としてみている。
   実際に書かれた壁画は、歪んでいる筈。

など、現実の生活の中で、昔も今も「歪み」がうまく
取り入れられていることに感心させられます。
学校で「総合的学習」で扱うとおもしろい題材になりそうな
気がします。
(歴史、美術、数学、技術(パレのパンタグラフ作製)、情報
のコラボレーションとして)

「十進BASIC」と「歪み絵」を通して、多くのことを
学ばせていただきました。
ありがとうございました。

今後ともよろしくお願いいたします。

         └アナモルフォーズのページを作りました。 白石 和夫 2007/11/11 11:12:12  ツリーへ

Re: いろいろとご教示いただき、ありがとうござ... 返事を書く ノートメニュー
白石 和夫 <ynwythjfwu> 2007/11/11 11:12:12
アナモルフォーズのページを作りました。
http://hp.vector.co.jp/authors/VA008683/Anamorfose.htm


インデックスへ EXIT
新規発言を反映させるにはブラウザの更新ボタンを押してください。