1. Trang chủ
  2. » Cao đẳng - Đại học

Metapost

9 37 0

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 9
Dung lượng 204,93 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Qua ví dụ trên chúng ta thấy: hình vẽ thứ i của file Hinhve.mp được đặt trong dấu ngoặc của lệnh beginfigi, các lệnh vẽ hình được đưa vào sau đó và được phân cách bởi dấu ";".. Các nội d[r]

Trang 1

VẼ HÌNH TRÊN LATEX VỚI METAPOST

ThS Trần Lê Nam - ThS Phan Thị Hiệp

1 Giới thiệu

Trong trình biên dịch LATEX, chúng ta có thể vẽ các hình từ các phần mềm và chèn chúng vào file TEX Tuy nhiên, các ảnh được chèn vào theo phương pháp này đều ở dạng bitmap Điều đó dẫn đến chất lượng bản in thấp, xuất ra file có dung lượng cao Hơn nữa, các phần mềm vẽ hình không cung cấp đủ các công cụ để vẽ các ảnh hình học Thêm vào đó, tính tương thích của mỗi loại ảnh với mỗi loại file xuất của LATEX

là khác nhau

Chính vì các lý do đó, cộng đồng người sử dụng TEX trên thế giới đã viết có gói lệnh, chương trình vẽ hình trực trên LATEX cho chất lượng ảnh cao như: gói pstricks, tikz, chương trình Metapost, Eukleides Trong số đó, chương trình biên dịch Metapost được đánh giá cao bởi những thông thạo về hình học

Metapost là một ngôn ngữ lập trình hình học được phát minh bởi John D Hobby, dựa trên hệ thống Metafont để tạo các fonts chữ đẹp được sáng tạo bởi Donald Knuth

Nó là một trình biên dịch xuất ra các file ảnh vector dưới dạng file *.mps Chúng có thể đưa trực tiếp vào file TEX để dịch ra ảnh *.dvi hay *.pdf

Trong bài báo, chúng tôi giới thiệu cách sử Metapost trên trình soạn thảo Winedt

để vẽ các hình và đồ thị trong chương trình toán học phổ thông Các chức năng mở rộng và nâng cao của Metapost sẽ được chúng tôi giới thiệu vào thời gian tới

2 Vẽ hình với Metapost

2.1 Ví dụ khởi đầu

− Trên Winedt, chúng ta tạo một file mới, đặt tên Hinhve.mp, nhập vào nội dung sau:

prologues:=3;

filenametemplate "%j_%c.mps";

beginfig(1);

pair A, B, C;

numeric u;

u:=1cm;

A:=(0,0);

B:=(3u,0);

C:=(u,2u);

draw A B C cycle;

label.lft(btex $A$ etex, A);

label.rt(btex $B$ etex, B);

label.top(btex $C$ etex, C);

endfig;

end;

Trang 2

Sau đó, chúng ta nhấp tổ hợp phím Ctrl+Shift+M hay biểu tượng trên Winedt

để được file Hinhve_1.mps

− Tiếp theo, chúng ta tạo một file TEX cùng thư mục với file Hinhve.mp, để chèn hình vừa vẽ Đặt tên nó là Vehinh.tex và nhập vào nội dung sau:

\documentclass{minimal}

\usepackage{graphicx}

\begin{document}

\includegraphics{Hinhve_1.mps}

\end{document}

C

Hình 1: Tam giác ABC

Chạy file Vehinh.tex, chúng ta được hình một vẽ tam

giác ABC (Hình 1)

Phân tích cấu trúc file Hinhve.mp, chúng ta thấy nó

gồm 3 phần chính

+ Hai dòng đầu dùng để khai báo tạo ra kiểu file

*.mps

+ Các lệnh vẽ hình nằm giữa hai lệnh \beginfig(1);

và \endfig;

+ Lệnh end; kết thúc file

