ウィキと言うものを使ってみようということで、まずは作るだけ作ってみるのです。



正多角形とその対角線


%!TEX TS-program = MetaPost
beginfig(0);
	u=6cm;
	n=17;
	pair a[]; a[0]=(u,0);
	path p; p=a[0];
	for i=1 upto (n-1):
		a[i]=(cosd(360*i/n),sind(360*i/n))*u;
		p:=p--a[i];
	endfor
	pickup pencircle scaled 0.5pt;
	for i=0 upto (n-1):
		for j=i upto (n-1):
			draw a[i]--a[j];
		endfor
	endfor
	pickup pencircle scaled 1pt;
	draw p--cycle;
endfig;
end.

出力結果

矢印


%!TEX TS-program = MetaPost
	numeric u;
	u=1.0cm;
	path p;
	p=(0,1)--(10.2,1)--(10,2)--(14,0)--(10,-2)--(10.2,-1)--(0,-1)--cycle;

beginfig(0);

	fill p scaled u withcolor (.3,1,.5);
	pickup pencircle scaled 5pt;
	draw p scaled u withcolor (.2,.7,.3);

endfig;
end.

出力結果

関数のグラフ


%!TEX TS-program = MetaPost

	u=2.5cm;

beginfig(0);

	% グラフを描画する関数を定義(パラメタ曲線として)
	def myfunction(expr t) := (t,t*mexp(-t*t*128)) enddef;

	% グラフを表す path 変数を設定
	path graph;
	graph = myfunction(-3)
	for i=-29 upto 30:
	..myfunction(i/10)
	endfor;
	
	% グラフを描画
	draw graph scaled u;
	
	% 座標軸を描画
	drawarrow ((-3.2,0)--(3.2,0)) scaled u;
	drawarrow ((0,-1.2)--(0,1.2)) scaled u;
	label.bot (btex $x$ etex, ((3.2,0)*u));
	label.rt (btex $y$ etex, ((0,1.2)*u));
	label.lrt ("O", (0,0));

	% 極大値、極小値
	draw ((1,0)--myfunction(1)) scaled u dashed evenly scaled .8;
	label.bot (btex $1$ etex, ((1,0)*u));
	draw ((-1,0)--myfunction(-1)) scaled u dashed evenly scaled .8;
	label.top (btex $-1$ etex, ((-1,0)*u));
	draw ((0,ypart myfunction(1))--myfunction(1)) scaled u dashed evenly scaled .8;
	label.lft ("Maximal", (0, ypart myfunction(1)*u));
	draw ((0,ypart myfunction(-1))--myfunction(-1)) scaled u dashed evenly scaled .8;
	label.rt ("Minimal", (0, ypart myfunction(-1)*u));
	
	% 関数の式を表示
	label (btex {$y=xe^{-x^2/2}$} etex, ((2.5,1)*u));

endfig;
	
end.

出力結果

※ myfunction の定義を修正した(exp(-t*t/2) → mexp(-t*t*128))。

関数のグラフ・汎用版


%!TEX TS-program = nv-MetaPost
outputtemplate := "%j-%c.mps";

% boolean variables for "parametric" macro (true = cubic bezier, false = line)
boolean curve.join, curve.join.line;
curve.join = true; curve.join.line = false;

% macro for parametric curves: x should be used as a parameter
vardef parametric@#(text t)(expr a,b)(expr n) :=
	save f;
	vardef f(expr x) := (t) enddef;
	f(a) for i=1 upto n: if curve.join@#:.. else:-- fi f((i/n)[a,b]) endfor
enddef;

% macro for graphs of designated function: x should be used as a variable
vardef graph@#(text t)(expr a,b)(expr n) := parametric@#(x,t)(a,b)(n) enddef;

beginfig(1);

u=100;

drawarrow ( (-2.1,0)--(2.1,0) ) scaled u;
drawarrow ( (0,-1.2)--(0,1.2) ) scaled u;

pickup pencircle scaled 1;

draw parametric(cosd(270x),sind(180x))(0,4)(50) scaled .5u withcmykcolor (.5,0,1,0);
draw parametric.line(cosd(270x),sind(180x))(0,4)(12) scaled .5u withcmykcolor (1,0,.5,0);

draw graph(2x/(1+x*x))(-2,2)(50) scaled u;
draw graph.line(2x/(1+x*x))(-2,2)(5) scaled u withcmykcolor (0,.5,1,0);

endfig;

end.

出力結果


定義されたマクロの簡単な説明:

