MePoTeXによる図形グラフの作成

in [TeXの部屋]

MePoTeXを利用した図形やグラフの作成手順を取りまとめました。

MePoTeXを活用して,図形とグラフを究めよう!

  • MathJaxを使用しているので、 スマホでは表示に時間がかかることがあります。
  • モバイル利用(Android)でのメニュー選択は、 SiteMapを利用するか、 または「長押し」から「新しいタブを開く」を選択してください。
■MePoTeXによる図形やグラフの作成法  [Map]


[御案内] TeXを利用して数学プリントを作成するとき, いろいろな図形やグラフを作成する必要があります. それを作成するアプリはTeXのシステムにすでに含まれています. 「MetaPost」です.さらに,それをTeXソースの中で利用できるようにした パッケージが「MePoTeX」(概要)です.詳細なマニュアルもあるのですが, TeXを使い慣れていない場合は全体像を把握しにくいかもしれません.
 そこで,ここでは,TeXを使い始めた方を念頭に, MePoTeXを用いた図形やグラフの作成方法について解説します. ただし,TeXのインストールはすでになされており, TeXによる通常文書は作成できるレベルにあることを前提とします. emathと類似したコマンドで 曲面の描画まで行うことができ、 図形をGhostscriptを経由しないEPSファイル(MPS)で保存することができます。

  • 「emath」+「MePoTeX」があれば、 数学教材の作成には十分ではないかとさえ思えます。
  • 下記解説の詳細は、 MePoTeXやMetaPostのマニュアルを 参照してください。
  • MePoTeXの作者「みなも」氏には、 多大の敬意を表します。ver1.00は2000年に発表され、 最新版は2022年1月のver4.50です。 MePoTeXが広く利用されるようになることを祈念します。


■基本的な平面図形

(注) Web上での表示の都合上、 空白は全角を使用しています。 以下のコードをコピーして実行するときは、 半角の空白かtabで置き換えて実行してください。


線分
(参照) \mptPoint\mptLabelxdraw

連立1次方程式
線分は2点を定義してxdrawで結ぶだけですが、 MetaPostには連立1次方程式を解く機能があります。 その機能を利用すると、点を複素数形式で定義して、 幾つかの点の間に成り立つ関係式を指定すれば、 式を満たす点を自分で具体的に求めなくても利用することができます。

  • \begin{MPpic}<1cm>(4,2|2) % 方程式の解から直線描画 \sendMP{  z.O=origin;  z.A=5w*dir(-30);  z.B=4w*dir(40);  2*z.O+z.A=2*z.C+z.B=3*z.D;  z.B+2*z.F=z.O+2*z.A=3*z.E;  xdraw(1pt) z.O--z.A;  xdraw(1pt) z.B--z.C;  xdraw(1pt) z.B--z.F; } % 点のラベル \mptLabel{z.O}[r]{O} \mptLabel{z.A}[tl]{A} \mptLabel{z.B}[b]{B} \mptLabel{z.C}[tr]{C} \mptLabel{z.D}[bl]   <1.5mm,0mm>{D} \mptLabel{z.E}[bl]   <1mm,0mm>{E} \mptLabel{z.F}[t]{F} \end{MPpic}
ここでは、点に「z」をつけて定義しています。 ベクトルの計算や複素数の計算を含むときは、 「z」をつけて記述した方が式が簡単に済みます。
「origin」は原点\(\small (0,0)\)を指します。 z.Aは、点Aを(5w,0)とするとき、OAを\(\small -30^{\circ}\)だけ 回転した点です。「dir( )」を掛けるることで簡単に回転できます。 同様に、点Bを(4w,0)とするとき、OBを\(\small 40^{\circ}\)だけ 回転した点がz.Bです。 明示的に定義しているのは、この3点だけです。

点を定義した後の式では、他の点C, D, E, Fを、 \[\small {\rm OD}:{\rm DA}={\rm CD}:{\rm DB}=1:2\] \[\small {\rm FE}:{\rm EB}={\rm AE}:{\rm EO}=1:2\] を満たすような点として定義します。 等号を続けた式で記述することができます。 MetaPostはその解を求めて、次のコマンドで利用することができます。 解くことができるのは連立1次方程式に限られます。 なお、ラベルを配置するには、多少の試行錯誤が必要になります。 これは、やむを得ないでしょう。

なお、このような方程式を記述して解を求めるのは連立1次方程式に 限られますが、「グラフの交点」を求めるコマンド 「InSecPoint」を利用すると、 超越方程式の解の近似値を求めることができます。


▲戻る(トップメニューマップ)

各種の図形記号
上の図に\(\small 1:2\)であることを「円弧の記号」で書き入れるには、 「\mptFromTo」を利用します。 書式は

  \mptFromTo[label=文字列]{始点}{終点}

の形です。 始点と終点の順番を変えると、円弧が反対側に表示されます。 始点から終点に向かう方向の左側に円弧が描かれます。 [ ]内には、他にもいろいろな指定をすることができます。 下のサンプルでは、弧DAの箇所で、 labelposとしてラベルを配置する場所を指定しています。 デフォルトの値は0.5で中央に配置されます。線分BFに近くなるので ちょっと左寄りにしました。 arcdirでは、始点からの円弧の角度を指定できます。 デフォルトの値は30度になっています。ここでは40度にしています。 angleで配置する文字を(必要性はないですが)90度回転させています。 markradiusでは、角度マークの半径の大きさを指定することができます。 デフォルトの半径は15ptです。ちょっと大きいように感じたので、 ここでは小さくしています。

「直角マーク」は\mptRightAngleMarkです。 直角をはさむ前後の2点を指定します。 最初の点から最後の点に向かう方向の左側に描かれます。 markradiusの値を変えると、 直角マークの1辺の長さを変更することができます。 デフォルトの値は5ptです。 なお、この角度は、実際には直角ではありません(念のため)。

「角記号」は\mptAngleMarkです。 頂点を挟む他の2点を指定します。 最初の点から最後の点に向かう方向の左側に描かれます。 2点の順番を誤ると角記号が外側につきます。 markradiusの値を変えると、 この記号の半径を変えられます。デフォルでは15ptになっています。 ちょっと大きいので、ここでは小さくしました。

  • \begin{MPpic}<1cm>(4,2|2) \sendMP{  z.O=origin;  z.A=5w*dir(-30);  z.B=4w*dir(40);  2*z.O+z.A=2*z.C+z.B=3*z.D;  z.B+2*z.F=z.O+2*z.A=3*z.E;  xdraw(1pt) z.O--z.A;  xdraw(1pt) z.B--z.C;  xdraw(1pt) z.B--z.F; } % 比を示す円弧 \mptFromTo[label=1]{z.D}{z.O} \mptFromTo[label=2,labelpos=0.7,  arcdir=40,angle=90]{z.A}{z.D} % 角記号 \mptRightAngleMark  [markradius=7pt]  {z.B}{z.D}{z.O} \mptAngleMark[label=$\alpha$,  markradius=10pt]  {z.B}{z.E}{z.D} (以下、上記と同じ) \end{MPpic}

▲戻る(トップメニューマップ)

