レス数が1スレッドの最大レス数(1000件)を超えています。残念ながら投稿することができません。
おちゃめくらぶ掲示板
-
「円を描く」アルゴリズム
プチコンで円形のフェードイン、フェードアウトプログラムを作ってみたにょ。
http://ww5.tiki.ne.jp/~ochame/petitcom/tips/routine.htm#circle_in
これを使えばロードランナーの開始時の演出も簡単に作れるようになるにょ。
原理はあえて説明するほどもないくらい簡単なものだけどGRP面の優先順位を最も高い状態に
してそれで画面全体をマスクして、円を描いていき透明色(0番)で塗りつぶしていっている
だけにょ。
唯一考えなくてはいけない部分はこの塗りつぶしの基準座標にょ。
円の大きさがどんどん大きくなっていくため同じ場所を基準にすることはできず、画面の
対角線上に4カ所塗りつぶす必要があるにょ。
対角線上というのはプチコンの画面は256x192の4:3であるためループ1回に付きX方向に4ドット
Y方向に3ドットずらせば整数で簡単に計算ができるにょ。
この場合のループ1回あたりの円の半径の増加量は5ドットとなるにょ。
とはいえ、円の中心点を基準にこれだけ分ずらすと常に円周上に塗りつぶしの基準点がある
ためうまく塗りつぶすことはできないにょ。
そのためそれより1ドット内側にしているにょ。
あとは4回に分けているのをループで1回にまとめて基準点のずれはパターン化できるため
短くまとまったにょ。
フェードアウトはその逆を行えばいいだけにょ。
円を描くというのはプチコンでは標準でGCIRCLE命令があるので非常に簡単にょ。
かつての8bitパソコンでは円を描くというのは非常に重い処理であり機種によっては円を
描いているのが目視できるレベルのものもあったにょ。
また円を描く命令がない場合は自分で実装する必要があるのだけどこれは三角関数を使えば
簡単に描けるにょ。
半径rの円における基準点(r,0)から中心点へと引いた直線となす角度がθとなる円周上に
おける点のX座標、Y座標は次のようになるにょ。
x=r sin θ
y=r cos θ
円の中心が(0,0)でないならば平行移動すればいいだけにょ。
これを指定の回数分ループすればいいにょ。
θの増分が3度単位ならば正120角形が描かれるにょ。
どこまでいけば「ほぼ円といってもいいレベル」になるかはrの大きさで変わってくるけど
rの2〜4倍くらいループすれば十分だと思われるにょ。
恐らくプチコンは正360角形であり、プチコンの画面解像度ならば十分に円といってもいい
レベルになるにょ。
上記の方法は三角関数を使うため実は非常に重いにょ。
プチコンの三角関数の演算速度は配列変数からの読み出し処理と変わらないくらいに高速で
あるためちゃんと演算している(普通ならば級数展開で一定ラインの近似値演算を求める)
とは思えず内部にテーブルを用意しているのではないかと思わせるレベルにょ。
では、三角関数がまともな速度で計算ができなかった8bitパソコンではどうやって円を描画
していたのかというと実は三角関数を使わず円を描画するアルゴリズムは多数あるので
それを利用していたと考えられるにょ。
円の描画アルゴリズムは英語版のWikipediaにも記載されているにょ。
http://en.wikipedia.org/wiki/Midpoint_circle_algorithm
ここに記載されているうちの1つをC++からプチコンに移植してみたにょ。
ACLS:R=90:A=128:B=96
X=R:Y=0:E=1-X
GOSUB @CIRCLE
END
@CIRCLE
GPSET A+X,B+Y,15
GPSET A-X,B+Y,15
GPSET A+X,B-Y,15
GPSET A-X,B-Y,15
GPSET A+Y,B+X,15
GPSET A-Y,B+X,15
GPSET A+Y,B-X,15
GPSET A-Y,B-X,15
Y=Y+1
IF E<0THEN E=E+Y*2-1ELSE X=X-1:E=E+Y*2-X*2-2
WAIT 3
IF X>=Y THEN @CIRCLE
RETURN
http://ww5.tiki.ne.jp/~ochame/petitcom/qr/circle.png (QRコード)
一瞬で描画し終わってしまうのはあまりに趣がないためレトロ風にウェイトを入れてみた
のでかつてのマシンではこんな感じで円を描画していたのかが分かるにょ。
整数演算だけで円が描画可能になっていることが分かると思うにょ。
このように4つの開始地点から8分割した円を描画している機種というのは結構多かったにょ。
塗りつぶし円は特定の境界色で円を描いてそれで塗りつぶすことが可能になるけど塗り
つぶした楕円はどうなのかというと楕円描画プログラムを書いてその中を塗りつぶすなんて
ことをしなくても問題はないにょ。
実は円や楕円の方程式を見てのように円周上のX座標が決まればY座標も決まるためそれを
線で引いて1ドットずつずらせば塗りつぶしたものになるためにょ。
これを使えば三角関数は不要にょ。
http://ww5.tiki.ne.jp/~ochame/petitcom/tips/routine.htm#circle
座標を求めるためにATANを使って角度を求めてその角度からSINとCOSを使って描画をすると
いう方法もあるけどそれだと二度手間になってしまうにょ。
ゲームにATANを使用する場面としてよく誘導弾の方向に用いられることがあるけど実は
誘導弾の向きもATANを使った場合には二度手間になってしまうにょ。
つまり、ATANは不要で四則演算で普通に方向は分かるにょ。
もっとも、プチコンの場合は三角関数の演算が超速いためATANを使った方が二度手間だけど
速度面では不利になるとは限らないけどね。(あと、「角度が○度以内なら誘導弾を発射
する」というように条件に角度が絡んでいる場合はATANで角度を出す必要がある)
twitter上でなぜかCIRCLE命令について盛り上がったので即興で冒頭のようなものを作った
のだけど私は結構TLで話題に出てきたようなものを元に便利ルーチンとして公開しているにょ。
大半が何に使うのか分からないような用途がかなり限定されているようなルーチンばかりで
私自身作ったけど使ってないようなものも多いにょ(笑)
それでも何かの役に立てばいいにょ。
良く使うルーチンは256文字以内ならばMEMリソースで保存しておけばファンクションキーに
ロードすることでプログラム中の任意の場所に挿入できるので便利にょ。
そういう時には私のPETIT EDITORなどのMEMリソース編集用テキストエディタが便利にょ。
http://ww5.tiki.ne.jp/~ochame/petitcom/2page.htm#edit
|
|
|
掲示板管理者へ連絡
無料レンタル掲示板