parametric(xの式,xの式)(a,b)(n)
(xの式,xの式) というパラメタ表示を持つ曲線の a≦x≦b の範囲の部分を近似的に表すパス.
区間 [a,b] の n 等分点における点をなめらかにつないだパスなので,n が大きいほど真の曲線に近づく(はず).

graph(xの式)(a,b)(n)
関数 y=(xの式) のグラフの a≦x≦b の範囲の部分を近似的に表すパス.
parametric(x,xの式)(a,b)(n) と同じ意味.

parametric.line(xの式,xの式)(a,b)(n)
graph.line(xの式)(a,b)(n)
n 等分点をなめらかにつなぐのではなく,線分でつないで出来るパス.

フォードの円


%!TEX TS-program = MetaPost

	u=10cm;

	def fordcircle(expr a,c) :=
	(fullcircle scaled (2/(2*c*c)) shifted (a/c,1/(2*c*c))) scaled u
	enddef;
	
	def FordCircles(expr k) :=
	draw fordcircle(0,1); draw fordcircle(1,1);
	clip currentpicture to (0,-u)--(u,-u)--(u,2u)--(0,2u)--cycle;
	begingroup;
	numeric a, n;
	for n=2 upto k:
	for i=1 upto n-1: a:=1;
	for j=2 upto n/2: if (i mod j)**2+(n mod j)**2=0: a:=0; else: fi; endfor;
	if a=1: draw fordcircle(i,n); fi;
	endfor endfor
	endgroup;
	draw (0,0)--(u,0);
	draw ((-.01,-.01)--(1.01,-.01)--(1.01,1.01)--(-.01,1.01)--cycle) scaled u withcolor white;
	enddef;

beginfig(0);

	pickup pencircle scaled .4bp;

	FordCircles(7);
	
endfig;
	
end.

出力結果

フォードの円についてはWikipediaを参照。

あみだくじ


%!TEX TS-program = MetaPost
	UnitLength=1.0cm;
	SkipRadius=0.20;
	VerticalStretch=1;
	HorizontalStretch=1;
	LetterOffset=0.4;
	string FontFamily;
	FontFamily="cmssbx10"; % Computer Modern Sans Serif, 10pt, Bold
	FontScale=1.5;
	Level=1;

	TracerLevel=0;
	TracerCurrentPosition=1;
	TracerPreviousPosition=1;
	color TracerColor;
	TracerColor=green;

	def unitized = scaled UnitLength enddef;
	def nextlevel = Level:=Level+1; enddef;
	def level expr l = Level:=l; enddef;

	def BasicHorizontalEdge(expr n) =
	if n>0:
	((0,0)--
	for k=1 upto n-1:
	((-1,0)..(0,1)..(1,0)) scaled SkipRadius shifted(k*HorizontalStretch,0)--
	endfor
	(n*HorizontalStretch,0))
	else:
	((0,0)--
	for k=-1 downto n+1:
	((1,0)..(0,1)..(-1,0)) scaled SkipRadius shifted(k*HorizontalStretch,0)--
	endfor
	(n*HorizontalStretch,0))
	fi
	enddef;
	
	def HorizontalEdge(expr a,b)(expr l) =
	BasicHorizontalEdge(b-a) shifted (a*HorizontalStretch,-l*VerticalStretch)
	enddef;
	
	def tp(expr a,b) =
	draw HorizontalEdge(a,b)(Level) unitized;
	enddef;
	
	def tatebou(expr width, height)(expr bars) =
	pickup pencircle scaled 1.5pt;
	for i=1 upto width:
	draw ((0,0)--(0,-height)) shifted(i*HorizontalStretch,0) unitized;
	for j=-1,1:
	label (decimal(i) infont FontFamily scaled FontScale,
	((i*HorizontalStretch,j*(.5height+LetterOffset)-.5height) unitized));
	endfor
	endfor
	VerticalStretch:=height/(1+bars);
	Level:=1;
	enddef;

	def TraceAmida(expr a)(expr b) =
	TracerLevel:=0;
	TracerCurrentPosition:=a;
	TracerColor:= b;
	enddef;	

	def GoDown =
	draw ((TracerCurrentPosition,TracerLevel)--(TracerCurrentPosition,TracerLevel+1))
	yscaled -VerticalStretch unitized withcolor TracerColor;
	TracerLevel:=TracerLevel+1;
	enddef;

	def PassDown =
	GoDown;
	draw ((-1,0)..(0,1)..(1,0)) scaled SkipRadius
	shifted (TracerCurrentPosition*HorizontalStretch,-TracerLevel*VerticalStretch) unitized;
	enddef;

	def MoveTo expr destination =
	GoDown;
	TracerPreviousPosition:=TracerCurrentPosition;
	TracerCurrentPosition:=destination;
	draw HorizontalEdge(TracerPreviousPosition,TracerCurrentPosition)(TracerLevel)
	unitized withcolor TracerColor;
	enddef;