分点
上記では、一定の比で分ける点を連立方程式を解くことで求めていますが、 比の値を与えて直接指定することもできます。 たとえば、3点A, B, Cを表すpair型の変数を、それぞれz.A, z.B, z.Cとするとき、 線分ABを \(\small t:(1-t)\) に分ける点は 「t[z.A, z.B]」(\(\small 0\leqq t\leqq 1)\) で表されます。 \(\small t<0\) のときは、ABの外側の点になります。 下記では、長さ4cmの線分ABを30度傾けて、 それを 0.25:0.75、つまり 1:3 に内分する点をCとしています。 負の数で指定すると、Aの反対側の点になります。 分点が分かりやすいように弧を入れています。

  • \begin{MPpic}<1cm>(4,4) % 2点A, Bの定義 \mptPoint{z.A}[A][tl]  (5pt){(0,0)} \mptPoint{z.B}[B][bl]  (5pt){4w*dir(30)} % 比を用いたC, Dの定義 \mptPoint{z.C}[C][tl]  (3pt){0.25[z.A,z.B]} \mptPoint{z.D}[D][tl](3pt)  {-0.25[z.A,z.B]} % 円弧 \mptFromTo{z.A}{z.C} \mptFromTo{z.C}{0.5[z.A,z.B]} \mptFromTo{0.5[z.A,z.B]}  {3/4[z.A,z.B]} \mptFromTo{3/4[z.A,z.B]}   {z.B} \mptFromTo{z.D}{z.A} \mptFromTo[label=4cm,  arcdir=40,angle=25]  {z.A}{z.B} \sendMP{  xdraw(0.5pt) z.B--z.D;  } \end{MPpic}
指定した辺の位置に、長さや比の値を円弧を利用しないで配置するには 「\mptLabel」を利用します。 下図では、線分ABを\(\small m:n\) に、 実際には \(\small 2:3\) に内分する点をPとして、 \(\small m, n\) をAPとPBの中点に配置しています。 APの中点を「1/2[z.A,z,P]」で指定しています。 「0.5[z.A, z.P]」でもかまいません。
  • \begin{MPpic}<1cm>(4,4) % 点の定義 \mptPoint{z.A}[A][tr]   (3pt){(0,0)} \mptPoint{z.B}[B][bl]   <1mm,0mm>(3pt)   {4w*dir(30)} \mptPoint{z.P}[P][br](3pt)   {0.4[z.A,z.B]} % 比の値の書き入れ \mptLabel{1/2[z.A,z.P]}[tl]   <1mm,0mm>{$m$} \mptLabel{1/2[z.P,z.B]}[tl]   <1mm,0mm>{$n$} \sendMP{   xdraw(0.5pt) z.B--z.A;   } \end{MPpic}

垂線の足
3点を指定して、そのうちの1点から他の2点を結ぶ線分に垂線を 下ろしたとき、その足の座標を求めることができます。 「\asi(z0,z1,z2)」とすると、 点z0からz1とz2を結ぶ線分に下ろした垂線の足の座標が求められます。

  • \begin{MPpic}<1cm>(4,4) % 点の定義 \mptPoint{z.A}[A][tr]  (3pt){(0,0)} \mptPoint{z.B}[B][bl]  <1mm,0mm>(3pt)  {4w*dir(30)} \mptPoint{z.P}[P][tl]  (3pt){(3w,0)} % 垂線の足と線描画 \sendMP{  z.H=asi(z.P,z.A,z.B);  xdraw(0.5pt) z.B--z.A;  xdraw(0.5pt) z.P--z.H;  } % 足のラベルと直角記号 \mptLabel{z.H}[br]{H} \mptRightAngleMark   {z.P}{z.H}{z.B} \end{MPpic}
上記では、点A, B, Pをそれぞれz.A, z.B, z.Cとして定めた後で、 点Hを点Pから線分ABに下ろした垂線の足として定義し、 その垂線と直角マークを書き入れています。

なお、空間内で、点Pから3点A,B,Cを通る平面に下ろした垂線の足を 求めることもできます。「Asi」です。


▲戻る(トップメニューマップ)

(参照) \mptDrawGrid\mptPoint\mptRightAngleMark\xdraw


円の描き方には、中心と半径を与える方法と、中心と円周上の1点を与える方法が あります。前者は「circle(中心, 半径)」、 後者は、「circle(中心,円周上の点)」です。 ただし、それにより円が描かれるわけではなく、 指定された経路が設定されるだけです。そのような経路を パス(path)といいます。 そして、経路を変数に保持することができます。 そのような変数をパス変数といいます。 経路(パス)を実際に描画するには、xdraw( ) を利用します。

  • \begin{MPpic}<1cm>(4,4) \mptDrawGrid  [linetype=dashed hasen()]  {0 step 1w until 4w}  {0 step 1h until 4w} \mptPoint{z.O}[O][tr]  (3pt){(2w,2h)} \sendMP{  path en; r=2w;  en=circle(z.O,r);  xdraw() en;  } \end{MPpic}
上記では、分かりやすいよう格子の上に円を描いています。 座標で \(\small (2, 2)\) の点をOとして、 半径2の円をパス変数「en」に保持して、 「xdraw( ) en;」により円が描かれています。 ここで宣言する変数名に数字や記号を含めるとエラーになるので気をつけてください。 数字を含めたいときは「path en[];」とします。 「[]」をつけるだけで、en1, en2, en[0.5], en[-1]などを 利用することができます。 経路を保存するには、あらかじめパス変数であることを宣言する必要があります。 「;」で区切れば、1行に複数のコマンドを書いてかまいません。 xdraw( )の括弧内では、線の太さや線種・色などを指定することができます。

ここではパス変数の宣言の仕方をかねましたが、 単に円を描画したいだけであれば 「xdraw() circle(z.O,2w);」だけでかまいません。 「circle」だけでなく「xdraw()」と併用する必要があります。 なお、もともとのMetaPostの描画コマンドは「draw」です。 「draw circle(z.O,2w);」としてもかまいませんが、 その場合には、線の太さや線種、あるいは色をつけるには、 MetaPostの長いコマンド書き入れる必要があります。 描画コマンドは「xdraw()」に1本化した方が良いと思います。

下記では、中心Oの他に、点P(2,0)を指定して円を描いています。 変数指定は行っていません。

  • \begin{MPpic}<1cm>(4,4) \mptDrawGrid  [linetype=dashed hasen()]  {0 step 1w until 4w}  {0 step 1h until 4w} \mptPoint{z.O}[O][tr]  (3pt){(2w,2h)} \mptPoint{z.P}[P][t]  <0mm,-1mm>(3pt){(2w,0)} \sendMP{  xdraw() circle(z.O,z.P);  } \end{MPpic}

▲戻る(トップメニューマップ)

円弧
円弧は「circulararc(中心, 起点, 終点)」で経路を指定します。 このとき、中心と起点は正しく指定する必要がありますが、 終点は円周上の点である必要はありません。中心と終点を結ぶ方向と 円周との交点までが円弧となります。 なお、起点には円弧の半径を指定できますが、 単位付き(w,h,u, あるいは pt, cm など)で指定する必要があります。 終点には中心角(度)を指定することができます。 いずれも、点の座標ではなく数値です。

  • \begin{MPpic}<1cm>(4,4) % 格子の描画 \mptDrawGrid  [linetype=dashed hasen()]  {0 step 1w until 4w}  {0 step 1h until 4w} % 点O,P,Qの定義と配置 \mptPoint{z.O}[O][tr]  (3pt){(2w,2h)} \mptPoint{z.P}[P][t]  <0mm,-1mm>(3pt){(2w,0)} \mptPoint{z.Q}[Q][tl]  <-1mm,0mm>(3pt){(3w,3h)} % 円弧と矢印つき円弧 \sendMP{  path enko;  r=sqrt(2);  xdraw() circulararc   (z.O,z.P,z.Q);  xdraw() z.O--(4w,4h);  enko=circulararc   (z.O,z.Q,120);  xdraw(red,"->") enko; } \end{MPpic}
上記では、OPを起点にしてOQの延長線上までの円弧と、 OQを起点にして中心角120度の円弧を矢印付きで描かれています。 半径と終点部分を数値にして enko を 「circulararc(z.O,r*w,120);」にすると、 中心Oから水平方向に \(\small \sqrt{2}\) だけ離れた箇所から 120度の矢印つきの円弧が描かれます。 経路(パス)を変数に保持するときは、 「sendMP」内で、「path」による変数宣言が必要です。 「xdraw」でのオプション指定により、 矢印には多彩なタイプを利用できます。