Qua ví dụ trên chúng ta thấy: hình vẽ thứ i của file Hinhve.mp được đặt trong dấu ngoặc của lệnh beginfig(i), các lệnh vẽ hình được đưa vào sau đó và được phân cách bởi dấu ";" Các nội dung tiếp theo của mục 2, chúng trình các kiểu dữ liệu, lệnh vẽ hình cơ bản và tùy chọn trong Metapost

2.2 Các kiểu dữ liệu trong Metapos

Metapost có 9 kiểu dữ liệu Trong số đó, chúng ta thường dùng các kiểu sau:

- numeric: dữ liệu về đại lượng như chiều dài, độ đo của góc

- pair: tọa độ của một điểm

- path: các đường thẳng hoặc đường cong

- transform: các phép biến hình

2.3 Khai báo một điểm trong Metapost

- Điểm A có tọa độ (x, y) trong mặt phẳng Euclid được khai báo bởi lệnh A=(x,y);

- Điểm A có tọa độ (r, θ) trong hệ tọa độ cực được khai báo bởi lệnh A=r*dir(θ);

top bot rt lft ulft urt

llft ulft

- Để đặt tên cho điểm A, chúng ta dùng lệnh: label.vt("A",A);

Ở đó vt là vị trí của nhãn A Nó nhận 1 trong tám vị trí như hình

bên Chúng ta dùng lệnh dotlabel thay cho lệnh label để thêm

một dấu chấm vào điểm cần đặt tên

Ví dụ: Khai báo điểm A(1, 2) trên mặt phẳng E2 và điểm B có mô-đun bằng 2√

2, góc bằng 450 trên mặt phẳng cực Đặt tên hai điêm đó là A, B

Trang 3

1

2

2

3

3

O

Hình 2: A(1, 2), B(2√

2, 450)

beginfig(3);

numeric u; u=1cm;

pair A,B;

A=(1,2)*u; B=2sqrt(2)*u*dir(45);

draw A withpen pencircle scaled 4bp;

draw B withpen pencircle scaled 4bp;

dotlabel.ulft("A",A);

dotlabel.urt("B",B);

endfig;

2.4 Vẽ đa giác

- Để vẽ đa giác qua các đỉnh A, B, , F ,

chúng ta dùng lệnh draw A B C F cycle

- Độ rộng của nét vẽ được xác đinh bởi lệnh withpen pencircle scaled ?bp;

- Để kẽ nét đức chúng ta dùng lệnh dashed evently

* Lưu ý: Để xác định độ rộng của toàn bộ đường trong hình vẽ, chúng ta dùng lệnh: pickup pencircle scaled ?bp;

Ví dụ: Vẽ hình chữ nhật và tứ diện

C D

Hình 3: Hình chữ nhật

beginfig(4);

pair A[];

numeric u; u=1cm;

pickup pencircle scaled 0.75bp;

A0=(0,0);A1=(4u,0);A2=(4u,3u);A3=(0,3u);

draw A0–A1–A2–A3–cycle;

dotlabel.lft("A",A0);

dotlabel.rt("B",A1);

dotlabel.rt("C",A2);

dotlabel.lft("D",A3);

endfig;

A

B

C D

Hình 4: Tứ diện

beginfig(5);

pair A[]; numeric u; u=1cm;

A0=(-2u,0);A1=(0,-2u);A2=(4u,0);A3=(u,4u);

pickup pencircle scaled 0.5bp;

draw A0–A1–A2–A3–A0;

draw A3–A1;

draw A0–A2 dashed evenly scaled 2;

label.ulft("A",A0);

label.lrt("B",A1);

label.urt("C",A2);

label.urt("D",A3);

endfig;

2.5 Tâm tỉ cự của 2 điểm

Cho trước hai điểm A, B, điểm C thỏa mãn

đẳng thức −→

AC = k−→

AB, k 6= 0, 1 được xác định bởi lệnh: C=k[A,B]

Trang 4

Một điểm bất kì trên đường thẳng (AB) được xác định bởi lệnh whatever[A,B].