beginfig(0);

	tatebou(7,6)(6);
	tp(1,2); tp(3,4); tp(5,7); nextlevel;
	tp(2,5); nextlevel;
	tp(1,3); tp(4,6); nextlevel;
	tp(2,7); nextlevel;
	tp(1,2); tp(3,6); nextlevel;
	tp(1,3); tp(4,5); tp(6,7); nextlevel;
	
	TraceAmida(3,(.3,.8,.1));
	MoveTo 4; PassDown; MoveTo 6; PassDown; MoveTo 3; MoveTo 1; GoDown;

	draw bbox currentpicture withcolor white;
endfig;

end.

出力結果

定義されたマクロの使い方に関する簡単な説明:
tatebou(a,b)(c):長さが b 単位であるような a 本の縦棒からなるあみだくじを用意、横棒は c 段に書き込む予定
tp(a,b):a と b の数字が振られた縦棒の間の互換を描き込む
nextlevel:描画する段を次の段に移動
TraceAmida(a,b):描画済みのあみだくじを a から出発してなぞる線を色 b で描く準備
MoveTo a:現在位置から 1 段下った後、a 番の棒に移動
GoDown:単に 1 段下る
PassDown:互換の飛び越え部分の下をくぐって 1 段下る

イラストのサンプル(クマ?)


%!TEX TS-program = MetaPost

	u=1.0cm;
	
	def ear_circle expr s :=
	buildcycle(((-1,0){dir 90}..(0,1)) scaled 1.5u,fullcircle scaled s shifted (-1.2u,u))
	enddef;
	
	path left_ear, left_inner_ear, right_ear, right_inner_ear,
	face, left_eye, right_eye, nose, mouth, around_mouth;

	right_ear = ear_circle 1.5u;
	right_inner_ear = ear_circle 1.2u;
	left_ear = right_ear reflectedabout((0,0),(0,1));
	left_inner_ear = right_inner_ear reflectedabout((0,0),(0,1));
	face = fullcircle scaled 3u;
	around_mouth =
	buildcycle((-.9,-1.2)..(0,-.5)..(.9,-1.2),(.9,-1.2)..(0,-1.5)..(-.9.,-1.2)) scaled u;
	left_eye = (fullcircle shifted (-4,-.5)) scaled .2u;
	right_eye = left_eye reflectedabout((0,0),(0,1));
	nose = ((0,-1.5){dir 130}..(-1.2,.5){dir 15}..{dir -15}(1.2,.5)
	..{dir 230}cycle) scaled .1u shifted (0,-.5u);
	mouth = ((-.3,-.35)..(0,-.3)..(.3,-.35)..(0,-.8)..cycle) scaled u shifted (0,-.5u);
	
	def rndcolor := (uniformdeviate(1),uniformdeviate(1),uniformdeviate(1)) enddef;

	def kuma(expr a,b,c,d,e,f,g) := image(
	fill left_ear withcolor a;
	fill right_ear withcolor a;
	fill left_inner_ear withcolor b;
	fill right_inner_ear withcolor b;
	fill face withcolor c;
	fill around_mouth withcolor d;
	fill left_eye withcolor e;
	fill right_eye withcolor e;
	fill nose withcolor f;
	fill mouth withcolor g;
	) enddef;
	
beginfig(0);

	for i=0 upto 4: for j=0 upto 4:
	draw kuma(rndcolor,rndcolor,rndcolor,rndcolor,rndcolor,rndcolor,rndcolor)
	shifted ((i,j)*4u);
	endfor endfor

endfig;

end.

出力結果

※ wiki上での表示が横にはみ出さないようにやや不自然なところで行を折り返している箇所があるが、コンパイルする上で支障はない。

アフターダーク・クロック


%!TEX TS-program = MetaPost

u=2cm;
def tv(expr a) := (sind(a),cosd(a))*u enddef;

