Mathematica で
M[x_] := N[Round[Re[x], 2^(-16)], 7]
MPcurve[f_, a_, b_, n_] :=
Module[{u = (b - a)/n, s = "(\n(", p, q, k},
s = StringJoin[
{s,
ToString[M[a]],
",",
ToString[M[f[a]]],
")\n"}
];
Do[
q = a + k u; p = q - u;
s = StringJoin[
{s,
".. controls (",
ToString[M[p + u/3]],
",",
ToString[M[f[p] + u/3 f'[p]]],
") and (",
ToString[M[q - u/3]],
",",
ToString[M[f[q] - u/3 f'[q]]],
")\n"}
];
s = StringJoin[
{s,
"..(",
ToString[M[q]],
",",
ToString[M[f[q]]],
")\n"}
], {k, 1, n}
];
StringJoin[{s, ") scaled 1;"}]
]
ParametricMPcurve[x_, y_, a_, b_, n_] :=
Module[{u = (b - a)/n, s = "(\n", p, q, k},
Do[
q = a + k u; p = q - u;
s = StringJoin[
{s,
"(",
ToString[M[x[p]]],
",",
ToString[M[y[p]]],
")\n"}
];
s =
StringJoin[
{s,
".. controls (",
ToString[M[x[p] + u/3 x'[p]]],
",",
ToString[M[y[p] + u/3 y'[p]]],
") and (",
ToString[M[x[q] - u/3 x'[q]]],
",",
ToString[M[y[q] - u/3 y'[q]]],
")\n.. "
}
], {k, 1, n}
];
s = If[
{x[a], y[a]} == {x[b], y[b]},
StringJoin[{s, "cycle"}],
StringJoin[
{s,
"(",
ToString[M[x[b]]],
",",
ToString[M[y[b]]],
")"}
]
];
StringJoin[{s, "\n) scaled 1;"}]
]
という関数を定義しておく.
前者は関数 f(x) の区間 [a,b] 上でのグラフを近似的に表すパスを生成する.
後者はパラメタ曲線 (x(t), y(t)), a<=t<=b を近似的に表すパスを生成する.
(始点と終点が一致する場合には cycle を返す)
最後の引数 n は区間の分割数.大きいほど正確になる.
※以下の点を変更した:
・変数 k を局所化し忘れていたので,k を局所変数リストに加えた.
・数値を MetaPost 精度に丸める関数 M を定義して MPcurve などに組み込んだ.
たとえば
f[x_] := x^2 Exp[-x]
MPcurve[f, -1, 4, 6]
を実行すると
(
(-1.,2.71828)
.. controls (-0.722222,0.453047) and (-0.444444,0.151316)
..(-0.166667,0.0328156)
.. controls (0.111111,-0.0856851) and (0.388889,0.101416)
..(0.666667,0.228185)
.. controls (0.944444,0.354955) and (1.22222,0.455557)
..(1.5,0.502043)
.. controls (1.77778,0.548528) and (2.05556,0.548909)
..(2.33333,0.527958)
.. controls (2.61111,0.507008) and (2.88889,0.465859)
..(3.16667,0.422609)
.. controls (3.44444,0.37936) and (3.72222,0.333752)
..(4.,0.29305)
) scaled 1;
というパスが出力される.
またたとえば
x[t_] := Cos[3 t]
y[t_] := Sin[2 t]
ParametricMPcurve[x, y, 0, 2 Pi, 8]
を実行すると
(
(1.,0.)
.. controls (1.,0.523599) and (-0.151746,1.)
.. (-0.707107,1.)
.. controls (-1.26247,1.) and (-0.785398,0.523599)
.. (0.,0.)
.. controls (0.785398,-0.523599) and (1.26247,-1.)
.. (0.707107,-1.)
.. controls (0.151746,-1.) and (-1.,-0.523599)
.. (-1.,0.)
.. controls (-1.,0.523599) and (0.151746,1.)
.. (0.707107,1.)
.. controls (1.26247,1.) and (0.785398,0.523599)
.. (0.,0.)
.. controls (-0.785398,-0.523599) and (-1.26247,-1.)
.. (-0.707107,-1.)
.. controls (-0.151746,-1.) and (1.,-0.523599)
.. cycle
) scaled 1;
というパスが出力される.
これらを「形式を選択してコピー>テキスト」によってコピーして,
MetaPost のソースファイルに貼り付けて利用する.