▲戻る(トップメニューマップ)

円の接線
MePoTeXには、 円に関する多様な接線を描画するマクロが 用意されています。

■円外の点から引いた接線
中心と半径を指定すると、 円外の点からその円に引いた接線の接点や接線自体を 求めるコマンドがあります。 中心z0、半径rの円に、円外の点z1から引いた接線は 2本あります。z1からz0を見て左側(left)にある接線の接点は 「TangPoint.l(z1,z0,r)」により、 右側(right)の接点は「TangPoint.r(z1,z0,r)」により 求めることができます。 その接線(パス値)は、 それぞれ「Tang.l(z1,z0,r)」「Tang.r(z1,z0,r)」 で求められます。

  • \begin{MPpic}<1cm>  (4|1,4|1) \sendMP{ numeric r; r=w;} % 点O, Pの定義 \mptPoint{z0}[O][tr]  (3pt){origin} \mptPoint{z1}[P][tl]  <0mm,-1mm>(3pt){(3w,2h)} % 接点T1, T2 \mptPoint{z2}[T$_1$][b]  <0mm,1mm>  {TangPoint.r(z1,z0,r)} \mptPoint{z3}[T$_2$][tl]  {TangPoint.l(z1,z0,r)} % 円と接線の描画 \sendMP{  xdraw() circle(z0,r);  xdraw() Tang.l(z1,z0,r);  xdraw() Tang.r(z1,z0,r);  \xdraw() z0--z2;  \xdraw() z0--z3;} % 直角マークの挿入 \mptRightAngleMark  {z1}{z2}{z0} \mptRightAngleMark  {z0}{z3}{z1} \end{MPpic}
上記では、\sendMP内で半径の値を定義します。 その後で中心O(z0)と点P(z1)を定めて、 「TangPoint」を利用して接点の座標をz2, z3に納めます。 その上で、\sendMPを改めて開いて 接線等を描画しています。 接線は、指定された点の両側に少し伸びるように 描かれます。伸ばす必要がないときは、 たとえば「xdraw() z0--z2;」とすればよいでしょう。 両側に伸ばす接線の長さを調整することも できます。マニュアルの104頁を参照してください。

▲戻る(トップメニューマップ)

■2つの円の共通接線
2つの円があるとき、 それらの共通接線を求めることもできます。

今、2つの円の中心と半径を、それぞれz1, r1, z2, r2 とすると、共通接線は外側に2本、 交差するものが2本あるので、全部で4本あります。 外側の接線は「OTang.l, OTang.r」、 内側の接線は「ITang.l, ITang.r」により求められ、 引数の順序は「OTang.l(z1,z2,r1,r2)」のような形です。 l(左)とr(右)の区別は、小円から大円をみたとき、 大円の接点が大円の中心のどちら側にあるかで区別します。 半径が同じ場合は、最初に指定した円を小円とします、

  • \begin{MPpic}<1cm> (4|1,4|1) % 半径の定義 \sendMP{ numeric r[]; r1=w; r2=2w;} % 中心の定義 \mptPoint{z1}[O$_1$][tr] (3pt){origin} \mptPoint{z2}[O$_2$][tl] <0mm,-1mm>(3pt){(4w,3h)} \sendMP{ % 円の描画 xdraw() circle(z1,r1); xdraw() circle(z2,r2); % 外側の接線 xdraw()  OTang.l(z1,z2,r1,r2); xdraw(1pt)  OTang.r(z1,z2,r1,r2); % 内側の接線 xdraw(hasen(),red)  ITang.l(z1,z2,r1,r2); xdraw(hasen(),blue)  ITang.r(z1,z2,r1,r2); } \end{MPpic}
上記では、外側の接線は細線と太線の実線で、 内側の接線は赤と青の破線で描画しています。 それぞれ左(l)、右(r)に対応しているので、 2つの区別をよくみて下さい。 接点の座標が必要なときは、 \sendMPを開く前に前項で述べた「TangPoint」を利用 すれば求められます。

なお、上記の図は、MPpic宣言の出だしで設定した 範囲を超えています。指定した範囲外をカットするには、 「ClipPATH」を利用します。 「xdraw()」の後の部分を、 ClipPATH(OTang.l(z1,z2,r1,r2))」 などとしてすべて「ClipPATH」で囲むと、 次のようになります。 参考までに格子も描画しておきました。

■共通接線の一気表示
円と2つの円の共通接線は、 「drawAllTang(z1,z2,r1,r2,t)」とすると 一気に全部引いてしまうことができます。 最後の引数「t」は「クリップ枠倍率」です。 tの値が負のときは枠線が引かれます。 tの値の絶対値の大きさにより、 伸ばす接線の長さを調整できます。

  • \begin{MPpic}<1cm>  (4|1,4|1) \sendMP{  numeric r[];  r1=w;r2=2w;} \mptPoint{z1}[O$_1$][tr]  (3pt){origin} \mptPoint{z2}[O$_2$][tl]  <0mm,-1mm>(3pt){(4w,3h)} \sendMP{  drawAllTang(z1,z2,r1,r2,-1); } \end{MPpic}

▲戻る(トップメニューマップ)

三角形

3点を指定してxdraw( )でつないでいくと三角形が描かれますが、 「\SetTriangle」を利用すると、 辺の比や角度を指定するだけで描くことができます。

[参照] \mptPoint\mptLabel\mptAngleMark分点


3辺の長さの比
頂点をA, B, Cとし、その対辺を a, b, c とします。 3辺の比 \(\small a:b:c\) を最初に指定して、 どれかの2点を具体的に決めると、 残りの点は自動的に決まります。 書式は、 「\SetTriangle(3点を保持する変数)(3辺の比)」の形です。 変数は、平面座標を表す pair型変数である必要があります。 変数宣言をするのは面倒なので、z.A, z.B, z.C のような形を 利用するのが良いでしょう。
  • \begin{MPpic} % 3辺が3:4:5の三角形を定義 \sendMP{  \SetTriangle(z.A, z.B, z.C)    (3,4,5);   } % 2点を定義すると、 % もう1点は自動決定する。 \mptPoint{z.A}[A][t]   <0mm,-1mm>{origin} \mptPoint{z.B}[B][t]   <0mm,-1mm>{(4w,0)} \mptPoint{z.C}[C][b]   <0mm,1mm>{z.C} % 点のラベル \mptLabel{1/2[z.A,z.B]}[t]   <0mm,-1mm>{$c$} \mptLabel{1/2[z.B,z.C]}[bl]   <1mm,0mm>{$a$} \mptLabel{1/2[z.C,z.A]}[br]   <-1mm,0mm>{$b$} % 三角形を描画 \sendMP{   xdraw(1pt) z.A--z.B      --z.C--cycle;   } \end{MPpic}
上記では、最初に3辺の比を指定します。 その上で、2点A, Bの座標を具体的に指定すると、 残りの点Cは自動的に決まります。 その後で、各辺の中点に辺の長さを表す文字を 配置しています。 2点間の比を与えて分点を決定するマクロを利用しています。 originは原点で、(0,0)のことです。 3辺の比は、点の座標を指定する前に記述する必要があります。

▲戻る(トップメニューマップ)


2辺の比と挟角
2辺の比と挟角を与えることでも三角形が決定します。 「\SetTriangle(3点)(2辺の比,挟角)」の形で指定します。
  • \begin{MPpic}<1cm>(4,4) % 2辺が11:12で、 % 挟角30度の三角形 \sendMP{ \SetTriangle(z.A, z.B, z.C)    (-11,30,-12);   } % 2点を定義 \mptPoint{z.A}[A][t]   <0mm,-1mm>{origin} \mptPoint{z.B}[B][t]   <0mm,-1mm>{(4w,0)} \mptPoint{z.C}[C][b]   <0mm,1mm>{z.C} % 点のラベルと角マーク \mptLabel{1/2[z.A,z.B]}[t]  <0mm,-1mm>{$c$} \mptLabel{1/2[z.B,z.C]}[bl]  <1mm,0mm>{$a$} \mptAngleMark  [label=$\theta$]  {z.C}{z.B}{z.A} % 三角形描画 \sendMP{ xdraw(1pt) z.A--z.B --z.C--cycle;  } \end{MPpic}