def adclock(expr h, m) := image(
begingroup;
pickup defaultpen;
draw fullcircle scaled 2.45u;
for i=0 upto 60: drawdot tv(6i); endfor
pickup pencircle scaled 2;
for i=1 upto 12:
  drawdot tv(30i);
  label(decimal(i) infont "cmtt10",1.11tv(30i));
endfor
pickup pencircle scaled 4;
drawdot origin;
pickup defaultpen;
z0=.6tv(30h+.5m);
z1-z0=.11z0 rotated 90;
z2-z0=.15z0 rotated 180;
z3-z0=.11z0 rotated 270;
z4-z0=.2z0 rotated 0;
filldraw z1..z2..z3..{z0}z4{-z0}..cycle;
draw origin--z0;
draw origin--1.12tv(6m);
label (if 60h+m<720:"am" else:"pm" fi infont "cmtt12" scaled 1.5, (0,-1.45u));
draw bbox currentpicture withcolor white;
endgroup;
)
enddef;

beginfig(0);
draw adclock(23,56);
endfig;
end.

出力結果

※ 村上春樹「アフターダーク」で、物語内部時刻を示す挿し絵として登場する時計を模したもの。

ディンキン図形


u = 1cm; % unit length
Rv = .15u; % radius of a vertex
Dv = 1.5u; % distance between vertices
Wah = .3u; % arrowhead width
Ps = .03u; % pen size

def suitably := scaled (u/.8cm) enddef; % for font scaling in label

boolean classic_arrow;
%classic_arrow = true;
classic_arrow = false;

path ArrowHead;
ArrowHead = (-Wah,Rv)--(0,0)--(-Wah,-Rv);

picture Vertex, DiArrow, TriArrow;
Vertex := image(
  pickup pencircle scaled Ps;
  unfill fullcircle scaled 2Rv;
  draw fullcircle scaled 2Rv;
);
def MultipleArrow(expr m,a,b) := image(
  begingroup; save p, s; path p;
  for i=0 upto m-1:
    s:=(a+b*i)*Rv; p:=(0,s)--(Dv,s);
    pickup pencircle scaled Ps;
    draw 
    if classic_arrow: p
    else: (0,s)--(p intersectionpoint ArrowHead shifted (Dv-Rv,0))
    fi;
  endfor
  draw ArrowHead shifted (if classic_arrow:.5Dv+.5Wah else:Dv-Rv fi,0);
  endgroup;)
enddef;
DiArrow = MultipleArrow(2,-.4,.8);
TriArrow = MultipleArrow(3,-.6,.6);

def vertex(expr a,b) := draw Vertex shifted ((a,b)*Dv) enddef;
def vertices(expr a) := for i=1 upto a: vertex(i,0); endfor enddef;
def simple_edge(expr a,b) :=
  pickup pencircle scaled Ps;
  draw (Rv+a*Dv,0)--(b*Dv-Rv,0);
enddef;
def double_edge(expr a,b) :=
  draw DiArrow if a>b: rotated 180 fi shifted ((a,0)*Dv);
enddef;
def triple_edge(expr a,b) :=
  draw TriArrow if a>b: rotated 180 fi shifted ((a,0)*Dv);
enddef;

def Dynkin_A(expr n) := image(
  simple_edge(1,n); vertices(n);
) enddef;

def Dynkin_B(expr n) := image(
  simple_edge(1,n-1); double_edge(n-1,n); vertices(n);
) enddef;

def Dynkin_C(expr n) := image(
  simple_edge(1,n-1); double_edge(n,n-1); vertices(n);
) enddef;

def Dynkin_D(expr n) := image(
  for i=0 upto 1:
  draw ((n-2)*Dv,0)--((n-1)*Dv,(i-.5)*Dv); vertex(n-1,i-.5);
  endfor
  simple_edge(1,n-2); vertices(n-2);
) enddef;

def Dynkin_E(expr n) := image(
  draw ((n-3)*Dv,-Rv)--((n-3)*Dv,Rv-Dv); vertex(n-3,-1);
  simple_edge(1,n-1); vertices(n-1);
) enddef;

def Dynkin_F(expr n) := image(if n=4:
  simple_edge(1,2); double_edge(2,3); simple_edge(3,4); vertices(4);
fi) enddef;

def Dynkin_G(expr n) := image(if n=2:
  triple_edge(1,2); vertices(2);
fi) enddef;

beginfig(1); % Dynkin diagrams

draw Dynkin_A(7);
draw Dynkin_B(7) shifted (0,-2Dv);
draw Dynkin_C(7) shifted (0,-4Dv);
draw Dynkin_D(8) shifted (0,-6Dv);
draw Dynkin_E(6) shifted (Dv,-8Dv);
draw Dynkin_E(7) shifted (.5Dv,-10Dv);
draw Dynkin_E(8) shifted (0,-12Dv);
draw Dynkin_F(4) shifted (1.5Dv,-14Dv);
draw Dynkin_G(2) shifted (2.5Dv,-16Dv);

