Chủ đề trong bài học Hàm cơ bản
Hàm (Command …) | Hàm (getpoint …)
Hàm (getdist …) | Hàm (getangle …) | Hàm (getint …) | Bài tập
Tiếp tục với chuổi bài Hướng dẫn học Autolisp cùng Blog xây dựng, hôm nay Tuệ sẽ giới thiệu các bạn về các Hàm nhập dữ liệu trong Autolisp. Sau khi học xong bài này và làm bài tập áp dụng bạn đã có thể tự mình viết được một số lisp cơ bản rồi đó
Xem lại các bài học trước
Bài 1: Các phép toán trong AutoLisp
Bài 2 : Một số hàm cơ bản của Autolisp
1.Hàm Command …
CHỨC NĂNG: Thực hiện lệnh của AutoCad
CÚ PHÁP:
Command “Tên_lệnh”["các đáp ứng lời nhắc" "các tuỳ chọn"...)
GIẢI THÍCH:
Tên_lệnh: là tên các lệnh của AutoCad
“các đáp ứng lời nhắc” và “các tuỳ chọn”: Tuân theo các lệnh của AutoCad
2. Các hàm nhập liệu từ người dùng
Các hàm sau sẽ tạm dừng chương trình để yêu cầu người dùng nhập dữ liệu vào từ bàn phím hoặc chuột
a. Hàm (getpoint …)
CHỨC NĂNG: Chờ người dùng nhập toạ độ một diểm
CÚ PHÁP:
(getpoint [point] [prompt])
GIẢI THÍCH:
point: Nếu có, cho bằng 1 danh sách điểm , là điểm thứ nhất, còn điểm người dùng nhập vào sẽ là điểm thứ 2. Điểm thứ 2 có thể cho bằng toạ độ tương đối.
[prompt]: Nếu có, là dòng nhắc hoặc giải thích về dữ liệu sẽ nhập. Dòng nhắc phải được đặt trong ngoặc kép “ ”
VD1 : Vẽ 1 đoạn thẳng Line khi biết toạ độ 2 điểm
Mở Visua Lisp Editor -> menu File -> New -> Soạn thảo Lisp có nội dung sau :
[php]
(defun c:VL () ;(1)
(setq p1 (getpoint "\n Nhap toa do diem thu nhat cua Line :")) ; (2)
(setq p2 (getpoint p1 "\n Nhap toa do diem thu hai cua Line :")) ; (3)
(Command "Line" p1 p2 "") ; (4)
) ; (5)[/php]
Giải thích
+ Dòng (1) định nghĩa 1 lệnh tắt để vẽ Line có tên là VL
+ Dòng (2) : Trên Command sẽ xuất hiện dòng nhắc Nhap toa do diem thu nhat cua Line. Hàm getpoint chờ người dùng nhập toạ độ hoặc pick trên màn hình, sau đó sẽ gán toạ độ này cho biến p1 nhờ hàm setq.
+ Dòng (3) : Trên Command sẽ xuất hiện dòng nhắc Nhap toa do diem thu hai cua Line. Hàm getpoint chờ người dùng nhập toạ độ hoặc pick trên màn hình, sau đó sẽ gán toạ độ này cho biến p2 nhờ hàm setq. Bạn để ý nếu hàm getpoint có chứa biến p1 thì sẽ xuất hiện sợi tóc của chuột tại điểm p1
+ Dòng (4): Thông qua hàm Command, ta vẽ 1 line từ p1 đến p2
+ Dòng (5): Dấu ) của hàm defun ở dòng (1)
Trước hết bạn xem lệnh Line của CAD:
Command: LINE -> Gõ Line
Specify first point: -> Nhập điểm thứ nhất
Specify next point or [Undo]: -> Nhập điểm thứ hai
Specify next point or [Undo]: -> Enter kết thúc lệnh
Bạn xem code Lisp tương ứng : (Command “Line” p1 p2 “”)
“Line” : Là lệnh Line của CAD
p1 : toạ độ điểm thứ nhất do USER nhập vào (đã được lấy bằng hàm getpoint)
p2 : toạ độ điểm thứ hai do USER nhập vào (đã được lấy bằng hàm getpoint)
“” : chính là enter
Bạn chạy thử Lisp VL trên xem nhé
b. Hàm (getdist …)
CHỨC NĂNG: Chờ người dùng nhập vào:
– Một số thực là một khoảng cách
– Toạ độ của 1 hoặc 2 điểm
Nếu nhập toạ độ điểm, AutoLisp hoàn trả khoảng cách giữa hai điểm
CÚ PHÁP: (getdist [point] [prompt])
GIẢI THÍCH:
point: giống như getpoint
[prompt]: là dòng nhắc hoặc giải thích về dữ liệu sẽ nhập
VD:
[php](<b>setq</b> r1 (<b>getdist </b>“Cho ban kinh duong tron:”))[/php]
Kết quả cho trên dòng nhắc:
Cho tam duong tron:
– Nhập vào một số thực dương hoặc
– Nhập toạ độ một điểm, dòng nhắc xuất hiện:
Second point: Tiếp tục nhập vào điểm thứ 2 để lấy khoảng cách giữa 2 điểm
c. Hàm (getangle …)
CHỨC NĂNG: Chờ người dùng nhập vào:
– Một số thực là số đo bằng độ của góc hoặc cung tròn
– Toạ độ của 1 hoặc 2 điểm
Nếu nhập toạ độ điểm, AutoLisp hoàn trả góc nghiêng giữa đoạn thẳng nối hai điểm so với phương nằm ngang
Kết quả trả về: REAL ( số đo là Radian)
CÚ PHÁP:
(getangle [point] [prompt])
GIẢI THÍCH:
point: giống như getpoint
[prompt]: là dòng nhắc hoặc giải thích về dữ liệu sẽ nhập
VD:
[php]
(setq a1 (getangle “Cho goc nghieng cua duong thang:”))[/php]
Kết quả cho trên dòng nhắc chờ người dùng nhập số liệu:
Cho goc nghieng cua duong thang:
d. Hàm (getint …)
CHỨC NĂNG: Chờ người dùng nhập vào một số nguyên
Kết quả: INT
CÚ PHÁP:(getint [prompt])
GIẢI THÍCH:
[prompt]: là dòng nhắc hoặc giải thích về dữ liệu sẽ nhập
e. Hàm (getreal …)
CHỨC NĂNG: Chờ người dùng nhập vào một số thực
Kết quả: REAL
CÚ PHÁP:
(getreal [prompt])
GIẢI THÍCH:
[prompt]: là dòng nhắc hoặc giải thích về dữ liệu sẽ nhập
Bài tập
1. Viết lệnh VTRON1 để vẽ 1 đường tròn khi biết tâm và bán kính. Tâm đường tròn do người sử dụng Pick trên màn hình, Bán kính đường tròn do người sử dụng nhập vào
2. Viết lệnh VTRON2 để vẽ 1 đường tròn đi qua 2 điểm A, B và vẽ 1 line đi qua A,B. 2 điểm A, B do người sử dụng Pick trên màn hình
3. Viết lệnh VTRON3 để vẽ 1 đường tròn đi qua 3 điểm A, B, C và vẽ tam giác ABC. 3 điểm A, B, C do người sử dụng Pick trên màn hình
4. Viết lệnh CONG cộng 2 số a và b. Số a và số b do người sử dụng nhập vào. In kết quả nhận được vào dòng Command (sử dụng hàm Princ)
Tiếp tục nhé :
Bài 5: Sử dụng toạ độ tương đối và toạ độ cực tương đối để vẽ 1 tam giác đều ABC, biết AB//Ox và cạnh AB=100. Điểm A nhập từ bàn phím
Ví dụ về cách sử dụng toạ độ tương đối và toạ độ cực tương đối:
[php]
(defun c:VL2 () ;(1)
(setq p1 (getpoint "\n Nhap toa do diem thu nhat cua Line :")) ; (2)
(Command "Line" p1 "@100<60" "") ; (3)
(Command "Line" p1 "@100,200" "") ; (4)
(Command "Line" p1 "@-200,-300" "") ; (5)
) ; (5)
[/php]
Giải thích:
+ Dòng (3) : Bằng cách sử dụng toạ độ cực tương đối vẽ 1 Line có điểm đầu là p1, độ dài bằng 100, nghiêng với phương OX 1 góc 60 độ
+ Dòng (4) : Bằng cách sử dụng toạ độ tương đối vẽ 1 Line có điểm đầu là p1, điểm cuối là p2 cách p1 theo phương Ox là +100, theo phương Oy là +200
Dòng (5) : Bằng cách sử dụng toạ độ tương đối vẽ 1 Line có điểm đầu là p1, điểm cuối là p2 cách p1 theo phương Ox là -200, theo phương Oy là -300
Bài 6: Vẽ 1 hình chữ nhật ABCD, biết AB=100, AD=200. AB//Ox. Điểm A nhập từ bàn phím
Bài 7 : Vẽ hình bình hành ABCD, biết AB=500, AD=200, góc DAB=60 độ, AB//Ox. Điểm A nhập từ bàn phím
Em xin gửi bài tập Anh xem dùm em với ạ: 1/BT1: (defun c:VTRON1 (/ p1 r) (setq p1 (getpoint “\nTam duong tron:”) r (getreal “\nBan kinh duong tron:”) ) (command “circle” p1 r) (princ) ) 2/BT2: (defun c:VTRON2 (/ p1 p2) (setq p1 (getpoint “\nDiem p1:”) p2 (getpoint p1 “\nDiem P2:”) ) (command “circle” “2p” p1 p2 “line” p1 p2 “”) (princ) ) 3/BT3: (defun c:VTRON3 (/ p1 p2 p3) (setq p1 (getpoint “\nDiem p1:”) p2 (getpoint p1 “\nDiem P2:”) p3 (getpoint p2 “\nDiem P3:”) ) (command “circle” “3p” p1 p2 p3 “line” p1 p2 p3 p1 “”) (princ)… Read more »
ở bài tập 3, tại sao khi pick 3 điểm bất kỳ trên màn hình thì cad ko vẽ tam giac bên trong đường tròn, nhưng khi ta bắt 3 điểm có sẵn trên màn hình ( vẽ một đường thẳng hoặc 2 đường thẳng giao nhau để lấy điểm) thì cad lại vẽ đc tam giac bên trong đường tròn nhỉ?
Em mới theo học mong các anh chỉ giáo
Bt anh Ngọc Quyền làm em Save và chạy được lisp rồi. Em có thắc mắc trong lisp có hàm (princ) . Theo bài 2 thì hàm Princ có cú pháp (Princ [expr [file-desc]]), vậy trong lisp này (princ) nghĩa thế nào ạ. em hỏi hơi gà mong các anh chị nhẹ tay
Hàm (Princ) không tham số là không xuất hiện gì trên màn hình bạn à
Chào bạn Cuong! Theo bài 2 thì hàm Princ có cú pháp (Princ [expr [file-desc]]) Mình quên giải thích thêm trong cú pháp : các đối số nằm trong cặp móc [] là có thể bỏ và đương nhiên khi bỏ đi thì nó sẽ có ý nghĩa khác (command “circle” “3p” p1 p2 p3 “line” p1 p2 p3 p1 “”) (Princ) Giải thích : Hàm command khi thực hiện xong lệnh thì sẽ trả về chữ Nil ngay tại command. Mình không muốn có chữ Nil đó ở dưới command thì mình sử dụng (princ) ngay sau command để… Read more »
Anh Tuệ giải thích thật dễ hiểu
Anh cho em hỏi tiếp tý ạ
Nếu em dùng
1.hàm getpoint lấy tọa độ 2 điểm rồi dùng distance lấy khoảng cách
2.Dùng hàm getdist
thì 2 cách làm này có gì khác nhau và nên làm cách nào vậy anh
Chào Ngọc Quyền!
Hàm getdist có thể cho người sử dụng (USER) nhập 1 số thực, hoặc là pick 2 điểm trên màn hình để lấy khoảng cách
– Với cách dùng hàm getpoint để lấy tọa độ 2 điểm rồi lấy khoảng cách thì sẽ mất đi tùy chọn nhập số như ở hàm getdist
-> Nên sử dụng getdist trong trường hợp này
Mình viết thêm các bài tập 5, 6, 7 là bài mới. Các bạn làm bài tập để nắm vững lý thuyết nhé
Em làm thử BT 5, 6 , 7:
Anh Tuệ xem em với:
1/BT5
(defun c:tamgiac()
(setq p1 (getpoint “\nNhap toa do diem thu nhat cua tam giac:”))
(command “line” p1 “@100<0" "@100<120" "@100<-120" "") ) 2/BT6: (defun c:hcn() (setq p1 (getpoint "\nNhap toa do diem thu nhat cua hinh chu nhat:")) (command "line" p1 "@100<0" "@200<90" "@100<180" "@200<-90" "") ) 3/BT7: (defun c:hbh() (setq p1 (getpoint "\nNhap toa do diem thu nhat cua hinh binh hanh:")) (command "line" p1 "@100<0" "@200<60" "@100<180" "@200<-120" "") ) Mà làm sao để code như trên của anh vậy ạ
Bài 6 thì mình viết ntn
(defun c:HCN ()
(setq p1 (getpoint “\n Nhap toa do diem can ve HCN :”))
(Command “rectang” p1 “@100,200” “”)
)
@ngọc quyền: Code như trên trong phần comment không làm được bạn à, bạn đang là SV hay là công tác đâu chưa?
Vì code trên ko đưa vào đc comment thì lisp nó ko hiện rõ đc chỗ nào cần vào đầu dòng hay…..(nhìn nó khó phân biệt cho người mới)
Em đang công tác ở Đà Nẵng anh Lenhan ạ
cho em hỏi về bài tập 2 vói ạ, em viết như thế này, và đường tròn của em lại chọn điểm A làm tâm, như vậy AB là bán kính chứ ko phải đường kính của đường tròn, và không có đường thẳng AB, có nhiều vấn đề em chưa hiểu rõ mong các bác chỉ ra chỗ sai giúp em: (defun c: VTRON2 () (setq A (getpoint “chon diem A”) B (getpoint ” chon diem B”)) (command “circle” A B) (command “line” A B) (princ)) theo như cú pháp của lệnh command thì tên lệnh nằm trong dấu… Read more »
Chào bạn Mai! 1./ Hàm Command nó thực hiện lệnh của CAD Ở code của bạn Ngọc Quyền: (command “circle” “3p” p1 p2 p3 “line” p1 p2 p3 p1 “”) Thì Lisp thực hiện tuần tự lệnh Circle của CAD, kết thức lệnh Circle thì thực hiện lệnh Line luôn Điều này cũng tương tự như bạn thực hiện 2 dòng Command, 1 dòng command thực hiện lệnh Circle, 1 dòng thực hiện lệnh Line (command “circle” “3p” p1 p2 p3) (Command “line” p1 p2 p3 p1 “”) 2./ Ở dòng (defun c: VTRON2 (/ p1 p2) Thì sau kí… Read more »
Cảm ơn bác Tue đã giải đáp thắc mắc. Để học thuộc thì dễ còn để hiểu rõ vấn đề thì ko dễ chút nào 🙂 . em còn phải học hỏi dài dài. chúc bác năm 2014 nhiều sức khỏe và thành công
ở bài tập 4 cách viết như bạn Quyền thì em chưa thử dùng, nhưng em viết thế này thấy dùng cũng ok ạ:
(defun c:CONG (/ a b)
(princ ” Tong 2 so la:” (+ (getreal ” nhap so a:”) (getreal “nhap so b:”))))
Chào bạn Mai!
Cách viết mã như bạn
(defun c:CONG (/ a b) (princ ” Tong 2 so la:” (+ (getreal ” nhap so a:”) (getreal “nhap so b:”))))
CHẮC CHẮN LÀ KHÔNG ĐƯỢC! Sai cú pháp rồi
em thử chạy thì vẫn cho ra kết quả đúng mà, kết quả giống như khi em chạy đoạn code mà bạn Quyền viết, chỉ là khi nó hiện kết quả nó ko hiện sau dòng :” tong 2 so la: ” mà nó hiện sau dòng :bad argument type: FILE . khi em chạy doạn code của bạn quyền thì cũng có kết quả tương tự như vậy, phải chăng cả 2 cùng sai ạ?
Chào bạn Mai!
Dòng bad argument type: FILE chính là dòng báo lỗi đối số đó bạn
Code bạn Quyền viết đâu có báo lỗi như thyế đâu bạn?
a Tue e cung mới tập tành với lisp, mấy bài của a rất hay mà dễ hiểu nữa
e xem hết ba bài a up lên rùi mà sao đợi lâu qá chưa thấy bài mới z a Tuệ
Em mới học về Autolisp. Khi em nhập để vẽ đường tròn biết tâm đường tròn và bán kình thì nó giống như chương trình của anh thì nó báo lỗi. (“Load failed”) mặc dù khi load lần đầu đã thành công. Em dùng CAD 2015. Đây là chương trình của em ạ.
(defun c:VeTRon1 (/ p1 r)
(setq p1 (getpoint “\ntam duong tron:”)
r (getreal “\nBan kinh duong tron:”)
)
(command “circle” p1 r)
(princ)
)
Vậy làm thế nào để nó chạy đc ạ? Em xin cảm ơn.