REALbasicが採用したオブジェクト指向のプログラムの面白さを一番よく表している、新しいクラスを取り上げてみました。C言語を使っての「Plug-in」の作成を楽しまれている方々の作品も、出回り始めて、ますます面白くなりそうですね。
第20回 - クリスマスツリーを作って下さい -
お星様のマークを基本型にして、変型できる、NewCanvasClassを作りました。クリスマス用のプログラムの飾り付けにでも使ってみて下さい。
今回は、プログラムの中身よりも、このNewCanvasClassを利用したプログラムを考えてほしいと思います。何か私には考え付かない使い道がありそうです。面白いものが出来ましたら、ぜひ、知らせて下さい。
今回の、はじまりは、図形内部の一部をマウスで引っ張り、その部分を中心にして図形を変型させてみようと考えたことでした。
このため、図形を小さな碁盤の目に刻んで、それぞれの四角形ごとの変型ルーチンが必要となりました。
結局、これは三角形の変換が基本になっていることに気付きまして、三角形内部の点が1つの頂点をマウスで移動させたときに、どのように移動するかを、計算し、変換ルーチンを作りました。
数式そのものは、単純で、プログラムも、数式通りに走りましたが、ここで問題が起りました。三角形の面積が小さくなる場合は問題ないのですが、面積が大きくなるようにマウスを動かすと、図形に隙間が表れます。考えてみると当たり前のことです。
これを回避するためには、空白の点を周りの点の色で補完することが必要になります。何か簡単な手はないかと考えましたが、ここでつまずいてしまいました。どうも発想を変えないとダメなようで、しばらく棚上げすることに決定。
でも、このままほったらかしておくと、ゴミになってしまいそうなので、三角形の、変型ルーチンだけでもまとめておこうと考えました。そこで、NewCanvasClass にして、1つの形として残しておくことにしました。
すでにあるクラスを利用しての、新しいクラスの作り方の基本は、「覚え書き」にありますので、参考にして下さい。
今回は、Canvasクラスを利用しました。新しいクラスの開発過程は、
- 通常のCanvasに、マウスにより線を描いたり、塗りつぶしたりするプログラムを、いつものようにコーディングします。
- 動作を確認した後、File メニューから「New Class」を選択して、PropertiesウインドウのSuperの欄からベースとするクラス(ここではCanvas)を選択します。
- この新しいクラスのウィンドウで、各イベントに、通常のCanvasのプログラムコードを、コピー&ペーストで書き写します。このとき、Window1にある、MethodやProperties内のコードも、新しいクラスのMethodやPropertiesに再定義して、書き写します。
- このようにして、とにかく、すべてのコードを、新しい、Canvasクラスの中に収めてしまいます。
- プログラムを走らせて、通常のCanvasと同じ動作をすることを確認する。
- Projectウィンドウから、新しいクラスのアイコンを、ディスクトップにドラッグします。これで、ディスクトップに、小さいアイコンのついたファイルが出来ます。
これで、いつでも、利用できる新しいクラスができました。さらに、開発を続けるためには。
- 新しいプロジェクトファイルを開きます。
- さきほど作ったNewClassの小さなアイコンをプロジェクトウインドウにドラッグします。
- Canvasアイコンをツールボックスからメインウインドにドラッグします。
- ドラッグしたCanvasのPropertiesウインドウのSuperの欄でNewClassの名前を選択します。
- このNewClassの内部変数や初期値などは、「NewClass名」.「変数名」の形で変更できます。(「NewClass名」はデフォルトでCanvas1になっているはずです。)もちろん、新しいクラスのBackDropに任意のPICTを張り付けることもできます。
- 動作確認を行いながら、NewClassの細かい変更などを行います。完成したクラスは、またディスクトップにドラッグして保存しておきます。
以上のようなステップで、新しいクラスを作ることが出来ます。
今回は、サンプルそのものより、NewClassの作り方、使い方がメインテーマですが、サンプルプログラムの説明を少しします。
サンプルプログラム「triangletest05」(使用したNewClassの名前「SClassTriangleE」)について。
プログラムでは、複数の点で囲まれた部分を塗りつぶす「FillPolygon」のGraphicsの命令の使い方と各サブルーチンの使い方などが、参考になると思います。
「三角形の内部か外部かを判別する方法」
いくつかの方法が考えられるますが、ベクトルで考えるのがスッキリしそうです。
3点P1,P2,P3と点P0、それぞれの点の位置ベクトルを、P1,P2,P3,P0 さらに n,m を実数としたとき、次の関係式「P0-P1 = n(P3-P1) + m(P2-P1)」で、「(m+n)<1 、 n>0 、 m>0 」の条件があるとき、点P0 は3点 P1,P2,P3 の内部にあります。
従って、
x0 -x1 = n ( x3 - x1 ) + m ( x2 - x1)
y0 -y1 = n ( y3 - y1 ) + m ( y2 - y1)
この2式より、n とm を計算して、判別条件に持ち込むことになります。
今回は、判別する点(x0,y0)と3点(x1,y1) (x2,y2) (x3,y3)を引数とし、返り値を「true」または「false」で戻すサブルーチンを定義しました。
EditメニューからNewMethodを選び、
Method Name:に「inside」
Parameters:に「x0 as double,y0 as double,x1 as double,y1 as double,x2 as double,y2 as double,x3 as double,y3 as double」
Return Type:に「Boolean」
とします。
このMethodに書き込むコードは以下のようになります。
//点(x0,y0)が3点(x1,y1) (x2,y2) (x3,y3)の作る
//三角形の内部にあるかどうかの判定。
dim m,n,mu,ml,nu,nl as double
mu=((x0-x1)*(y3-y1)-(x3-x1)*(y0-y1))
ml=((x2-x1)*(y3-y1)-(x3-x1)*(y2-y1))
m=mu/ml
nu=((x0-x1)*(y2-y1)-(x2-x1)*(y0-y1))
nl=((x3-x1)*(y2-y1)-(x2-x1)*(y3-y1))
n=nu/nl
if (m+n)<1 and n>0 and m>0 then
return true
end if
このサブルーチンの使い方は、
inoroutをboolean型の変数として
「inorout=inside(5,5,1,1,10,3,6,10)」のようにして使います。
サンプルの中では、以下のように使っています。
SClassTriangleE:Events:MouseDown
//------------ 一部分です -------------
//三角形の内部にある点かどうかの判別
//サブルーチン。返り値をbooleanにしている。
if inside (x,y,x(0),y(0),x(1),y(1),x(2),y(2) )then
//後は、このフラッグ「pf(3)」で判別する。
pf(3)=1
else
pf(3)=0
end if
//-----------------------------------
この新しいクラス「SClassTriangleE」を通常のプログラムで使用し(このときの名前を「canvas1」)、内部の変数を変更する場合、例えば、三角形の内部の塗りつぶし色「cfill」は
Window1のEventsのOpenや、PushbuttonのActionなどに
canvas1.cfill=rgb(100,20,100)
のように使います。
サンプルプログラム「Xmas1.0」(使用したNewClassの名前「SClassStarE」)について。
ここで使用したNewClass(名前は「SClassStarE」)は、先の三角形を改造し、頂点の数を3個から10個に増やしたものです。配列を増やせばよいだけなので変更は簡単に出来そうでしたが、また、壁に当たりました。
多角形塗りつぶしのサブルーチンが言うことを聞きません。相当に悩みましたが原因は、サブルーチンの引数の数が20を超えると受け付けてくれないようです。配列で引数を定義できれば、スッキリしますが、サポートされていません。原因が分れば、回避するのもまた楽しみです。
先の三角形のNewClassでは、Canvas内での図形の移動を可能にしていましたが、この、星形のNewClassは、20個ぐらいの数を1つのプログラムで使うことをイメージして作りました。。従って、星のCanvas内での図形の移動はできないほうが、使いやすいと考えました。移動を可能にしたい場合は、三角形のNewClassを参考にして下さい。
Canvas枠の右下の点をつかんでの拡大縮小も、三角形のNewClassと同様に出来ます。
さらに、これ「SClassStarE」を使っての、サンプルプログラム「Xmas1.01」では、移動、変型を行った後の、各点の情報を、メニューからファイルに保存できるようにして、いつでもファイルから読み取るようにしました。
それでは、お楽しみください。
今回の「triangletest05」と「Xmas1.01」の ソースプログラムです。
プロジェクトファイルのみです。REALbasicの最新バージョンが必要です。30 kバイト
ソースコードについての質問やご意見がありましたら以下のアドレスまでご連絡下さい。
koko-@mx2.tiki.ne.jp