label(btex $A_7$ etex suitably, (0,0));
label(btex $B_7$ etex suitably, (0,-2Dv));
label(btex $C_7$ etex suitably, (0,-4Dv));
label(btex $D_8$ etex suitably, (0,-6Dv));
label(btex $E_6$ etex suitably, (0,-8Dv));
label(btex $E_7$ etex suitably, (0,-10Dv));
label(btex $E_8$ etex suitably, (0,-12Dv));
label(btex $F_4$ etex suitably, (0,-14Dv));
label(btex $G_2$ etex suitably, (0,-16Dv));

endfig;

end.

出力結果

※ ディンキン図形(Dynkin diagram)については…さしあたり Wikipedia (English) とか Wolfram MathWorld とかを参照、ということで。
※ 途中にあるブール値 classic_arrow を true にすると、二重・三重の矢印の出力がちょいと変化します。

計るだけダイエット・記録用紙


自分にとっても「あると便利なもの」であるような、実用的な例として作ってみた。
prologue:=1;

UPPER_BOUND = 1;
LOWER_BOUND = -2;
DAYS = 14;

ux=1.7cm;
uy=3.6cm;
x_margin=.3cm;
weight_box_width=1.8cm;
weight_box_height=1.0cm;
memo_box_width=ux;
memo_box_height=4.5cm;
memo_box_radius=1mm;
memo_box_margin=.5mm;
period_box_width=2.5cm;
period_box_height=1.0cm;
period_box_distance=ux;

color color_of_sun,color_of_moon,
  letter_color_of_days,background_color[],
  color_of_weight_box,color_of_current_weight_box,
  color_of_horizontal_lines,color_of_vertical_lines;
color_of_sun = red;
color_of_moon = red+green;
letter_color_of_days = red+.5green;
background_color[0] = white; % even days
background_color[1] = red+.9green+.9blue; % odd days
color_of_weight_box = .7white;
color_of_current_weight_box = .4white;
color_of_horizontal_lines = .4white;
color_of_vertical_lines = .3white;

def ovalbox(expr width,height,radius,margin) :=
  (margin+radius,-margin)
  --(width-margin-radius,-margin){right}
  ..(width-margin,-margin-radius)
  --(width-margin,margin+radius-height){down}
  ..(width-margin-radius,margin-height)
  --(margin+radius,margin-height){left}
  ..(margin,margin+radius-height)
  --(margin,-margin-radius){up}
  ..cycle
enddef;

ims=.1cm;
picture sun,moon;
sun = image(
  fill fullcircle scaled 2ims withcolor color_of_sun;
  draw fullcircle scaled 2ims;
  for i=0 upto 7:
    draw ((1.4,0)--(1.8,0)) scaled ims rotated (45i);
  endfor);
moon = image(
  begingroup; save t,s,p,q; path p,q; t=130; s=1.4ims;
  p=((cosd(t),sind(t))..(0,1){right}..(1,0)..{left}(0,-1)..(cosd(t),-sind(t))) scaled s;
  q=((cosd(t),-sind(t))..((1+cosd(t))/2,0)..(cosd(t),sind(t))) scaled s;
  fill p..q..cycle withcolor color_of_moon; draw p..q;
endgroup;);

outputtemplate := "hakarudake_sheet.mps";

beginfig(1);
for i=0 upto DAYS-1:
  draw ovalbox(memo_box_width,memo_box_height,memo_box_radius,memo_box_margin)
  shifted (i*ux,LOWER_BOUND*uy-10mm) withcolor .2white;
  label("memo" infont "pagk" scaled .6,((i+.5)*ux,LOWER_BOUND*uy-12mm));
  filldraw unitsquare xscaled ux yscaled (uy*(UPPER_BOUND-LOWER_BOUND))
    shifted (ux*i,uy*LOWER_BOUND) withcolor background_color[i mod 2];
  label(decimal(i+1) infont "pplb" scaled 1.6, (ux*(i+.5),uy*LOWER_BOUND-7mm))
    withcolor letter_color_of_days;
  draw sun shifted (ux*(i+.25),uy*(LOWER_BOUND)-3mm);
  draw moon shifted (ux*(i+.75),uy*(LOWER_BOUND)-3mm);
endfor
pickup pencircle scaled .3pt;
for i=1 upto 2DAYS:
  draw ((0,LOWER_BOUND*uy)--(0,UPPER_BOUND*uy))
    shifted (ux*(i-.5)/2,0) dashed evenly scaled .5
      withcolor color_of_vertical_lines;