Từ đó, giao điểm C của hai đường thẳng (AB) và (EF ) được xác định bởi lệnh C=whatever[A,B]=whatever[E,F]

Ví dụ: Vẽ trọng tâm của một tam giác

A

M

N G

Hình 5: Trong tâm tam giác

beginfig(6);

pair a, b, c, m, n, g;

u:=1.2cm; a:=(u,2u); b:=(0,0); c:=(3u,0);

m:=1/2[b,c]; n:=1/2[a,c];

g:=whatever [a,m] = whatever [b,n];

draw a–b–c–cycle;

draw a–m;draw b–n;

label.top(btex A etex, a);

label.lft(btex B etex, b);

label.rt(btex C etex, c);

label.bot(btex M etex, m);

label.urt(btex N etex, n);

dotlabel.ulft(btex G etex, g);

endfig; 2.6 Vẽ đường tròn

Đường tròn tâm A đường kính 2r > 0 được

vẽ bằng lệnh: draw fullcircle scaled 2r shifted A

Ví dụ: vẽ đường tròn tâm A(1, 2) bán kính AB với B(3, 4)

A

B

-2

-2

-1 -1 1 1

2 2

3 3

4 4

5 5

0

beginfig(7);

pair A,B;

numeric u;

u=1cm;

A=(1cm,2cm); B=(3cm,4cm);

draw fullcircle scaled 2abs(A-B) shifted A;

dotlabel.top(btex A etex, A);

dotlabel.urt(btex B etex, B);

endfig;

2.7 Đường phân giác của một góc

Hàm angle(A-B) cho ra góc giữa trục Ox và véc-tơ −→

AB

A

M

Hình 6: Đường phân giác một góc

