中級編 〜 命令を作る

基本的な命令以外の複雑な曲線や図形を描く場合は、自分でそのような命令(関数)を作るか、誰かが作ったライブラリを利用するしかありません。中級編では、具体的な題材を扱いながら命令を作っていきます。

関数の定義

関数[*1]の定義は、次のようにします。

# 関数を定義
●自作関数(引数A,引数B,引数C)
 引数A+引数B+引数Cを戻す

呼び出すには、このようにします。

# 作った関数を呼び出す
自作関数(2,3,4)を言う

日本語的な命令の定義の仕方

先程の例では、関数名()で命令を呼び出しましたが、他の命令と同じように「AをBでC。」のように日本語的に呼び出したいですね。「引数+助詞+…+命令」の形で命令を呼び出せるようにするには、宣言文に助詞をつけるだけです:

●平行移動(X,YをA,Bだけ)
 「{X+A},{Y+B}」を戻す

引数の型を指定する

引数の型を明示することもできます。

●平行移動({数値}X,{数値}Yを{数値}A,{数値}Bだけ)
 「{X+A},{Y+B}」を戻す

しかし、「平行移動」という変換命令としては少々不便です。XやYの値を直接書き換えられないからです:

X=100
Y=200
X,Yを300,400だけ平行移動
それを言う。        # 400,600 ... 平行移動している
「{X},{Y}」と言う。 # 100,200 ... 元の値のまんま

例えば、「AにBを直接足す」命令は、 A に変数を渡すとその変数の内容を直接 B だけ増やします。ただの「足す」命令では逆に、渡した変数の内容を直接書き換えたりはしません。

引数として渡した変数に破壊的な処理[*2]をしたい場合は、変数型として参照渡し型を指定します。C言語で言う所のポインタのようなものです。

●平行移動({参照渡し}X,{参照渡し}Yを{数値}A,{数値}Bだけ)
 XにAを直接足す。# X=X+A
 YにBを直接足す。# Y=Y+B

変数を書き換える命令は、命令の説明文を読むときちんと「変数の内容書き換える」と書いてあります。逆に、説明にそのように書いていない命令は全て普通の「値渡し」、つまり変数の内容を書き換えないタイプです。

では実際に回転命令を作ってみます。回転の詳しいアルゴリズムはここでは割愛しますが、点(x,y)を原点中心にθ[rad]回転した点(X,Y)を計算するには次の式を用います:

X=xcosθ-ysinθ, Y=xsinθ+ycosθ

# 「X,YをPI/6だけ回転」のように使う
●回転({参照渡し}X,{参照渡し}Yをθだけ)
 xとは数値=X
 yとは数値=Y
 cosとは数値=COS(θ)
 sinとは数値=SIN(θ)
 X = x*cos - y*sin
 Y = x*sin + y*cos

変数X,Yの値を直接書き換えます(そのため、きちんと計算できるよう元々の変数X,Yの値を退避用の変数x,yにコピーして計算に用いていることに注意してください)。

また、θには弧度法単位[rad]で角度を指定する必要があります。度数法で角度を指定したい場合は次のように工夫してみましょう:

# 「X,Yを30度回転」のように使う
●度回転({参照渡し}X,{参照渡し}Yをθだけ)
 X,YをDEG2RAD(θ)だけ回転

注釈

*1
公式マニュアルによると、正式には関数ではなくユーザ定義命令と呼びます。しかし、長ったらしくて面倒なのと、他の言語や掲示板での慣習などから、(作者も含めて)皆関数と呼んでいます。
*2
破壊的な処理とは、変数の内容を直接書き換えるような処理のことです。どの命令がどの引数に対して破壊的なのか把握するのはとても重要です(書き換えるつもりがなかったのに破壊的な処理で変数の中身が変わってしまったり、書き換えたつもりで非破壊的だったために中身が変わっていなかったりすると、意図とは全く違うプログラムになってしまう!)。破壊的な命令は主に、配列・表に対する命令に多数存在します。命令の説明をよく読んで注意するようにしましょう。