endfor
s=0;
for i=LOWER_BOUND step .05 until UPPER_BOUND:
  s:=1-s;
  pickup pencircle scaled if s=0: .2pt else: .4pt fi;
  draw (0,uy*i)--(DAYS*ux,uy*i)
    if s=0: dashed evenly scaled .5 fi withcolor color_of_horizontal_lines;
endfor
pickup pencircle scaled .6pt;
for i=LOWER_BOUND upto UPPER_BOUND-1:
  draw (0,uy*(i+.5))--(DAYS*ux,uy*(i+.5));
endfor
for i=LOWER_BOUND upto UPPER_BOUND:
  draw (0,uy*i)--(DAYS*ux,uy*i) withpen pencircle scaled 1.2pt;
  draw ovalbox(weight_box_width,weight_box_height,1mm,0)
    withpen pencircle scaled 2pt
      shifted (-(x_margin+weight_box_width),i*uy+weight_box_height/2)
        withcolor if i=0: color_of_current_weight_box else: color_of_weight_box fi;
  label.ulft("kg" infont "pagk", (-x_margin,i*uy-weight_box_height/2));
endfor
draw image(begingroup;
  save p,w,h,d; path p;
  w=period_box_width; h=period_box_height; d=period_box_distance;
  p=ovalbox(w,h,1mm,0);
  pickup pencircle scaled 1pt;
  draw p shifted (-(2w+d),h) withcolor .5white;
  draw p shifted (-w,h) withcolor .5white;
  label.lrt("From:" infont "pagk" scaled .6, (-(2w+d),h));
  label.lrt("To:" infont "pagk" scaled .6, (-w,h));
  draw ((-4,-1){dir 60}..(-1,1)..(0,0)..(1,-1)..{dir 60}(4,1))
    scaled 1mm shifted (-w-d/2,h/2);
endgroup;) shifted (DAYS*ux-2mm,UPPER_BOUND*uy+2mm);
endfig;

end.

出力結果:計るだけダイエット・記録用紙(PNG) / 計るだけダイエット・記録用紙(PDF)

※ ちょっと小さいけれど、1ヶ月用(PDF)を作ってみました。

サクラ的な何か


beginfig(1);
numeric R,r; R=3cm;r=1.6cm; path p;
z0=r*(cosd(-18),sind(-18)); z3=R*(0,1);
z2=z0 rotated 72; z4=z0 rotated 144;
z4-z1=whatever*(z4-z0); z1=whatever*(z0+z2);
z5=z1 reflectedabout(origin,z3);
z31=z3+(.05R,0); z32=z3-(0,.05R); z33=z3-(.05R,0);
p=z1..z2..{dir 140}(z31--z32--z33){dir 220}..z4..z5;
pickup pencircle scaled 5bp;
for i=0 upto 4:
  draw subpath (0,4.85) of p rotated 72i;
  draw subpath (5.25,6) of p rotated 72i;
endfor
endfig;
end.

出力結果

ドーナツ


def dohnut(expr n,s):= image(
begingroup; save d,p,q,hole;
path p,q; picture hole;
hole = image(
  begingroup; save p,q,a,b,u,v; path p,q;
  a=.2s; b=.1s; u=-30; v=210;
  p=(for i=u step 5 until v+1: (a*cosd(i),b*sind(i)) if i<v:..fi endfor) shifted (0,-.03s);
  q=p reflectedabout(origin,(1,0));
  draw q; draw subpath(10,38) of p;
endgroup;);
d=.5s;
p=(n*d,0){up}..((n-1)*d,.4s)
for i=1 upto n-1:
  ..((n-2i)*d,.3s)..((n-2i-1)*d,.4s)
endfor
..{down}(-n*d,0);
draw p; draw p rotated 180;
for i=1 upto n: draw hole shifted ((n+1-2i)*d,0); endfor
endgroup;)
enddef;

beginfig(1);
draw dohnut(1,3cm) rotated -45;
draw dohnut(2,2cm) shifted (4cm,0);
draw dohnut(3,1cm) rotated 45 shifted (8cm,0);
draw dohnut(7,1.5cm) shifted (4cm,-2.5cm);
endfig;

出力結果

三角形の4つの心


numeric unit_length;
unit_length = 2cm;
letter_scale = 1.2;
def lovely := withpen pencircle scaled 1bp enddef;