\SetTriangle( )( )の最初の括弧では点を指定し、 2つめの括弧では指定された点に対応する対辺を設定します。 ここでは、\(\small a: c=11: 12\) を指定しています。 この場合の比の値は符号「-」をつけて指定します。 残った箇所には、その2辺に挟まれる角の値(度)を指定します。

▲戻る(トップメニューマップ)


2つの内角
2つの内角を決めると、残りの角は自動的に決まってきます。 さらに、2つの頂点を決めると、三角形が決定します。 2つ目の括弧では、 最初に指定する点を頂点とする頂角を2つ指定します。 残りの角には「0」を入れます。
  • \begin{MPpic}<1cm>(4,4) % 2つの内角を指定 \sendMP{ \SetTriangle(z.A, z.B, z.C)    (70,30,0);   } % 2点を定義 \mptPoint{z.A}[A][t]   <0mm,-1mm>{origin} \mptPoint{z.B}[B][t]   <0mm,-1mm>{(4w,0)} \mptPoint{z.C}[C][b]   <0mm,1mm>{z.C} % 角マーク \mptAngleMark  [label=$\alpha$,   markradius=10pt,   labeldist=6pt]   {z.B}{z.A}{z.C} \mptAngleMark  [label=$\beta$,   markradius=18pt,   labeldist=6pt]   {z.C}{z.B}{z.A} % 三角形描画 \sendMP{  xdraw(1pt) z.A--z.B    --z.C--cycle;  } \end{MPpic}
上記では、\(\small \angle{\rm A}=70^{\circ}, \angle{\rm B}=30^{\circ}\) を指定しました。 また、各記号の半径(markradius)と、 角を表すラベルの位置(labeldist)を調整しています。

▲戻る(トップメニューマップ)


三角形の諸要素
三角形は基本的な図形なのですが、 驚くほどのいろいろな性質があります。 MePoTeXでは、三角形を指定すると、 重心、外心、 内心、垂心、そして 傍心を求めるコマンドが用意されています。 以下では、重心と内心についての利用例を説明します。

■重心
  • \begin{MPpic}<1cm>(5|1,4|1) % [A] 3点と重心。三角形描画。 \sendMP{  z0=origin; z1=(4w,0);  z2=(3w,2h);  z3=jusin(z0,z1,z2);  xdraw() z0--z1    --z2--cycle;  } % [B] 頂点のラベル。 \mptPoint{z0}[B][tr]  <0mm,-1mm>(3pt){(0,0)} \mptPoint{z1}[C][t]  <0mm,-1mm>(3pt){(4w,0)} \mptPoint{z2}[A][bl]  <0mm,1mm>(3pt){(3w,3h)} %[C]頂点から対辺の中点に線。 \sendMP{ xdraw(.3pt) z0--1/2[z1,z2]; xdraw(.3pt) z1--1/2[z2,z0]; xdraw(.3pt) z2--1/2[z0,z1];  } % [D] 中点であることの記号。 \mptPoint{z3}[G][tr]  <0mm,-1mm>(3pt){z3} \mptLabel{1/4[z0,z1]}   {$\circ$} \mptLabel{3/4[z0,z1]}   {$\circ$} \sendMP{ drawTick(z1--z2)(0.25,0.75)   (0)(-2pt,2pt); drawTick(z2--z0)(0.25,0.75)   (-1pt,1pt)(-2pt,2pt);  } \end{MPpic}
[A]では、最初に頂点を定義して重心を求め、 三角形を描画しています。
[B]では、定義した座標 z2, z0, z1 に A, B, C をラベルづけしました。 順番を変えたのにはあまり意味はありません。 z.A, z.B, z.C としてもかまいませんが、数字の添え字を用いた理由は 後述します。
[C]では、定義した3点を頂点とする三角形の重心を z3 として、 各頂点から対辺の中点まで線を引いていきます。 たとえば、BC間の中点は「1/2[z0,z1]」 により指定できます。
[D]では、重心Gにラベルをつけています。 ラベルを配置してから線を引くと、文字と線がかぶるので、 [C][D]の描画順には注意が必要です。 また、辺BCに等分したことを示す記号を付しています。
[E]では、等分記号を短い線分で描いています。 「drawTick」はMetaPostのコマンドで、 次のような書式になります。

  drawTick(線分)(目盛りを配置する相対位置)
    (相対位置からのずれ)(線分の始点と終点)

目盛りを配置する位置は、 始点を0、終点を1とした相対座標で指定します。 いずれも、1/4, 3/4の箇所に配置するように指定しています。 「ずれ」は、相対位置からのずれです。 相対位置の箇所でかまわないときは、 ACのように(0)を指定します。ABのように2本線を引くときは、 (-1pt, 1pt)としてずらしています。 線分ABの場合の短い線は、相対位置で(-1pt,-2pt)から(-1pt,2pt)までと、 (1pt,-2pt)から(1pt,2pt)までの線が引かれています。

▲戻る(トップメニューマップ)

■内心
  • \begin{MPpic}(5|1,4|1) % [A] 頂点と内心の定義。 % 三角形描画。 \sendMP{  z0=origin; z1=(4w,0);  z2=(3w,3h);  z3=naisin(z0,z1,z2);  xdraw() z0--z1--z2     --cycle;   } % [B] 頂点のラベルづけ。 \mptPoint{z0}[B][tr]   <0mm,-1mm>(3pt){(0,0)} \mptPoint{z1}[C][t]と   <0mm,-1mm>(3pt){(4w,0)} \mptPoint{z2}[A][bl]   <0mm,1mm>(3pt){(3w,3h)} % [C] 内心から頂点への線と % 内心円。 \mptPoint{z3}[I][tr]   <0mm,-1mm>(3pt){z3} \sendMP{  xdraw(.3pt) z0--z3;  xdraw(.3pt) z1--z3;  xdraw(.3pt) z2--z3;  xdraw(.3pt)   circle(z3,asi(z3,z0,z1));  } % [D]角の2等分と直角の記号 \mptAngleMark  [tick=0,arcdir=30]  {z2}{z0}{z3} \mptAngleMark  [tick=0,arcdir=30]  {z3}{z0}{z1} \mptPutAngleMark  [tickpos={0.25,0.75}]  {z2}{z1}{z0}  {\tiny $\circ$} \mptPutAngleMark  [tickpos={0.25,0.75}]  {z0}{z2}{z1}  {\tiny $\bullet$} \mptRightAngleMark{z3}  {asi(z3,z0,z1)}{z1} \end{MPpic}
[A]〜[C]の箇所は、重心のときと同様です。 内心は「naisin(z0,z1,z3)」により得られます。 [D]では、角の2等分の記号を付しています。 「\mptAngleMark」は、角の円弧を描いて、 指定された箇所に目盛りの短い線を入れます。 オプションの「tick=0」は弧の中央を指しています。 \(\small \angle \rm ABC\)において、 AB側に寄って打ちたいときは負のptで、 BC側に寄って打ちたいときは正のptで指定します。 「arcdir」は、円弧の始点での方向です。 \(\small \angle \rm ABC\)の場合は、ABから伸びる弧の方向を指定します。

▲戻る(トップメニューマップ)

