8.図形の描き方 <平面図形の場合> (中級編 その1)
初級編に続いて,平面図形を描くためのやや高度な機能をご紹介します。
- 数値式の記述方法
図形を描くときには,点の座標を与えたり,曲線の方程式を指定したりするための数値式が必要になってきます。
PICTURE にまだなれていない人がよく間違えるのは,文章中に数式を表示するための数式記述と,数値を計算するための数値式とを混同することです。後者が今から説明するものですが,BASIC言語の数式表現とほぼ同じです。
- 整数,小数はそのまま書きます。 (例) 2, 3.25
なお,たとえば 0.23 を .23 のように書くことも許されています。
- 演算子は次の5種類です。 "+", "-", "*", "/", "^" (最後の "^" はべき乗)。演算子同士の優先順位は,通常の規則に従います。
(例) 3.1 + 2.56^3 / 4 * 1.3 - 8 (演算子の前後などに半角空白を入れてもかまいません)
- カッコ。丸カッコ "(", ")" 以外は使えません。ただし,何重の入れ子状態になっても結構です。
(例) 3.1 + 2.56 ^ (3 / (4 + 2.5))
- 関数。以下の関数が使えます。
abs(…) 絶対値
exp(…) eのべき乗
log(…) 自然対数
log10(…) 常用対数
sqr(…) , sqrt(…) 平方根(どちらも同じ)
sin(…) サイン,cos(…) コサイン, tan(…) タンジェント, cot(…) コタンジェント
sinh(…) ハイパボリックサイン, cosh(…) ハイパボリックコサイン, tanh(…) ハイパボリックタンジェント
asin(…) アークサイン (-pi/2 〜 pi/2 の値を返す)
acos(…) アークコサイン (0 〜 pi の値を返す)
atan(…) アークタンジェント (-pi/2 〜 pi/2 の値を返す)
arg(x;y) 複素数x+yiの偏角 (-pi 〜 pi) (コンマではなく,セミコロンで区切る)
int(…) 整数部分 (それを超えない最大の整数)
min(…;…) 小さい方の値 (コンマではなく,セミコロンで区切る)
max(…;…) 大きい方の値 (コンマではなく,セミコロンで区切る)
- 定数。特殊な定数として,
pi 円周率のπです。(例) sin(2/3*pi)
自然対数の底 e は,exp(1) によって与えられます。
- (注意) 次のような間違いがよくありますから,ご注意ください。
- 掛け算で "*" を落とす。 (誤) 2pi, 3sin(…) → (正) 2*pi, 3*sin(…)
- 三角関数のべき乗。 (誤) tan^2(pi/5) → (正) (tan(pi/5))^2
- なお,これらの数値式は,図形を描くための \picture 中に限らず,本文中においても,たとえば
- \parskip{\lineskip * 1.5}
のように,数値を表現する箇所ならどこででも使うことができます。
- 数値を文字に代入して使う
複雑な数値式で計算される数値などは,それを文字に代入してから使うと,便利なことが多いです。同じ数値を何度も使うときには特に便利ですし,原稿を読みやすくする意味でも有効です。
この目的のために,\constant コマンドと,ローカル/パブリック変数があります。後者は,主にユーザー定義の描画関数マクロの中で使われます(もちろん,\picture コマンドの中でも自由に使えます)。
- \constant コマンド
PICTURE には,a0 から a99 までの合計100個の文字定数が用意されています。これらに値を代入するコマンドが \constant です。このコマンドは,本体の描画コマンド群を記述するよりも手前に記述しなければなりません(\basicset コマンドの直前または直後です)。また,\constant コマンドは,1個の \picture コマンド中で1回しか使えません(これは何ら手足を縛る制約とはなりません)。うまく使うと,ものすごく便利です。
- コマンドの形式は,
- \constant{a0=…, a1=…, a2=…, …}
- です。文字定数は,必ずしも番号順に代入しないといけないわけではありません。また,すべてを使わないといけないわけでもありません。代入しなければ,初期値はすべて0
です。
また,たとえば,
- \constant{a0=pi/5, a1=a0*2, a2=a0*3}
- のように,代入するための数値式中に,別の文字定数を使うこともできます。
当然ながら,\constant コマンドで代入した文字定数は,本体部の描画コマンド中で自由に使えます。たとえば
- \polygon{a0*3, a1/2, a2+a3, a4, a5, a6, a7, a8, a10, a11}
\text{0, a5, a8, 4, $2a$}
- のような使い方です。
- 文字定数の使い道いろいろ
- 1個の数式では表現困難な複雑な数値を表現する
計算の途中結果を次々に文字定数に代入しつつ,最終結果を得るような使い方があります。たとえば,A(a1, a2), B(a3, a4), C(a5,
a6) としたとき,∠ABCの二等分線上で,Bからの距離が a7 である点の座標を知りたいとします。これを1つの数式で表現するのはあまりに複雑です。計算の途中結果を次々と文字定数に代入しながら,最終結果を得るというのが,わかりやすい計算になると思います。(具体的な計算は省略します)
- 同じ数値を何度も使う
- たとえば三角形を描くとして,その3頂点の座標を前もって文字定数に代入して A(a1, a2), B(a3, a4), C(a5, a6) としておけば,
- \picture
{
……
\polygon{a1, a2, a3, a4, a5, a6} //三角形を描く
\pen{2} //点線を指定
\specialarc{d, a1, a2, a3, a4, .3} //AB間に点線で弧を描く
\text{0, a1, a2, 8, A} //頂点Aに「A」という文字を入れる
……
}
のように,その座標を簡単に何度でも使うことができます。
- 図形の拡大・縮小に使う
(\basexy, \basexyzコマンドを使えば,ここに記すような使い方は不要です。)
\basicset コマンドの最後の引数で,座標単位の実長を指定できます。ですから,これを変えることで,図形全体の拡大,縮小が可能になります(試行錯誤をしながら,文書中に納めるのに最も適した大きさを選択できます)。しかしこれだけだと,描かれる図は拡大・縮小されても,描画領域全体の大きさはそのままです。これではあまり有り難味がありません。
- 文字定数をうまく使うと,座標単位の実長に合わせて描画領域の大きさも変化させることができます。たとえば,
- \picture
{
\basicset{6*a0, 4*a0, 1.5*a0, 2*a0, a0}
\constant{a0=1.2}
……… //引き続く本体の描画コマンド群
}
- とします。こうしておくと,a0=1.2 の部分を調整するだけで,座標単位の実長と,それに応じた描画領域の大きさの両方を変えることができます。便利な使い方です。
なお,上の例でお分かりのように,\basicset と \constant とは,どちらを先に記述しても,\constant で設定した文字定数を \basicset 中で使うことができます。
- ローカル/パブリック変数
a0 〜 a99 の文字定数は,\constant コマンドの中でのみ代入・変更が可能です。それ以降の描画コマンド群の中では,代入や変更はできません。途中での代入・変更が必要なときには,ローカル変数を使うのが普通です。
ローカル変数は,\vala 〜 \valz, \valA 〜 \valZ の合計52個あります。「ローカル」とは,現在の \picture コマンドの中だけで有効という意味です。たとえばそれを \picture コマンドの外側の本文中で使ったり,次の \picture コマンドに引き継ぐようなことはできません。もしそういう必要があるのなら,パブリック変数を使います。
パブリック変数は,\pvalA 〜 \pvalZ の合計26個あります。これはPICTURE文書全体に対して有効な共通の変数となります。
- 変数への値の代入・変更は,\vala{数値式} の形式をとります。
- (例) \vald{2*sin(a1+a2)-\pvalC} (注) \vald = 数値式 という表現は不可です。
変数の値を使うときは,上の例にもあるように,"{ }" をつけないで単に \vala のように記述します。
変数の特殊な使い道をいくつか紹介します。
- 描画コマンドの戻り値として使う。描画コマンドによっては,戻り値をもつものがあります。たとえば,楕円外の点から楕円に接線を引く \ellipsetangent というコマンドがあります。これは,接線を引くとともに,2接点の座標をパブリック変数を用いて返します。(\pvalU, \pvalV), (\pvalX, \pvalY) が2つの接点です。ですから,\ellipsetangent コマンドを用いたあと,その接点の座標を別の目的で使うことができます。
- 繰り返し処理で使う。類似の処理を何度も繰り返すときのために,\while コマンドがあります。
- たとえば,ある処理を10回繰り返したければ,
- \valn{0}
\while{\valn<10}
{
…… //繰り返すコマンド群
\valn{\valn+1} //これがないと無限ループに入ってしまいます。
}
とします。
|