def centers(expr p,q,r) := image(
begingroup;
save a,v,w,f,cl_cog,cl_ic,cl_oc,cl_cc,i,R;
numeric a[]; pair v[],w[],f[]; color cl_cog,cl_ic,cl_oc,cl_cc;
a0=p; a1=q; a2=r;
for i=0 upto 2: a[i]:=a[i]*unit_length; endfor % 長さを単位長倍する
pickup pencircle scaled 2bp;

v0 = (0,0); v1 = (a2,0);
v2 = ((halfcircle scaled 2a0 shifted v1) intersectionpoint (halfcircle scaled 2a1 shifted v0));
draw v0--v1--v2--cycle;
w0=(v1+v2)/2; w1=(v2+v0)/2; w2=(v0+v1)/2;
% 重心
pair cog; % Center Of Gravity
cog=(v0+v1+v2)/3;
cl_cog=red+.4green;
for i=0 upto 2: draw v[i]--w[i] lovely withcolor cl_cog+.4white; endfor
% 内心と内接円
pair ic; % Inner Center
ic-v0=whatever*(unitvector(v1-v0)+unitvector(v2-v0));
ic-v1=whatever*(unitvector(v0-v1)+unitvector(v2-v1));
cl_ic=red;
draw fullcircle scaled 2ypart ic shifted ic withcolor cl_ic;
for i=0 upto 2: draw v[i]--ic lovely withcolor cl_ic+.5white; endfor
% 垂心
pair oc; % OrthoCenter
oc-v0 = whatever*((v1-v2) rotated 90);
oc-v1 = whatever*((v2-v0) rotated 90);
cl_oc=blue;
f2-v0=whatever*(v1-v0);
f0-v1=whatever*(v2-v1);
f1-v2=whatever*(v0-v2);
f2-v2=whatever*(oc-v2);
f0-v0=whatever*(oc-v0);
f1-v1=whatever*(oc-v1);
for i=0 upto 2: draw f[i]--v[i]--oc lovely withcolor cl_oc+.5white; endfor
% 外心と外接円
pair cc; % CircumCenter
(v0+v1)/2-cc = whatever*((v0-v1) rotated 90);
(v1+v2)/2-cc = whatever*((v1-v2) rotated 90);
cl_cc=.75green;
R=arclength(cc--v0);
draw fullcircle scaled 2R shifted cc withcolor cl_cc;
for i=0 upto 2: draw ((-R*unitvector(cc-w[i]))--(R*unitvector(cc-w[i])))
  shifted cc lovely withcolor cl_cc+.5white; endfor
% 重心,垂心,外心は一直線上にある。
draw oc--cog--cc withcolor .7white;
% 点とラベル
fill fullcircle scaled 5bp shifted cog withcolor cl_cog;
fill fullcircle scaled 5bp shifted ic withcolor cl_ic;
fill fullcircle scaled 5bp shifted oc withcolor cl_oc;
fill fullcircle scaled 5bp shifted cc withcolor cl_cc;
label.rt("center of gravity" infont "pagk" scaled letter_scale,cog) withcolor cl_cog;
label.rt("inner center" infont "pagk" scaled letter_scale,ic) withcolor cl_ic;
label.rt("orthocenter" infont "pagk" scaled letter_scale,oc) withcolor cl_oc;
label.rt("circumcenter" infont "pagk" scaled letter_scale,cc) withcolor cl_cc;
endgroup;)
enddef;

beginfig(1);
draw centers(7,6,5);
endfig;

end.

出力結果

白抜き文字


beginfig(0);
path p; picture q; string s,S,F;
F="cmssbx10";
S="One for all, all for one.";
x=0;

for n=1 upto length S:
  s:=substring (n-1,n) of S;
  if s=",": s:="comma";
  elseif s=".": s:="period"; fi
  if s=" ": x:=x+10; else:
    q := glyph s of F scaled .05;
    rightmost:=xpart (urcorner q);
    leftmost:=xpart (ulcorner q);
    for item within q:
      p := pathpart item;
      draw p shifted (x,0) withpen pencircle scaled 1.2;
    endfor
    x:=x+(rightmost-leftmost)+2 if s="f":-3.8 fi;
  fi
endfor
endfig;

end.

MetaPost による文字(列)の変形のための練習。
文字列を引数に取るマクロにしようと試みたのだけれど、
同一 figure 内で同じマクロを2回使うと原因不明のエラーが出る、
という症状に悩まされて断念。
う〜ん、何故だろう?

出力結果

星型のパス


beginfig(1);
n=5; path star;
for i=0 upto n-1:
  z[i]=(0,1cm) rotated (360*i/n);
endfor
star = for i=0 upto n-1:
  z[i]--((z[(i-1) mod n]--z[(i+1) mod n]) intersectionpoint (z[i]--z[(i+2) mod n]))--
endfor cycle;
draw star;
endfig;