Giả sử AM là tia phân giác của góc [BAC

Chúng ta hãy tìm tọa độ của điểm M theo tọa độ

các điểm A, B, C

Theo Hình 6, chúng ta có góc tọa bởi véc-tơ

−−→

M A bằng 1/2 tổng của hai góc angle(B-A) và

angle(C-A) Do đó, tọa độ của điểm M có dạng

A + x.dir12(angle(B-A) + angle(C-A))

Do đó, trong metapost, chúng ta xác định một

điểm M nằm trên tia phân giác của góc [BAC

bởi lệnh:

M=A+whatever*dir(.5angle(B-A)+.5angle(C-A));

Trang 5

2.8 Phép biến hình trên mặt phẳng

Trong Metapost, chúng ta có các phép biến hình trên mặt phẳng sau:

(x; y) shifted (a; b) = (x + a; y + b);

(x; y) rotated (θ): phép quay quanh gốc tọa độ, góc quay θ

(x; y) rotatedaround ((a; b);θ) phép quay quanh điểm (a,b), góc quay θ

(x; y) slanted a = (x + ay; y);

(x; y) scaled a = (ax; ay): phép vị tự tâm O tỉ số a

(x; y) xscaled a = (ax; y);

(x; y) yscaled a = (x; ay);

(x; y) zscaled (a; b) = (ax -by; bx + ay):

Sử dụng các phép biến hình trên, chúng ta dựng được hầu hết các hình phẳng và hình trong không gian thường găp

Ví dụ: Vận dụng phép tịnh tiến và vị tự để dụng mặt cầu

O

beginfig(9);

numeric u; u=1.5cm; path d[];

pickup pencircle scaled 0.5bp;

d0=fullcircle scaled 3u;

d1=halfcircle scaled 0.85u;

d1:=d1 xscaled 3/0.85;

d2:=d1 yscaled -1;

draw d0; draw d2;

draw d1 dashed evenly;

dotlabel.top(btex O etex,(0,0));

endfig;

Ví dụ: Sử dụng phép quay, tịnh tiến để dựng đường

thẳng Euler

H I O C

A 1

C 1 C0

A0

beginfig(10);

numeric u;

pair A,B,C,H,O,I,Ap[],Bp[];

pickup pencircle scaled 0.5bp;

u=1.5cm;A=(-2,0)*u;B=(2,0)*u;C=(-0.5,3)*u;

Ap1=whatever[B,C]

= whatever[A,(B-C) rotated 90 shifted A];

Ap2=whatever[B,A]

=whatever[C,(B-A) rotated 90 shifted C];

H=whatever[A,Ap1]=whatever[C,Ap2];

Bp1=1/2[A,B];Bp2=1/2[B,C];

I=whatever[C,Bp1]=whatever[A,Bp2];

O=whatever[(A-B) rotated 90 +Bp1,Bp1]

=whatever[(B-C) rotated 90 +Bp2,Bp2];

draw fullcircle scaled 2abs(O-A) shifted O;

draw A–B–C–cycle;

draw A–Ap1; draw C–Ap2;

Trang 6

draw C–Bp1;draw A–Bp2;

draw H–I–O–H;

draw O–Bp1; draw O–Bp2;

dotlabel.ulft(btex H etex,H); dotlabel.urt(btex I etex,I);

label.top(btex C etex,C); label.llft(btex A etex,A);

label.lrt(btex B etex,B); label.urt(btex A1 etex,Ap1);

label.bot(btex C1 etex,Ap2); label.bot(btex C0 etex,Bp1);

dotlabel.rt(btex O etex,O); label.urt(btex A0 etex,Bp2);

endfig;

Ví dụ: Vẽ đường tròn nội tiếp và bàn tiếp tam giác

I

O C

beginfig(11);

numeric u;

pair A,B,C,D,E,O,I,Ap[],Bp[];

u=1cm;

pickup pencircle scaled 0.5bp;

A=(-2,0)*u;B=(2.5,0)*u;C=(-0.5,3)*u;D=2.2[A,B];E=3[A,C];

Bp1=whatever[A,B]=whatever*dir(0.5angle(A-C)+0.5angle(B-C))+C; Bp2=whatever[A,C]=whatever*dir(0.5angle(A-B)+0.5angle(C-B))+B; O=whatever[C,Bp1]=whatever[B,Bp2];

I=whatever[(C-O) rotated 90 +C,C]=whatever[(B-O) rotated 90 +B,B]; Ap1=whatever[A,B]=whatever[(A-B) rotated 90+O,O];

Ap2=whatever[A,B]=whatever[(A-B) rotated 90+I,I];

draw A B C cycle;draw B D;draw C E;

draw C O;draw B O; draw C I; draw B I;

draw fullcircle scaled 2abs(O-Ap1) shifted O;

draw fullcircle scaled 2abs(I-Ap2) shifted I;

dotlabel.urt(btex $I$ etex,I); dotlabel.ulft(btex $O$ etex,O); label.ulft(btex $C$ etex,C); label.llft(btex $A$ etex,A);

label.lrt(btex $B$ etex,B);

endfig;

2.9 Vòng lập xác định

Vòng lập xác định for có cấu trúc:

Trang 7

for i=gt_ban_dau step gt_tang until gt_cuoi:

Hệ lệnh;

endfor;

Thay vì dùng step 1 until, chúng ta có thể dùng upto Tương tự, downto thay cho step -1 until

Ví dụ: Vẽ đồ thị hàm số y = x2 với x ∈ (−2, 2)

1 2 3

4

y= x 2

beginfig(12);

numeric u,i; path p; u=1cm;

p=(-2,(-2)*(-2))*u

for i=-2+0.1 step 0.1 until 2.1:

(i,i*i)*u

endfor;

for i=-3 upto 3:

label.bot(decimal(i), (i,0)*u);

draw (i,-0.05)*u–(i,0.05)*u;

endfor;

for i=1 upto 4:

label.rt(decimal(i), (0,i)*u);

draw (-0.05,i)*u–(0.05,i)*u;

endfor;

drawarrow (-3.5u,0)–(3.5u,0);drawarrow(0,-u)–(0,4.5u);

draw p withpen pencircle scaled 1bp;

endfig;

2.10 Xây dựng một đường cong đóng

Lệnh buildcycle(p1, p2, , pm) tạo ra một đường cong đóng từ các đường pi Sau khi tạo ra được một đường cong đóng, chúng ta dùng lệnh

fill duong_cong withcolor mau;

để tô màu miền trong của nó

Ví dụ: Minh họa diện tích hình phẳng

x

y

f (x)

beginfig(13);

numeric xmin, xmax, ymin, ymax; xmin := 1/2;

xmax := 6; ymax := 2/xmin;

u := 1cm; xinc := 0.1;

path pts_f;

pts_f := (xmin,2/xmin)*u

for x=xmin+xinc step xinc until xmax:

(x,2/x)*u

endfor;

path hline[], vline[];

hline0 = (-0.5,0)*u – (xmax+0.5,0)*u;

vline0 = (0,-0.5)*u – (0,ymax+0.5)*u;

vline0.5 = (0.75,0)*u – (0.75,ymax)*u;

vline4 = (4,0)*u – (4,ymax)*u;

Trang 8

fill buildcycle(hline0, vline0.5, pts_f, vline4) withcolor blue;

drawarrow hline0;

drawarrow vline0;

draw (0.75,0)*u – vline0.5 intersectionpoint pts_f

draw (4,0)*u – vline4 intersectionpoint pts_f

draw pts_f withpen pencircle scaled 1bp;

label.bot(btex x etex, (xmax,0)*u);

label.lft(btex y etex, (0,ymax)*u);

label.urt(btex f (x) etex, (2,1)*u);

endfig;

Trong ví dụ trên, lệnh intersectionpoint dùng để xác định giao điểm của hai đường cong

2.11 Xén một hình

Lệnh clip p to q; dùng để cắta hình p theo một đường cong q và giữ lại phần ở miền trong của q

Ví dụ: Vẽ thiết diện của một tứ diện

A

B

C

D

P

Q

R

beginfig(14);

pair A[],B[]; numeric u,i; path p,c;u=1cm;

A0=(-2u,0);A1=(0,-2u);A2=(4u,0);A3=(u,4u);

B0=1/2[A0,A2];B1=1/2[A2,A1];B2=1/2[A2,A3];

p=B0–B1–B2–cycle;

c:=-500*dir(15)–500*dir(15);

for i=0 upto 25:

draw c shifted (0,5*i);

draw c shifted (0,-5*i);

endfor;

clip currentpicture to p;

pickup pencircle scaled 0.75bp;

draw A0–A1–A2–A3–A0; draw A3–A1;

draw A0–A2 dashed evenly scaled 2 shifted (10,0);

draw B2–B0–B1 dashed evenly scaled 1;

draw B1–B2;

dotlabel.ulft("A",A0); dotlabel.lrt("B",A1); dotlabel.urt("C",A2);

dotlabel.urt("D",A3); dotlabel.ulft("P",B0); dotlabel.lrt("Q",B1); dotlabel.urt("R",B2); endfig;

Ví dụ: Vẽ hình cánh quạt

beginfig(2);

path p[],a,q; numeric u; u=1cm;

pickup pencircle scaled 0.5;

p0=halfcircle scaled 6u;

p1=halfcircle scaled 1u shifted (-2.5u,0);

p2=halfcircle scaled 1u shifted (2.5u,0);

p3=halfcircle scaled 4u yscaled -1;

q=buildcycle(reverse(p1),reverse(p3),reverse(p2),p0);

a=-6u*dir(30)–6u*dir(30);

for i=-30 upto 22:

Trang 9

draw a shifted (i*u/5,0);

endfor;

clip currentpicture to q;

draw q withpen pencircle scaled 1bp;

endfig;

3 Kết luận

TÀI LIỆU THAM KHẢO

1 John D Hobby, A user’s manual for MetaPost, AT&T Bell Laboratories Com-puting Science Technical Report 162, 1992

2 André Heck, Learning MetaPost by doing, AMSTEL Institute, Universiteit van Amsterdam, 2005

Ngày đăng: 16/06/2021, 22:54

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm