Large Display Size Middle Display Size Small Display Size
概要 キーワード 著者

Nintendo3DS「プチコン3」で3D計算

●実行中動画



▲動画 Nintend3DSで3D計算
動画再生できない場合は MP4ファイル ダウンロード(795KB)

プチコンでの3D計算プログラムです。


●SmileBASIC ソースコード

見やすくするためインデントを加えてあります。

最初に3つの関数定義を行い、

続いて、正六面体の頂点情報、面情報のデータ。

最初は面は気にしないで、正六面体の8つの頂点に注目して、頂点の3次元座標X, Y, Zを2次元座標H, Vにして配列に収めます。(コメントの '2D ホゾン )

次に6枚の面について、面それぞれについて、開始点から最終点までラインを引いて最後に開始点へ戻ってラインを閉じて四角形(ポリゴン)にします。

ポイント: 面ごとに頂点を取り出して、頂点を3次元から2次元座標に変換すると、面どうしで同じ頂点を参照している部分があり、同じ変換を無駄に行ってしまうので、まずは頂点だけに注目して全部変換済みにして、面からの参照はこの変換済みの頂点座標にすれば無駄がなくなります。そうするのが当たり前かもしれませんが…。

関数1 HENKAN: 中学生の数学で習うような計算です。これで3D計算を行っています。

関数2 AXIS: AXISと言うと難しそうな単語ですが、座標軸という意味で、2次元座標を調整しています。

関数3 KAITEN: 高校生の数学で習う三角関数です。角度の単位はラジアンになっています。

OPTION STRICT

'---SPEED CUSTOM

VAR KAITENRATE=0.05
VAR VSYNCVALUE=2

'---COMMON SETTING

VAR I,J,K
VAR TEN
VAR X,Y,Z,H,V
VAR FH,FV
VAR BH,BV

'FUNCTION 1
DEF HENKAN X,Y,Z,S OUT H,V
H=X*(S/Z) *17.6
V=Y*(S/Z) *17.6
END

'FUNCTION 2
DEF AXIS H,V OUT OH,OV
OH=H+200
OV=-V+120
END

'FUNCTION 3
DEF KAITEN CX,CY,X,Y,THETA2 OUT OX,OY
DEC X,CX
DEC Y,CY
VAR R=SQR(X*X+Y*Y)
VAR THETA1=ATAN(Y,X)
OX=COS(THETA1+THETA2)*R
OY=SIN(THETA1+THETA2)*R

INC OX,CX
INC OY,CY
END

DIM COLORS[8]
COLORS[0]=RGB(0,0,0)
COLORS[1]=RGB(0,0,255)
COLORS[2]=RGB(255,0,0)
COLORS[3]=RGB(255,0,255)

COLORS[4]=RGB(0,255,0)
COLORS[5]=RGB(0,255,255)
COLORS[6]=RGB(255,255,0)
COLORS[7]=RGB(255,255,255)

VAR _X=0
VAR _Y=1
VAR _Z=2

VAR _H=0
VAR _V=1

'/---COMMON SETTING


'---MODEL DATA

DIM MTENS[8,3]

MTENS[0,_X]=-1:MTENS[0,_Y]=-1:MTENS[0,_Z]=-1
MTENS[1,_X]= 1:MTENS[1,_Y]=-1:MTENS[1,_Z]=-1
MTENS[2,_X]= 1:MTENS[2,_Y]= 1:MTENS[2,_Z]=-1
MTENS[3,_X]=-1:MTENS[3,_Y]= 1:MTENS[3,_Z]=-1
MTENS[4,_X]=-1:MTENS[4,_Y]=-1:MTENS[4,_Z]= 1
MTENS[5,_X]= 1:MTENS[5,_Y]=-1:MTENS[5,_Z]= 1
MTENS[6,_X]= 1:MTENS[6,_Y]= 1:MTENS[6,_Z]= 1
MTENS[7,_X]=-1:MTENS[7,_Y]= 1:MTENS[7,_Z]= 1


DIM MMENS[6,4]

I=0

MMENS[I,0]=0:MMENS[I,1]=1
MMENS[I,2]=2:MMENS[I,3]=3
INC I

MMENS[I,0]=4:MMENS[I,1]=5
MMENS[I,2]=6:MMENS[I,3]=7
INC I

MMENS[I,0]=7:MMENS[I,1]=6
MMENS[I,2]=2:MMENS[I,3]=3
INC I

MMENS[I,0]=1:MMENS[I,1]=5
MMENS[I,2]=6:MMENS[I,3]=2
INC I

MMENS[I,0]=0:MMENS[I,1]=1
MMENS[I,2]=5:MMENS[I,3]=4
INC I

MMENS[I,0]=4:MMENS[I,1]=0
MMENS[I,2]=3:MMENS[I,3]=7
INC I


VAR MSCALE = 10

DIM MMOVE[3]
MMOVE[_X]=0
MMOVE[_Y]=0
MMOVE[_Z]=300

VAR MKAITENKAKU=0

'2D ザヒョウ カクノウ ヨウ
DIM MTENS2[8,2]

'---/MODEL DATA


'---START PROGRAM

GCLS:CLS

WHILE TRUE
RUNNING
VSYNC VSYNCVALUE
WEND

'EO PROGRAM




'---MAIN PROGRAM

DEF RUNNING

'--CALC

'カイテン ススメル
INC MKAITENKAKU,KAITENRATE


'TEN 3D TO 2D
FOR I=0 TO 7

'3D
X=MTENS[I,_X]
Y=MTENS[I,_Y]
Z=MTENS[I,_Z]

'3D カイテン
KAITEN 0,0,X,Z,MKAITENKAKU OUT X,Z
KAITEN 0,0,Z,Y,.5 OUT Z,Y

'3D ワールド ヘンカン
X=X * MSCALE + MMOVE[_X]
Y=Y * MSCALE + MMOVE[_Y]
Z=Z * MSCALE + MMOVE[_Z]

'3D -> 2D ヘンカン(トウエイ)
HENKAN X,Y,Z,50 OUT H,V

'2D ホゾン
MTENS2[I,_H]=H
MTENS2[I,_V]=V

NEXT I



'--DRAW

'ガメンショウキョ
GFILL 0,0,399,239,COLORS[0]

FOR I=0 TO 5

'カイシテン
TEN=MMENS[I,0]

FH=MTENS2[TEN,_H]
FV=MTENS2[TEN,_V]

AXIS FH,FV OUT FH,FV

BH=FH
BV=FV

'ライン
FOR J=1 TO 3
TEN=MMENS[I,J]

H=MTENS2[TEN,_H]
V=MTENS2[TEN,_V]

AXIS H,V OUT H,V

GLINE BH,BV,H,V,COLORS[4]

BH=H:BV=V
NEXT J

'トジル
GLINE BH,BV,FH,FV,COLORS[4]

NEXT I

END'RUNNING

'---/MAIN PROGRAM





ラジアンについて

角度は普通、0°~360°です。「角度はラジアン」と言うと難しそうですが、円をドルに換算する、センチメートルをインチに換算する、という種類 の事柄と同じものです。0°~ 360°は 0 ラジアン~ 2 * 3.14 ラジアンにそのまま対応しています。ちょっと難しい印象ですが、わかりやすい「度」を使わずに難しい「ラジアン」を使う理由は、そのほうが中高生より先の高度な数学の世界では計算しやすいということです。

度をラジアンに変換するには、

「360°は、2 * 3.14 ラジアン に対応している」 ならば、「1°当たりのラジアン」は、
2 * 3.14 / 360
である。
たとえば 30°をラジアンに変換するには、
( 2 * 3.14 / 360 ) * 30
で求まる。

この変換をプチコンのプログラムで書くと

VAR RAJIAN=(2*PI()/360)*KAKUDO

という感じです。3.14 はプチコンでは PI() にすれば 3.141592.. となり計算結果がより正確になります。式を簡単化すると

VAR RAJIAN=PI()/180*KAKUDO

です。

プチコンの数学の関数群も、角度を扱うものはラジアンを使っているものがほとんどですが、プチコンには度からラジアンを求める RAD() という関数が用意されています。優しいです。上の簡単化した式はプチコンではさらに、

VAR RAJIAN=RAD(KAKUDO)

とできます。

逆にラジアンを度にする


逆にラジアンを度にするには(先の式 RAJIAN=PI()/180*KAKUDO の両辺を PI()/180 で割ります)

VAR KAKUDO=RAJIAN/(PI()/180)

これも関数が用意されていて

VAR KAKUDO=DEG(RAJIAN)

とできます。

以下のプログラムはラジアンではなく度を使ってプログラムしています。数学関数に度を渡すときだけRAD()を使ってラジアンに変換しています。前のプログラムとの違いは黄色のマーカーで示してあります。

ラジアンはちょっと難しいなと思う人は参考にしてください。

OPTION STRICT

'---SPEED CUSTOM

VAR KAITENRATE=2
	
'2ド

VAR VSYNCVALUE=2

'---COMMON SETTING

VAR I,J,K
VAR TEN
VAR X,Y,Z,H,V
VAR FH,FV
VAR BH,BV

'FUNCTION 1
DEF HENKAN X,Y,Z,S OUT H,V
H=X*(S/Z) *17.6
V=Y*(S/Z) *17.6
END

'FUNCTION 2
DEF AXIS H,V OUT OH,OV
OH=H+200
OV=-V+120
END

'FUNCTION 3
DEF KAITEN CX,CY,X,Y,KAKUDO OUT OX,OY
DEC X,CX
DEC Y,CY
VAR R=SQR(X*X+Y*Y)
VAR THETA1=ATAN(Y,X)
VAR THETA2=RAD(KAKUDO)
OX=COS(THETA1+THETA2)*R
OY=SIN(THETA1+THETA2)*R

INC OX,CX
INC OY,CY
END

DIM COLORS[8]
COLORS[0]=RGB(0,0,0)
COLORS[1]=RGB(0,0,255)
COLORS[2]=RGB(255,0,0)
COLORS[3]=RGB(255,0,255)

COLORS[4]=RGB(0,255,0)
COLORS[5]=RGB(0,255,255)
COLORS[6]=RGB(255,255,0)
COLORS[7]=RGB(255,255,255)

VAR _X=0
VAR _Y=1
VAR _Z=2

VAR _H=0
VAR _V=1

'/---COMMON SETTING


'---MODEL DATA

DIM MTENS[8,3]

MTENS[0,_X]=-1:MTENS[0,_Y]=-1:MTENS[0,_Z]=-1
MTENS[1,_X]= 1:MTENS[1,_Y]=-1:MTENS[1,_Z]=-1
MTENS[2,_X]= 1:MTENS[2,_Y]= 1:MTENS[2,_Z]=-1
MTENS[3,_X]=-1:MTENS[3,_Y]= 1:MTENS[3,_Z]=-1
MTENS[4,_X]=-1:MTENS[4,_Y]=-1:MTENS[4,_Z]= 1
MTENS[5,_X]= 1:MTENS[5,_Y]=-1:MTENS[5,_Z]= 1
MTENS[6,_X]= 1:MTENS[6,_Y]= 1:MTENS[6,_Z]= 1
MTENS[7,_X]=-1:MTENS[7,_Y]= 1:MTENS[7,_Z]= 1


DIM MMENS[6,4]

I=0

MMENS[I,0]=0:MMENS[I,1]=1
MMENS[I,2]=2:MMENS[I,3]=3
INC I

MMENS[I,0]=4:MMENS[I,1]=5
MMENS[I,2]=6:MMENS[I,3]=7
INC I

MMENS[I,0]=7:MMENS[I,1]=6
MMENS[I,2]=2:MMENS[I,3]=3
INC I

MMENS[I,0]=1:MMENS[I,1]=5
MMENS[I,2]=6:MMENS[I,3]=2
INC I

MMENS[I,0]=0:MMENS[I,1]=1
MMENS[I,2]=5:MMENS[I,3]=4
INC I

MMENS[I,0]=4:MMENS[I,1]=0
MMENS[I,2]=3:MMENS[I,3]=7
INC I


VAR MSCALE = 10

DIM MMOVE[3]
MMOVE[_X]=0
MMOVE[_Y]=0
MMOVE[_Z]=300

VAR MKAITENKAKU=0
	
'0ド


'2D ザヒョウ カクノウ ヨウ
DIM MTENS2[8,2]

'---/MODEL DATA


'---START PROGRAM

GCLS:CLS

WHILE TRUE
RUNNING
VSYNC VSYNCVALUE
WEND

'EO PROGRAM




'---MAIN PROGRAM

DEF RUNNING

'--CALC

'カイテン ススメル
INC MKAITENKAKU,KAITENRATE


'TEN 3D TO 2D
FOR I=0 TO 7

'3D
X=MTENS[I,_X]
Y=MTENS[I,_Y]
Z=MTENS[I,_Z]

'3D カイテン
KAITEN 0,0,X,Z,MKAITENKAKU OUT X,Z
KAITEN 0,0,Z,Y,13 OUT Z,Y
	
'13ド


'3D ワールド ヘンカン
X=X * MSCALE + MMOVE[_X]
Y=Y * MSCALE + MMOVE[_Y]
Z=Z * MSCALE + MMOVE[_Z]

'3D -> 2D ヘンカン(トウエイ)
HENKAN X,Y,Z,50 OUT H,V

'2D ホゾン
MTENS2[I,_H]=H
MTENS2[I,_V]=V

NEXT I



'--DRAW

'ガメンショウキョ
GFILL 0,0,399,239,COLORS[0]

FOR I=0 TO 5

'カイシテン
TEN=MMENS[I,0]

FH=MTENS2[TEN,_H]
FV=MTENS2[TEN,_V]

AXIS FH,FV OUT FH,FV

BH=FH
BV=FV

'ライン
FOR J=1 TO 3
TEN=MMENS[I,J]

H=MTENS2[TEN,_H]
V=MTENS2[TEN,_V]

AXIS H,V OUT H,V

GLINE BH,BV,H,V,COLORS[4]

BH=H:BV=V
NEXT J

'トジル
GLINE BH,BV,FH,FV,COLORS[4]

NEXT I

END'RUNNING

'---/MAIN PROGRAM

その他

プチコン ←→ パソコン

ちなみに、これらソースコードはプチコンのプログラムで誰かがプログラムをQRコードにして表示するものを作成してくれたので、それを利用しました。

新しいウィンドウで開く: http://wiki.hosiken.jp/petc3gou/?Toukou/プログラムをQRコードに変換

このプログラムを使ってプチコンでQRコードを表示 →

スマートホンのバーコードリーダーで読み取り →

読み取り内容をBluetoothでPCへ送信

で、このホームページに掲載しました。

逆にこのソースコードをプチコンへ送る方法ですが、それも誰かが、PCのスピーカーからNintendo3DSのマイクへ向かってXMODEMというプロトコルか何かで送信するプログラムを作ってくれています。

プログラミングと夜更かし

私は朝から晩まで、その後、晩から朝までプログラミングに没頭することが多いです。

こうやってプログラミングのノウハウを公開したりして、どなたかがこのノウハウを見て自分でもやってみようと思い、同じように夜更かしをして、人生を棒に振ってしまうということはないかなと心配したりします。

私は夜更かしについてどうしているかというと、金曜の夜から日曜の夕方くらいまでは夜更かしを(よくないとは思いながらも)自由にしています。そして日曜の夜から平日をはさみ、木曜の夜までは、ちょっときつく聞こえるとは思いますが、自分の場合はプログラミングを基本的に禁止しています。

プログラミングを始めると、ノリというものがあり、ノリが続く間はやめることはできません。「切りが悪いのでやめられない」とも言います。昔社員としてプログラマーをやっていたときに同僚の人が「私も切りが悪いときはやめられず夜更かししてしまう」と言っていました。同じように思っている人はいるんですね。

私のように平日にプログラミングを始めると深夜2時、3時になってしまい、翌日の仕事にさしつかえる、という場合は、禁止にしたほうがちょうどいいんです。禁止にすると下記のようにいろいろな平和を感じます。

  • 仕事から部屋に帰ると、「プログラムは禁止だから、どうしよう…掃除でもしよう」
  • 楽しいけど、ぼっとうしすぎで苦痛でもあるプログラミングをしなくてもいい…平和だ…映画でも見よう。
  • 仕事は技術屋の側面があり、仕事の勉強をしなきゃならない。平日夜は勉強の時間を確保できてる。趣味は週末にできるし、バランスが良いな。

小中学、高校生、大学生など学生については、私は学生の頃を振り返ると、「もっとしっかりやればよかった」と後悔する一方で、学生の頃は、遊びあり、悩みあり、でいろいろ複雑。子供なのに大人よりも複雑な中にいる。しっかり学校に行きたいとは思うけど、悩みが足を引っ張る。遊びが近くにあるので遊んでしまう。勉強したい気持ちはあってちょっと勉強するけど、どうも軌道に乗らないようだ。と学生の頃はうまくいかなくて無理もなかった、と理解する部分もある。

自分に子供がいたとして、その子供が夜更かしをしてプログラミングをしていて、翌日の学校が元気に登校できずうまくいかない、としたら、私はどうするかな。子は親を見て育つと言うし、実際そうだと思うので、みずから平日のプログラミングはやめて夜23時には消灯するかな。

プログラミングを夜更かしせずに早く終わらせる。そのための手段として2つあります。完璧ではありませんが効果はありますよ。

save.txt

今やっているプログラムを中断しなきゃ、というとき、save.txtに今考えていることを必要なことだけ書き出す。

たとえば会社で仕事を中断するとき、明日の自分のために「次はこれをやる」という内容のポストイット(メモ)を仕事場に貼っておきます。朝仕事場に行くとそのメモを見れば仕事の開始が早いです。

save.txtに日付を記入し、今現在プログラムはどんな状況か、次はどうするのか、といったことを書けば、一応中断できます。

DS内部にメモを取るのは難しいしスマートホンもメモを書くには楽じゃないので、パソコンがベストです。

(DSで集中的にプログラミングする場合、メモとかどんなふうに管理すればいいかなと思いますが、私も子供のころはプログラムのメモは作っていなかったので子供にとっては必要ないかもしれません。大人だったらパソコンで管理しつつDSでプログラム…かな?)

自主ライブラリ、自主ヘルプの作成

プログラムに時間がかかるのは、同じプログラムを作っていることも原因の一つです。同じプログラムは開拓が進むに応じて、どんどん蓄積していくのが理想です。また、こんなエラーが出たらどうする、というヘルプを自主的に作っておきます。そうすると目的までの時間が短縮されます。


それでも夜更かししたいものですが、少なくとも平日は夜更かししないほうが良いです。え~っという声が聞こえてきそうですが…。夕方に1、2時間くらいは…というのも、私の場合ですが駄目でした。一度始めると没頭するので一切やらないのがベストだと、最近(40歳)になってわかってきました。

仕事の勉強、学校の勉強も、腰を上げて始めてみればなかなか面白いものです。趣味のおもしろさにはかないませんが、面白さはあります。(大人になるといろいろわかるので勉強に面白さが入ってくる。学生にとってはそれがないので退屈になりがち。興味のないことを無理に続けると嫌いになります。難問ですね。興味のあるところを探してそこから入る、基礎がためをする、いろいろありますが、そこから「わかった!」という楽しさにつながる…かなあ?) そのへんの事実も知っておけば、平日にしぶしぶ勉強を始めて、なるほどねと思うかも。

ついでに

ついでに、なぜ3DCGのプログラムをNintedo3DSのプチコンで作成して、今回アップロードしたのかというと、自分の力試しです。

最近私は3D計算についてちょこちょこ勉強しています。しかし仕事は電子回路とか電気機器の製造とかの仕事をしていて、ちょっと畑違いです。

私にとって3D計算というのは今のところ、仕事のスキルの1つと捉えていて、今まで本業の仕事の勉強(電気)をおざなりにしてまで3Dの計算を勉強してきたけど、それでちゃんと身についているのかなと思ったわけです。時間を費やしたのに、あまりできません、だともったいないので…。

勉強したとはいえ、この3D計算は中学生の数学でできるもので難しいものではありません。回転は三角関数で高校数学ですが、すごく難しいわけではありません。

行列を使ったりベクトルを使ったりする方法もありますが、それは勉強した全体の1割くらいの時間だけで、内容も難しいし、身についていません。

ページ制作 homepage6047


ページの上端へ (もくじ開く)