■\sendMP内の繰返し
ここでのサンプルでは、点を z.A というタイプではなく、 添え字に数を用いた z0, z1, z2, z3 の形で指定しました。 MetaPostでは、\(\small n\) を数値とすると、 zn は z[n] と同一視されます。したがって、たとえば z.2 は z[0.2]のことになります。 このことを利用すると、重心や内心から各頂点に線を引く部分を プログラムで簡潔に指定することができます。 下記では、ラベルの指定等を省いています。
  • \begin{MPpic}<1cm>(5|1,4|1) \sendMP{ % [A] 点の定義と三角形の描画  z0=origin;  z1=(4w,0); z2=(3w,3h);  z3=naisin(z0,z1,z2);  xdraw() z0--z1--z2--cycle; % [B] 内心から垂線を描画 for n=0,1,2:  draw z[3]--asi(z[3],  z[(n)mod3],z[(n+1)mod3]); endfor; % [C] 内心円の描画 xdraw(.3pt)  circle(z3,asi(z3,z0,z1));  } \end{MPpic}
[B]では、内心から各辺への垂線描画を 繰り返し処理で行っています。 「mod 3」は3で割った余りを返します。 n=0,1,2のとき、(n,n+1)=(0,1), (1,2), (2,3)ですが、3で割った余りは (n,n+1)=(0,1), (1,2), (2,0) となるので、 各辺への垂線の足が網羅されます。 点の分かりやすさでは「z.A」タイプですが、 何らかの同一操作を繰り返すときは、点は「zn」タイプを利用した方が 良いように思います。