def star_shaped_path(expr n,R,r):=
for i=0 upto n-1:
  (R*(sind(360i/n),cosd(360i/n)))--(r*(sind(360(i+.5)/n),cosd(360(i+.5)/n)))--
endfor cycle
enddef;

def fillwithboundary(expr p,b,d):=
fill p withcolor d;
draw p withcolor b;
enddef;

beginfig(2);
fillwithboundary(star_shaped_path(30,1cm,0.9cm),.5red,red);
label(decimal(28) infont "cmssbx10" scaled 3,origin) withcolor white;
endfig;

星(figure(1))と星型のパスを使ったバッジ(figure(2))。

出力結果:スターバッジ

cutbeforeとcutafterの使用例


beginfig(1);
z1=(0,0); z2=(100,0); z=(50,30);
path p,p[];
p=z1..z..z2;
p1=fullcircle scaled 10 shifted z1;
p2=fullcircle scaled 10 shifted z2;
drawarrow (p cutbefore p1) cutafter p2;
draw p1;
draw p2;
endfig;

「膨らみの錯視」


def unitbox:=unitsquare shifted -center unitsquare enddef;

beginfig(1);
n=7; u=20;

for i=-n upto n:
for j=-n upto n:
fill unitbox scaled u shifted (i*u,j*u) withcolor if ((i+j) mod 2 = 0): black else: white fi;
endfor
endfor

for i=1 upto n-1:
fill unitbox scaled .3u shifted ((i-.3)*u,.3u) withcolor if (i mod 2 = 1): black else: white fi;
fill unitbox scaled .3u shifted ((i-.3)*u,-.3u) withcolor if (i mod 2 = 1): black else: white fi;

fill unitbox scaled .3u shifted (.3u,(i-.3)*u) withcolor if (i mod 2 = 1): black else: white fi;
fill unitbox scaled .3u shifted (-.3u,(i-.3)*u) withcolor if (i mod 2 = 1): black else: white fi;

fill unitbox scaled .3u shifted ((-i+.3)*u,.3u) withcolor if (i mod 2 = 1): black else: white fi;
fill unitbox scaled .3u shifted ((-i+.3)*u,-.3u) withcolor if (i mod 2 = 1): black else: white fi;

fill unitbox scaled .3u shifted (.3u,(-i+.3)*u) withcolor if (i mod 2 = 1): black else: white fi;
fill unitbox scaled .3u shifted (-.3u,(-i+.3)*u) withcolor if (i mod 2 = 1): black else: white fi;
endfor

for i=1 upto n:
for j=1 upto n:
if (i*i+j*j<(n-.8)*(n-.8)):
fill unitbox scaled .3u shifted ((i+.3)*u,(j-.3)*u) withcolor if ((i+j) mod 2 = 1): black else: white fi;
fill unitbox scaled .3u shifted ((i-.3)*u,(j+.3)*u) withcolor if ((i+j) mod 2 = 1): black else: white fi;

fill unitbox scaled .3u shifted ((-i+.3)*u,(-j-.3)*u) withcolor if ((i+j) mod 2 = 1): black else: white fi;
fill unitbox scaled .3u shifted ((-i-.3)*u,(-j+.3)*u) withcolor if ((i+j) mod 2 = 1): black else: white fi;

fill unitbox scaled .3u shifted ((i+.3)*u,(-j+.3)*u) withcolor if ((i+j) mod 2 = 1): black else: white fi;
fill unitbox scaled .3u shifted ((i-.3)*u,(-j-.3)*u) withcolor if ((i+j) mod 2 = 1): black else: white fi;

fill unitbox scaled .3u shifted ((-i+.3)*u,(j+.3)*u) withcolor if ((i+j) mod 2 = 1): black else: white fi;
fill unitbox scaled .3u shifted ((-i-.3)*u,(j-.3)*u) withcolor if ((i+j) mod 2 = 1): black else: white fi;
fi
endfor
endfor

endfig;
北岡明佳の錯視のページ にある「膨らみの錯視」を生成する。
長い間更新していなかったので、画面下部に表示されるアラートを消すために追加してみました。

このページへのコメント

5BTvmN <a href="http://xsdynqtmztfl.com/">xsdynqtmztfl</a>, [url=http://wwzhoizjlwmn.com/]wwzhoizjlwmn[/url], [link=http://eqqivjzmgjau.com/]eqqivjzmgjau[/link], http://fmzcsiipdyhp.com/

0
Posted by owuszmepw 2013年11月15日(金) 10:03:33 返信

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

×

この広告は60日間更新がないwikiに表示されております。

Wiki内検索

Menu

ここは自由に編集できるエリアです。

メンバーのみ編集できます