同じ書式を利用すると、重心をz3として各辺の中点を結ぶには  draw(z3,1/2[z[(n)mod3],
   z[(n+1)mod3])
を繰り返すことで実現できます。


▲戻る(トップメニューマップ)

四角形

[参照] \mptPoint\mptLabel\mptAngleMarkxdraw分点


4点定義
四角形を描くには、単に4点を指定してxdraw( )でつないでいくだけです。
  • \begin{MPpic}<1cm>(6,4) \mptPoint{z.A}[A][tr]   <-1mm,-1mm>{origin} \mptPoint{z.B}[B][tl]   <1mm,0mm>{(6w,0)} \mptPoint{z.C}[C][bl]   <0mm,1mm>{(5w,3h)} \mptPoint{z.D}[D][br]   <0mm,1mm>{(2w,4h)} \sendMP{ xdraw() z.A--z.B--   z.C--z.D--cycle; } \end{MPpic}

▲戻る(トップメニューマップ)

長さと角度
点を次々に繋いでいくだけなのですが、 その際に距離や角度を定めながら繋いでいくこともできます。 初字に「z」のついた変数は、 複素数やベクトルとして利用することができます。 たとえば、点 z.P から右方向に 4w 進んだ点は「z.P+4w*right」 の形で指定することができます。 「right」は「dir0」のことで、0度方向の単位ベクトルです。 同様の形で、left, up, down が利用できます。 20度方向であれば「dir20」です。角度は、つねに横軸の正の方向から 図った角です。\(\small -20\)であれば、「dir-20」とします。 ( ) で囲ってもよいですが、数の場合は省略することができます。
  • \begin{MPpic}<1cm>(6,4) \mptPoint{z.A}[A][tr]   <-1mm,-1mm>{origin} \mptPoint{z.B}[B][tl]   <1mm,0mm>   {z.A+6w*right} \mptPoint{z.C}[C][bl]   <0mm,1mm>   {z.B+3w*dir120} \mptPoint{z.D}[D][br]   <0mm,1mm>   {z.C+3w*dir160} \sendMP{ xdraw(1pt) z.A--z.B--   z.C--z.D--cycle; } \mptLabel{1/2[z.A,z.B]}[t]   <0mm,-1mm>{6} \mptFromTo   [label=3]{z.C}{z.B} \mptLabel{1/2[z.C,z.D]}[bl]   <1mm,0mm>{3} \mptAngleMark  [label=$60^{\circ}$,    xshift=-5pt]  {z.C}{z.B}{z.A} \end{MPpic}
上記は、点Aからスタートして、右に 6w 進んだ点をB、 そこから120度の方向に 3w だけ進んだ点をC、 そして、さらに160度の方向に 3w だけ進んだ点をDとしています。 したがって、辺AB, BC, CDの長さは正確で、\(\small \angle{\rm ABC}\)も 正確に60度です。辺の長さは、 分点を決めるマクロ「t[z.A,z.B]」 を利用して各辺の中点に書き込まれています。

▲戻る(トップメニューマップ)

4辺の比
前述のやり方では最後の辺の長さが分かりませんが、 MePoTeXには4辺の長さの比と具体的な2点を指定すると、 一気に円に内接する四角形を描画するマクロがあります。 「SetInsTetragon」です。 外接円の中心も求められます。 書式は、次のようなものです。\sendMP内で使用します。

 SetInstTetragon(頂点の名前)(外接円の中心)(4辺の長さの比)

  • \begin{MPpic}<1cm>(6,4|2) % [A] 4辺の比を指定 \sendMP{ SetInsTetragon  (z.A, z.B, z.C, z.D)  (z.O)(6,3,3,4);} % [B] 2点を定義 \mptPoint{z.A}[A][tr]  <-1mm,-1mm>{origin} \mptPoint{z.B}[B][tl]  <1mm,0mm>{z.A+6w*right} % [C] 他の点の配置 \mptPoint{z.C}[C][bl]   <0mm,1mm>{z.C} \mptPoint{z.D}[D][br]   <0mm,1mm>{z.D} \mptPoint{z.O}[O][b]   <0mm,1mm>(2pt){z.O} % [D] 四角形と外接円 \sendMP{ xdraw(1pt) z.A--z.B--   z.C--z.D--cycle; xdraw(hasen())   circle(z.O,z.A); } % [E] 辺の比を記入 \mptFromTo[label=6,   arcdir=15]{z.B}{z.A} \mptLabel{1/2[z.B,z.C]}[tr]   <-1mm,0mm>{3} \mptLabel{1/2[z.C,z.D]}[tr]   <0mm,-1mm>{3} \mptLabel{1/2[z.D,z.A]}[tl]   <1mm,0mm>{4} \end{MPpic}
上記では、最初に[A]で\sendMPにより頂点の名前と外接円の中心を納める 変数と4辺の比の値を定めます。 頂点を A, B, C, Dとすると、それぞれ AB, BC, CD, DA の順の比になります。 この時点では、点の座標は定まっている必要はありません。
次に、[B]で具体的な2点を定めます。 ここでは、前述の例にならい、底辺の端点 A, B を指定しています。 これを指定した段階で他の2点と中心の座標が定まります。
[C]では、他の点 C, D, O のラベルを配置する位置を指定しています。
以上の指定を終えた後で、[D]で xdraw を利用して 四角形と外接円を描画します。
[E]では、辺の比の値を書き入れています。 デフォルトで描画するとABの円弧が大きすぎるので、 「arcdir」により弧の角度を小さくしています。

▲戻る(トップメニューマップ)

多角形

[参照] \mptPoint\mptLabel\mptAngleMark\mptDrawGrid


正多角形
正多角形を描くには「Polygon」を利用して、 中心と頂点の数を指定します。
  • \begin{MPpic}<2cm>(2|2,2|2) \mptDrawGrid  [linetype=dashed hasen()]  {-2w step w until 2w}  {-2w step w until 2w} \sendMP{  xdraw() Polygon(5,z0); } \end{MPpic}
上記では、参考までに格子も描画しました。 「Polygon(5, z0)」を描画していますが、 頂点の数を指定しただけで中心 z0 は具体的には指定されていません。 「Polygon」は、中心が指定されないときは原点を中心とします。 頂点数が指定されても半径が指定されないと具体的に描画できませんせんが、 指定されないときは (w,0) を一つの頂点として描画します。 つまり、頂点数だけ指定されて中心も頂点も指定されないときは、 原点を中心として、一つの頂点は (w,0) であるとして描画します。 また、中心を指定するときは、あらかじめペア型変数に座標を定義して、 その変数を用いて指定します。Polygon の中に座標で定義することは できません。

中心の座標を納める変数をたとえば z0 とすると、 Polygon は、 各頂点を自動的に z0v1, z0v2, などの変数に反時計回りに 割り振ります。頂点だけではなく、各辺の中点も z0s1, z0s2, などに割り振ります。 したがって、中心と頂点数だけ指定すれば、 他の頂点や各辺の中点の座標を自分で求める必要はありません。 描画した正多角形の外接円は、中心と頂点を指定すれば描画されます。 また、内接円は中心と辺の中点を指定すれば描画されます。 さらには、正多角形の周の長さも求められます。中心を z0 とした場合は、 周の長さは L.zo という数値変数(numeric)に記録されています。

  • \begin{MPpic}<1cm>(4|4,5|3) \mptDrawGrid  [linetype=dashed hasen()]  {-4w step w until 4w}  {-3w step w until 5w} \sendMP{  z0v1=(2w,-2h);  z0v5=(-2w,-2h);  xdraw(1pt) Polygon(5,z0);  xdraw() circle(z0,z0v1);  xdraw(red) circle(z0,z0s1); } \mptLabel{z0v5}[tr]{A} \mptLabel{z0v1}[tl]{B} \mptPoint{z0}[O][tr]  <-1mm,0mm>(3pt){z0} \mptLabel{(-3w,-3.5h)}  {周の長さ  $L=\UseNumeric{L.z0}$} \end{MPpic}
上記では、最初に2つの頂点の座標を指定しています。 この2点を指定するだけで辺の長さが決まるので、 頂点数を指定すると正多角形が描画されます。 指定した2点を A, B 、 中心を O としてラベルを配置しました。 また、周の長さが L.zo に計算されているので、 「UseNumeric」というマクロを利用して表示しています。

▲戻る(トップメニューマップ)


内接・外接多角形
円に内接または外接する多角形の中心角の列を指定して、 その多角形を描くマクロも用意されています。 円に内接する多角形は「IPolygon」、外接多角形は「OPolygon」です。 指定する角度は、内接多角形では中心と頂点を結んだときの中心角、 外接多角形では中心と接点を結んだときの中心角です。

正多角形の場合と同様に、中心を z0 とした場合、 内接多角形の頂点の座標は z0v1, z0v2 などに、 外接多角形の頂点の座標は z0s1, z0s2 などに、 そして周の長さは L.z0 に納められます。

  • \begin{MPpic}<1cm>(4|4,6|3) \sendMP{ % 内接多角形の底辺2点を定義 z0v1=(2w,-2h); z0v5=(-2w,-2h); % 内接多角形の描画 xdraw(1pt,red)  IPolygon    (90,120,60,30)(z0); % 内接多角形の中心と同じに、 % 接点の1つを内接点にして % 外接多角形を描画 z1=z0; z1s5=z0v5; xdraw(1pt,blue)  OPolygon    (90,120,60,30)(z1); % 円を描画 xdraw(hasen())  circle(z0,z0v1); % 中心と頂点を結ぶ for i=1 step 1 until 5: xdraw(red) z0--z0v[i] endfor; } % ラベルの配置 \mptLabel{z0v5}[tr]{A} \mptLabel{z0v1}[tl]{B} \mptPoint{z0}[O][tr]   <-1mm,0mm>(3pt){z0} \end{MPpic}
上記では、内接多角形の底辺の両端を定義して、 中心角として 90度, 120度, 60度, 30度を指定しています。 残りの角は自動的に計算されます。 2つの多角形が描画されますが、それぞれの中心を表す変数は、 その頂点や接点を表す都合上、変える必要があります。 たとえば、z0v1は内接多角形の頂点ですが、v0s1は辺の中点を表します。 内接多角形の頂点と外接多角形の接点は計算されますが、 外接多角形の頂点の座標は計算されないので注意が必要です。

▲戻る(トップメニューマップ)

■平面グラフ

(注) Web上での表示の都合上、 空白は全角を使用しています。 以下のコードをコピーして実行するときは、 半角の空白かtabで置き換えて実行してください。


グラフ描画
[参照] \mptDrawGrid\mptXaxis\mptLabel\sendMPxdraw

登録関数
MetaPostには一通りの関数がそろっていますが、 三角関数は度数法が利用されていたり、指数関数は \(\small e^x\) ではなく \(\small e^{x/256}\) が利用されていたりするようです。 通常の使用では使いにくいので、MePoTeXでは使いやすく改良されています。 以下のような関数を使用できます。
  • 整数関数
    整数\(\small l\)を整数\(\small r\)で割った余りは「mod(l/r)」、 商は「div(l/r)」。整数に丸めるのは「round」。ガウス記号 \(\small [ ]\) は「floor」。
  • 絶対値関数は「abs」。平方根は「sqrt」。
  • 三角関数
    弧度法では「sin, cos, tan」、逆関数は「Arcsin, Arccos, Arctan」。
    度数法では「sind, cosd, tand」、逆関数は「Arcsind, Arccosd, Arctand」。
  • 指数・対数関数
    指数関数 \(\small e^x\) は「exp」、 対数関数 \(\small \log_e{x}\) は「ln」、 常用対数 \(\small \log_{10}{x}\) は「Log」。
  • べき乗は「**」を利用する。 たとえば、\(\small x^y\) は「x**y」とする (この書式はgnuplotでも同様)。
  • ベクトル関係
    平面ベクトルの方向角は「angle」(度数法)、長さは「abs」、 x, y成分はそれぞれ「xpart, ypart」。 x度方向の単位ベクトルは「dir(x)」。
  • 円周率 \(\small \pi\) は「PI=3.1415」が登録済みです。

★マニュアルの図のコードをコピーして実行して「\dis」に関する エラーが出るときは、こちらを参照してください。

▲戻る(トップメニューマップ)


直線
直線は、 次の項目で述べる一般的な関数のグラフ描画 コマンド「kansu」を利用することもできますが、 1次式を指定して直線のパスを得て、 それを xdraw() で描画することもできます。 「linear」と「Linear」という2つのマクロが用意されています。 1次式は \(\small t\) を変数として、次のような書式で指定します。

linear(at+b)(左端, 右端)(下端, 上端)
Linear(at+b)           

左端・右端は横軸の範囲、下端・上端は縦軸の範囲です。 「Linear」を利用すると、\begin{MPpic} で指定した範囲が用いられます。

座標軸に平行な直線、特に縦軸に平行な直線は1次式では指定できません。 媒介変数を利用すれば描画できますが、 MePoTeXでは座標軸に平行な直線を描画するマクロが用意されています。 「Hline」「Vline」です。それぞれ、次のような書式になります。

横軸に平行 Hline(\(\small y\) 座標)(左端)(右端)
縦軸に平行 Vline(\(\small x\) 座標)(下端)(上端)

  • \begin{MPpic}<1cm>(5|5,4|4) % グリッドと座標軸 \mptDrawGrid  [linetype=dashed hasen(),   xmin=-5w,xmax=5w,   ymin=-4h,ymax=4h]   {-5w step w until 5w}   {-4h step h until 4h} \mptXaxis[l]<1mm,0mm>{$x$} \mptYaxis[b]<0mm,1mm>{$y$} % \sendMP{ % パス変数の宣言  path la,lb; % 直線のパス設定と描画  la:=linear(t/2-1)(-4,4)(-3,1);  lb:=Linear(-t/2+1);  xdraw() la;  xdraw(red) lb; % 座標軸に平行な直線  xdraw(blue) Vline(-3)()();  xdraw(green) Hline(2)(-4)(4);} \end{MPpic}
上記のコードでは、いったん直線のパスをパス変数に保存していますが、 変数宣言することなく 「xdraw() Linear(-t/2+1)」のような形で利用することもできます。 また、座標軸に平行な直線の左端・右端や下端・上端を省略すると、 \begin{MPpic}で指定した範囲で描画されます。

▲戻る(トップメニューマップ)


グラフ描画
関数 \(\small f(x)\) の \(\small a\leqq x\leqq b\) における グラフを描画するコマンドは、 「kansu(f(t))(a, b, 分割数)」です。 独立変数は \(\small t\) を使用します。 グラフは、指定された範囲を分割数で指定した区間に細分し、 各小区間ごとに端点の座標を計算してそれを結んで描かれます。 したがって、分割数を多くするほど精密なグラフになりますが、 必要以上に多くすると時間がかかります。 具体的な数値と変数との積では、積の記号「*」は省略してかまいません。
  • \begin{MPpic}<1cm>(4|4,6|2) % 格子の描画 \mptDrawGrid  [linetype=dashed hasen()]  {-4w step 1w until 4.1w}  {-2w step 1w until 6.1w} % 座標軸の描画 \mptXaxis[l]   <1mm,0mm>{$x$} \mptYaxis[b]   <0mm,1mm>{$y$} % グラフの描画 \sendMP{  xdraw() kansu   (abs(t*t-4))(-4,4,40);  xdraw() kansu(t+2)   (-4,4,10); } \end{MPpic}
上記では、\(\small |x^2-4|, x+2\) のグラフを \(\small -4\leqq x\leqq 4,~-2\leqq y\leqq 6\) の範囲で描画していますが、 グラフが範囲からはみ出している部分があります。 \(\small |x^2-4|\) の定義域を調整することで範囲内に収まるように することもできますが、 MePoTeXには範囲外の部分を切り取るマクロがあります。 グラフ描画に関わるいろいろな機能は、 「描画の小技」を参照してください。 「ClipPATH」です。
  • \begin{MPpic}<1cm>(4|4,6|2) % 格子の描画(同上) % 座標軸の描画(同上) % 経路(パス)の保存と描画 \sendMP{  path ptha,pthb;  ptha=kansu(abs(t*t-4))    (-4,4,40);  pthb=Linear(t+2);  xdraw() ClipPATH(ptha);  xdraw() pthb; } \end{MPpic}
はみ出し部分をカットするには、 最初に提示したコードで絶対値関数の部分を 「ClipPATH」を用いて「xdraw() ClipPATH(kansuu(略)(略))」とするだけですが、 上記では別な形のコードで提示しています。
MetaPostにはいろいろな変数宣言がありますが、 グラフや図形自体を保持する変数があります。 それが「パス変数」と呼ばれるものです。 変数名に数字や記号を含めるとエラーになるので気をつけてください。 \sendMP内の最初で、ptha, pthbをそのような変数として宣言し、 その後にそれぞれの変数に関数とその定義域部分を定義します。 「Linear」を用いると、 1次関数 \(\small at+b\) の式だけを定義するだけですみます。 「Linear」は、\sendMPで設定した区画からはみ出した部分は ClipPATHを使用しなくても自動的にカットします。

なお、「ClipPATH」は万能ではありません。基本的には、 グラフの始点や終点がはみ出す場合が想定されています。 途中で何度も出たり入ったりするような場合は想定されていないので、 そのような場合は\sendMPの区画を調整した方が良いでしょう。

▲戻る(トップメニューマップ)


媒介変数表示
媒介変数表示で \(\small x=f(t), y=g(t)~(\alpha\leqq t\leqq \beta)\) で表された関数のグラフは、「kansuP」を利用して同様にします。 下記は、リサージュ曲線 \(\small x=\sin{2t}, y=\sin{3t}\) です。 ラベルの配置はグラフを描画してから行うと、 文字の背景部分のグラフを消して表示されます。
  • \begin{MPpic}<2.5cm>   (1.25|1.25,1.25|1.25) % 格子の描画 \mptDrawGrid [linetype=dashed hasen()] {-1.25w step 0.25w   until 1.25w} {-1.25w step 0.25w   until 1.25w} % 座標軸の描画 \mptXaxis[l]   <1mm,0mm>{$x$} \mptYaxis[b]   <0mm,1mm>{$y$} % グラフの描画 \sendMP{  xdraw()   kansuP(sin(2t),sin(3t))    (0,2*PI,500) } % ラベルの配置 \mptLabel{origin}[tr]   <-1mm,-1mm>{O} \mptLabel{(w,0)}[tl]   <1mm,-1mm>{1} \mptLabel{(-w,0)}[tl]   <-1mm,-1mm>{$-1$} \mptLabel{(0,h)}[br]   <-1mm,1mm>{1} \mptLabel{(0,-h)}[tr]   <-1mm,-1mm>{$-1$} \end{MPpic}
▲戻る(トップメニューマップ)


サイクロイド
媒介変数表示で表される曲線としては、 サイクロイド曲線がよく例示されます。 これは、直線上を円が転がっていくときの、 円上の定点が描く軌跡です。周知のように、 半径 \(\small a\) の円上の定点を原点とすると、 その定点の描く軌跡は次の式で表されます。

  \(\small x=a(t-\sin{t})\)
  \(\small y=a(1-\cos{t})\)

この曲線は、 前述の媒介変数表示を利用すると描くことが できますが、転がっている円までは描画されません。 MePoTeXでは、その円も同時に描くマクロが用意されています。 「drawCycloid」です。書式は、

 drawCycloid(パス, 半径, 分割数, 円描画)

の形です。「パス」によりどんな曲線に沿って転がすかを 指定できます。必ずしも直線である必要はありません。 半径は転がる円の半径で、分割数は、 転がす曲線(パス)を幾つかに分割して軌跡を求めるかを 指定します。 分割点ごとの座標を求めて結んでいくので、 当然ながら分割数が多いほどなめらかな曲線になります。 「円描画」では、\(\small n\) 分割したときに 転がる円を描く箇所を指定することができます。 つまり、何分割目の円を表示するかを指定できます。 0〜n 以外の数の場合は円は描かれずにサイクロイド曲線 だけが描かれます。 (a,k) の形のペア型変数で指定すると、 \(\small x=a\) の箇所から分割点が \(\small k\) ごとの円が描画されます。
  • \begin{MPpic}<1cm>(8|2,2) % パス(pth)の定義 \mptPath{pth} {(0,0)--(2*PI*w,0)} \sendMP{ % パスを描画 xdraw() pth; % サイクロイドを描画 drawCycloid(pth,w,100,-1); } \end{MPpic}
上記では、「\mptPath」により 線分「(0,0)--(2*PI*w,0)」を「pth」という 変数に保存しています。 経路(パス)を保持しているだけで描画はされません。 このように、\mptPathを利用すると、 パス変数であることをいちいち宣言する必要はありません。 マニュアル(57頁)では原点を「orijin」として指定されて いますが、エラーになるので「(0,0)」としています。

その後で、 \sendMP内で定義したパス(pth)を描画して、 指定したパスの区間 \(\small [0, 2\pi]\) を100等分して 半径1(w)の円に対するサイクロイド曲線を描画しています。 「円描画」の箇所には負数を指定したので、 円は描画されません。


▲戻る(トップメニューマップ)

以下は、この引数をいろいろ変えた場合です。
  • 「drawCycloid(pth,w,100,50)」
    円だけが描画されます。 100分割したときの50番目なので、 ちょうど半回転したときです。 曲線も描画するには、上記のコマンドも記述します。
  • 「drawCycloid(pth,w,100,(0,25)」
    0番目から始めて、25番目ごとの円が描画されます。 100分割しているので全部で5個の円が描画されます。
下記は「drawCycloid(pth,w,100,-1)」も 書き入れた場合です。\sendMPを2つ利用して、 2つ目の\sendMPでは[1pt]で線の太さを指定しています。 デフォルトの太さは 0.6pt です。
  • \begin{MPpic}<1cm>(8|2,2) \mptPath{pth}   {(0,0)--(2*PI*w,0)} \sendMP{ xdraw() pth; drawCycloid    (pth,w,100,(0,25));} \sendMP[1pt]{ drawCycloid    (pth,w,100,-1);} \end{MPpic}
「drawCycloid」に指定するパスは、 直線である必要はありません。 円を指定すると、アステロイド曲線が描かれます。 いろいろな曲線を指定して遊んでみることができます。
  • \begin{MPpic}<1cm>   (5|5,5|5) \mptXaxis<1mm,0mm>{$x$} \mptYaxis<0mm,1mm>{$y$} \mptPath{pth}  {circle((0,0),4w)} \sendMP{  xdraw(hasen()) pth;  drawCycloid   (pth,w,100,(0,5));} \sendMP[1pt]{  drawCycloid   (pth,w,100,-1);} \end{MPpic}
▲戻る(トップメニューマップ)


トロコイド
サイクロイドは円周上の1点が描く軌跡ですが、 円周上の点と中心を結ぶ線分を内分あるいは外分する点が描く 軌跡はトロコイドと呼ばれます。 そのトロコイドを描くマクロは「drawTrochoid」です。 引数が1つ増えて、回転する円の半径の後の引数は、 円周上の点と中心を結ぶ線分上のどの点の軌跡を描くかを 指定します。下記では、1.5倍の点(つまり、回転円の外側の点) の軌跡を描くことを指定しています。 負の数を指定すると、中心の反対側の点になります。 他の引数は、サイクロイドの場合と同様です。
  • \begin{MPpic}<1cm>(8|2,2) % パス(pth)の定義 \mptPath{pth}   {circle((0,0),4w)} \sendMP{   xdraw() pth; % 100分割中10刻みで円描画   drawTrochoid   (pth,w,1.5,100,(0,10));} % トロコイド曲線の描画 \sendMP[1pt]{   drawTrochoid   (pth,w,1.5,100,-1);} \end{MPpic}
サイクロイドの場合も同様ですが、 パス(pth)で指定する曲線は任意でかまいません。 マニュアルにある図92(p58)では、 適当な点を xdraw() で結んだ曲線が指定されています。

▲戻る(トップメニューマップ)


極座標
極座標で \(\small r=f(\theta)~(\alpha\leqq \theta\leqq \beta)\) で表された関数のグラフは、 度数法では「kansuR」、弧度法では「kansuRR」を利用して同様にします。 格子「\mptDrawGrid」のオプションに「polar」を追加すると、 同心円と動径が描画されます。 半径を 0.2w 刻み、動径は 36度刻みにしています。 角度のデフォルトの単位は度数法です。半径部分に単位の「w」をつけないと、 「pt」が単位となります。

下記は、三葉線 \(\small r=\sin{3\theta}\) のグラフです。 極座標の場合は度数法を用いた方が扱いやすいので、 三角関数は「sind」を利用しています。

  • \begin{MPpic}<2.5cm>   (1.2|1.2,1.2|1.2) % 格子の描画 \mptDrawGrid  [polar,  linetype=dashed hasen()]  {0 step .2w until 1.21w}  {36 step 36 until 360} % 座標軸の描画 \mptXaxis[l]   <1mm,0mm>{$x$} \mptYaxis[b]   <0mm,1mm>{$y$} % 経路(パス)の保存 \sendMP{  xdraw() kansuR(sind(3t))    (0,360,500) } \mptLabel{(1w,0)}[tr]   <0mm,-1mm>{1} \mptLabel{(0,1h)}[br]   <-1mm,0mm>{1} \end{MPpic}
▲戻る(トップメニューマップ)


繰返しと条件文
既存の関数を組み合わせて自前の関数を定義するため、 繰り返し処理や条件文を利用することができます。 下記では、目に見える描画部分で例示します。

[参照] xfillcircle

■for文
繰り返し処理を行う「for-endfor」は、下記のような形で利用します。

  • \begin{MPpic}<1cm>(4,4) \sendMP{  z0=origin; % [A]刻み幅を指定した繰り返し  for n=0 step 30 until 90:   xdraw() z0--dir(n)*4w;  endfor; %[B] 値を指定した繰り返し  for n=15,45,75:   xdraw(blue) z0--dir(n)*2w;  endfor; %[C] 上限を指定した繰り返し  for n=1 upto 4:   xdraw(green)     z0--dir(n*20)*3w;  endfor; %[D] 線で結ぶ動作の繰り返し  xdraw(red) z0   for n=1 step 30 until 91:    --dir(n)*4w   endfor; } \end{MPpic}

[A]は刻み幅を指定した繰返しです。 原点をO、座標が(4w,0)の点をPとするとき、 線分OPの角度を30度ずつ増やしながら90度になるまで描画しています。

[B]は、繰返し処理を行う値を指定しています。 点P(2w,0)に対して、 線分OPを青色にして15度、45度、75度傾けています。

[C]は、単に繰返し回数を指定しています。 点P(3w,0)に対して、線分OPを緑色にして20度ずつ傾けています。

[D]は、点Pを(dir(1)*4w,0)として、 原点Oと次々に30度ずつ方向を変えながら結んでいっています。 「dir(t)」はt度方向の単位ベクトルなので、 「dir(t)*4w」は点Pを(4w,0)とするとき、OPをt度だけ回転した点です。 \(\small t=1, 31, 61, 91\) のときの回転行列をかけると、 (4w,0)の点はそれぞれ (3.9993w,0.0698h), (3.4287w,2.0601h), (1.9392w,3.4985h), (-0.0698w,3.9994h)に移ります。 これらの点を赤色で結んでいます。


■if-else-fi文
条件文として「if-else-fi」を利用することができます。 下記は、MePoTeXのマニュアルの図46(p.37)を改変したものです。
  • \begin{MPpic}<1cm>(4,4) \sendMP{ for t=0 step 1 until 4:  if odd t:   for s=1 step 2 until 4:    xfill(if odd ((s+1)/2):    Yellow else:blue fi)    circle((s*w,t*h),w);   endfor  else :   for s=0 step 2 until 4:   xfill(if odd (s/2):green    else: red fi)    circle((s*w,t*h),w);   endfor  fi; endfor; } \end{MPpic}
if文の書式は、「if (条件): (処理1) else: (処理2) fi;」の形です。 「elseif」を使用する場合は、 「if (条件1): (処理1) elseif (条件2): (処理2) fi;」とします。 以下では、単位を(w,h)として単位は省略して説明します。

ここでは、「xfill(色) circle(中心, 半径)」により、 格子点を中心とする半径1の円内が塗りつぶされています。 縦(t)と横(s)の座標の値を1ずつ増やしながら、まず 「odd t」によりtが奇数かどうかを判定しています。 奇数のときは「true」、偶数のときは「false」が返されます。 偶数かどうかの判定は「even t」です。

縦(t)が奇数のときは、さらに横(s)に対して(s+1)/2の偶奇を判定し、 奇数のときは黄色、偶数のときは青色の円(中心(s,t)、半径は1)で塗りつぶします。 縦(t)が偶数のときは、横(s)に対して s/2の偶奇を判定し、 奇数のときは緑色、偶数のときは赤色の円で塗りつぶします。

具体的に確かめると、(s,t)は次の順になります。

  1. \(\small t=0\) の偶数ときは
    (0,0), (2,0), (4,0)の順に
    赤、緑、赤。
  2. \(\small t=1\) の奇数のとき
    (1,1), (3,1)の順に黄、青。
  3. \(\small t=2\) の偶数とき
    (0,2), (2,2), (4,2)の順に
    赤、緑、赤。
  4. \(\small t=3\) の奇数のとき
    (1,3), (3,3)の順に黄、青。
  5. \(\small t=4\) の偶数とき
    (0,4), (2,4), (4,4)の順に
    赤、緑、赤。

▲戻る(トップメニューマップ)

copyright