Trang chủ

Thứ Bảy, 22 tháng 1, 2011

Hướng dẫn viết lispcad

06:06 Được đăng bởi Phạm Quốc Duy
Bạn nên theo dỏi theo tên bài viết tăng từ nhỏ tới lớn thì mới đúng trình tự!
Trong các loạt bài viết này mình sẽ dùng ngôn ngữ bình dân như nói chuyện để hướng dẩn và diển tả cách lập trình lisp cho dể hiểu và cũng dể cho mình khi viết bài.
*Công cụ dùng viết lisp:
-Tất cả các chương trình có thể soạn và lưu file txt.-Cá nhân mình dùng Notepad.

-Lưu file bằng phần mở rộng (đuôi) lsp là thành file lisp (chạy được hay không tính sau)
*Khái niệm nôm na về lập trình lisp.
-Cách mình viết là cách thô sơ nhất: Trong khi vẽ CAD có 1 số thao tác lặp đi lặp lại có cả việc tính toán nếu làm thủ công thì mệt và nhàm nên mình lưu các thao tác này vào 1 file txt có đuôi là lsp để nó làm cho mình.
*Cấu trúc 1 lệnh lisp:
-Nguyên tắc chung: cứ mở ngoặc ra thì phải đóng lại trong 1 file lisp số lượng dấu “(” và “)” luôn bằng nhau.
-Mở đầu luôn luôn có dòng sau:(defun c:lenlenh ()
Trong đó tenlenh là cái mà bạn gỏ vào thanh command để thực thi lệnh lisp
-Kết thúc luôn là dấu ngoặc đơn đóng:)
-Toàn bộ phần giữa quyết định việc lệnh lisp của bạn làm việc gì, từ nay về sau mình sẽ nói về cách viết đoạn giữa này còn cái mở đầu và kết thúc luôn như vậy.
06:12 Được đăng bởi Phạm Quốc Duy
Bạn nên theo dỏi theo tên bài viết tăng từ nhỏ tới lớn thì mới đúng trình tự!
*Để chọn 1 điểm (để làm gì thì tùy bạn) dùng dòng sau:
(setq a (getpoint "Chon diem: "))
Trong đó:
-a: là điểm xác định bằng cách pick chuột.
-Chon diem: là dòng chữ sẽ hiển thị trên dòng lệnh khi chạy lệnh.

*Để thực hiện 1 lệnh cad trong lisp thì gỏ đúng trình tự mà lệnh cad chạy, lưu ý "" là thay cho enter.
Ví dụ:(command ".line" a b "")
Tác dụng:
-Thực hiện lệnh line, chọn điểm a, chọn điểm b, enter.
-Bạn thấy chưa giống y như vẽ cad thôi có gì đâu.
*Bây giờ ví dụ gọn gọn nhé:
Bắt đầu bằng cái lisp vẽ đoạn thẳng nhé.
(defun c:doanthang ()
(setq a (getpoint "Chon diem: "))
(setq b (getpoint "Chon diem: "))
(command ".line" a b ""))
-Bạn lưu đoạn trên ra file vdt.lsp-Khởi động CAD.-Gỏ lệnh AP. Chọn đến file vdt.lsp load nó lên.
-Rồi bạn chỉ cần nhập lệnh doanthang nó hỏi bạn Chon diem bạn chọn 1 điểm nó lại hỏi Chon diem bạn lại chọn nó vẽ ra đoạn thẳng qua 2 điểm bạn vừa chọn.
-Khớ khớ chắc bạn kiu lisp gì mà mắc cười vậy. Đừng nôn nóng cái này là bước đầu mà từ từ rồi bạn sẽ thấy cái hay của lisp đem lại.
!^__^! Theo dỏi các bài tiếp theo nhé.
06:15 Được đăng bởi Phạm Quốc Duy
Bạn nên theo dỏi theo tên bài viết tăng từ nhỏ tới lớn thì mới đúng trình tự!
Đây là những gì hiển thị trên dòng lệnh khi chạy lệnh doanthang.
Command: doanthang
Chon diem: Chon diem:
nil

*Phân tích:
-Hai câu hỏi của lisp là Chon diem và Chon diem dính liền nhau trên 1 hàng và cuối cùng xuất hiện chữ nil không được đẹp mắt lắm.
-Khi bạn chọn điểm thứ nhất trên màn hình lisp sẽ tiếp tục chọn điểm thứ hai nhưng không xuất hiện “dây tóc” nối điểm thứ nhất với con trỏ như thường thấy ở lệnh line của cad làm việc chọn điểm thứ hai không được bài bản cho lắm.
*Khắc phục:Sửa đoạn lisp lại như sau:
(defun c:doanthang ()
(setq a (getpoint "\nChon diem: "))
(setq b (getpoint a"\nChon diem: "))
(command ".line" a b "")
(princ))
Bây giờ load lại và thực hiện lệnh doanthang sẽ thấy:
Command: DOANTHANG
Chon diem:
Chon diem:
Hai câu hỏi của lisp đưa ra xuống hàng đàng hoàn.Chữ nil cuối lệnh đã biến mất.Có dây tóc giúp việc chọn điểm thứ hai trực quan hơn.
*Phân tích:
\n sẽ làm cho các nội dung phía sau đó nhảy xuống hàng.
Thêm chữ
a sau getpoint sẽ làm xuất hiện dây tóc nối con trỏ với điểm a
(princ) sẽ ghi ra 1 dòng trắng giúp triệt tiêu các thông báo lòng thòng khi chạy lisp còn dư.
!^__^! Theo dỏi các bài tiếp theo nhé.
06:18 Được đăng bởi Phạm Quốc Duy
Bạn nên theo dỏi theo tên bài viết tăng từ nhỏ tới lớn thì mới đúng trình tự!Cũng với đoạn trên nhưng bây giờ không vẽ đường thẳng nửa mà vẽ đường tròn:
Thay dòng
(command ".line" a b "")
Bằng dòng
(command ".circle" a b)
Bạn để ý nhé dòng vẽ line có "" sau khi chọn a và b còn vẽ circle thì không. Vì khi vẽ line sau khi nhập hai điểm sẽ tiếp tục lệnh line muốn kết thúc phải enter, còn circle thì chỉ cần chọn tâm và bán kính là kết thúc lệnh nên không có enter để kết thúc.
-Để thấy cái lợi của lisp bạn lưu đoạn sau thành file lsp rồi chạy thử.
(defun c:doanthang ()
(setq a (getpoint "\nChon diem: "))
(setq b (getpoint a"\nChon diem: "))
(command ".line" a b "")
(command ".circle" a b)(command ".circle" b a)
(princ))
Sẽ thấy sau khi chọn 2 điểm trên màn hình lisp sẽ vẻ ra:
-Đường thẳng từ a đến b.
-Đường tròn tâm a bán kính ab.
-Đường tròn tâm b bán kính ab.
**Kinh nghiệm rút ra:
-Từ 1 kiểu dữ liệu nhập vào lisp có thể làm nhiều việc (đây mới là sử dụng nguyên gốc hai điểm a và b chưa kể đến tính toán và cho ra điểm mới phục vụ mục đích nào đó).
-Sau khi dử liệu được nhập (điểm a và b) có thể dùng vào mọi việc không cần đến thứ tự ví dụ nhập a trước nhưng vẫn có thể dùng b trước như dòng vẽ circle thứ 2.
06:21 Được đăng bởi Phạm Quốc Duy
Bạn nên theo dỏi theo tên bài viết tăng từ nhỏ tới lớn thì mới đúng trình tự!Từ 2 điểm a và b lisp sẽ làm được rất nhiều việc.
-Giới thiệu 1 số hàm đối với 1 điểm:
(setq xa (car a)) tọa độ x của điểm a
(setq ya (cadr a)) tọa độ y của điểm a
(setq za (caddr a)) tọa độ z của điểm a
-Giới thiệu 1 số hàm đối với 2 điểm:
(setq daiab (distance a b)) khoảng cách từ a đến b
(setq gocab (angle a b)) góc mà đoạn ab tạo với trục x
-Giới thiệu hàm tính toán:Cú pháp các hàm toán học hơi ngược với cách thông thường:(dấu sốđầu sốsau) nghĩa là nếu muốn có
a+b thì viết (+ a b) đối với + - * / điều như vậy.
**Từ hai điểm a và b kết hợp các hàm trên chúng ta bắt đầu cho việc tính toán cho ra những kết quả phục vụ cho việc mình cần.
-Tìm điểm nằm chính giữa a và b:
+Ngoài việc xác định 1 điểm bằng cách pick điểm thông qua hàm getpoint như trên thì 1 điểm trong lisp còn biểu diển như sau:
(setq c (list xc yc zc))
Trong đó:Xc, yc, zc lần lượt là tọa độ x, y,z của điểm c các giá trị này được xác định kiểu gì cũng được. Trong trường hợp này xác định từ các giá trị của điểm a và b. Để đơn giản mình chỉ tính toán trên mặt phẳng xy khi nào lisp vẽ phối cảnh mình hãy đưa giá trị z vào từ bây giờ 1 điểm chỉ cần biểu diển bằng x và y nên xác định điểm c như sau:
(setq c (list xc yc))
(setq xab (+ xa xb)) xác định 1 biến tạm bằng tổng x điểm a và x điểm b
(setq yab (+ ya yb)) xác định 1 biến tạm bằng tổng y điểm a và y điểm b
(setq xc (/ xab 2)) xác định x điểm c bằng cách lấy xab chia 2
(setq yc (/ yab 2)) xác định y điểm c bằng cách lấy yab chia 2
(setq c (list xc yc)) xác định điểm c bằng x và y vừa tính được.
(defun c:doanthang ()
(setq a (getpoint "\nChon diem: "))
(setq b (getpoint a"\nChon diem: "))
(command ".line" a b "")
(command ".circle" a b)
(command ".circle" b a)
(setq xa (car a))
(setq ya (cadr a))
(setq xb (car b))
(setq yb (cadr b))
(setq xab (+ xa xb))
(setq yab (+ ya yb))
(setq xc (/ xab 2))
(setq yc (/ yab 2))
(setq c (list xc yc))
(command ".circle" c a)
(princ))
*Bây giờ chạy thử đoạn trên bạn sẽ thấy có thêm 1 vòng tròn tâm là trung điểm đoạn ab đường kính bằng ab.
*Hai hàm:
distanceangle trong bài này chưa xài tới nhưng nhân tiện nói về đểm mình nói luôn bạn hãy ghi nhớ cho sau này.
06:30 Được đăng bởi Phạm Quốc Duy
Bạn nên theo dỏi theo tên bài viết tăng từ nhỏ tới lớn thì mới đúng trình tự!Đoạn lisp trên mình viết rất cơ bản làm từng bước 1 để bạn làm quen, thực chất bạn có thể làm gọn lại bằng cách gộp các đoạn lại với nhau.

-Cụ thể đoạn
(setq xa (car a))
(setq xb (car b))
(setq xab (+ xa xb))
-Có thể thay bằng
(setq xab (+ (car a) (car b)))
-Tương tự sau khi gộp bước 1 từ đoạn:
(
setq xa (car a))
(setq ya (cadr a))
(setq xb (car b))
(setq yb (cadr b))
(setq xab (+ xa xb))
(setq yab (+ ya yb))
(setq xc (/ xab 2))
(setq yc (/ yab 2))
(setq c (list xc yc))
-Ta có
(setq xab (+ (car a) (car b)))
(setq yab (+ (cadr a) (cadr b)))
(setq c (list (/ xab 2) (/ yab 2)))
-Tương tự sau khi gộp bước 2 ta có
(setq c (list (/ (+ (car a) (car b)) 2) (/ (+ (cadr a) (cadr b)) 2)))
*Đoạn lisp bây giờ còn như sau:
(defun c:doanthang ()
(setq a (getpoint "\nChon diem: "))
(setq b (getpoint a"\nChon diem: "))
(command ".line" a b "")(command ".circle" a b)
(command ".circle" b a)
(setq c (list (/ (+ (car a) (car b)) 2) (/ (+ (cadr a) (cadr b)) 2)))
(command ".circle" c a)
(princ))
*Chạy thử kết quả giống y như trước nhưng ngắn được 1 số dòng. Nếu mới bắt đầu viết gộp quá rối thì bạn cứ viết từng bước như cũ đến khi nào rành rành thì bắt đầu gộp lại.
*Mới có pick 2 điểm mà đã đủ thứ chuyện vậy đó. Tất nhiên cái hình mà lisp này vẽ ra giống y như cái mạng nhện vậy chẳng để làm gì cả nhưng khi đã nắm vấn đề thì bạn muốn làm gì mà chả được.
06:34 Được đăng bởi Phạm Quốc Duy
Bạn nên theo dỏi theo tên bài viết tăng từ nhỏ tới lớn thì mới đúng trình tự!
Bây giờ bỏ bớt cái hình tròn tâm b đường kính ab đi.
Áp dụng lệnh Array với cái hình tròn tâm a đường kính ab.
Cho nó Array thành 8 đối tượng quanh điểm c nhé.
-Cú pháp lệnh Array như sau:
+Vì trong lệnh Array có hỏi chọn đối tượng nhưng mình muốn nó chọn tự động cái hình tròn thì làm sao? Giải pháp đưa ra là lựa chọn
last nghĩa là chọn đối tượng mới tạo ra muốn vậy cái đường tròn này mình đừng vẽ vội mà chỉ vẽ nó trước khi thực hiện lệnh Array thôi.
(command ".circle" a b)
(command ".array" "last" "" "p" c "8" "" "")
+Giải thích dòng trên: gọi lệnh Array, gỏ
last để chọn đối tượng vừa tạo trước đó, enter kết thúc chọn đối tượng, gõ p để chọn kiểu Array là Polar, chọn điểm tâm quay là c, gỏ 8 để xác định số lượng tạo ra là 8, enter hai lần để kết thúc lệnh Array.

(defun c:doanthang ()
(setq a (getpoint "\nChon diem: "))
(setq b (getpoint a"\nChon diem: "))
(command ".line" a b "")
(setq c (list (/ (+ (car a) (car b)) 2) (/ (+ (cadr a) (cadr b)) 2)))
(command ".circle" c a)
(command ".circle" a b)
(command ".array" "last" "" "p" c "8" "" "")
(princ))

*C
hạy thử đoạn trên. Khớ khớ đẹp chưa có nguyên cái bông rồi nhưng sao nhiều cánh quá á? Yên tâm sẽ có cách cho bạn quyết định số lượng cánh của cái bông này…….
06:37 Được đăng bởi Phạm Quốc Duy
Bạn nên theo dỏi theo tên bài viết tăng từ nhỏ tới lớn thì mới đúng trình tự!**Bây giờ thêm 1 dòng giúp bạn quyết định số lượng sẽ Array.
-Để nhập 1 chuổi vào lisp dùng dòng sau:
(setq sl (getstring 5"\nSo luong:"))
-Bạn lưu ý con số
5 này nhé, nếu không có nó thì khi nhập chuổi nút Space sẽ tương đương với enter nghĩa là kết thúc quá trình nhập chuổi, còn có nó thì Space là khoảng trắng.

Tùy theo nhu cầu chuổi cần nhập mà quyết định có số 5 này hay không.
-Để thấy lisp làm việc từng bước mình thêm dòng hỏi số lượng này vào sau dòng vẽ line và circle.
Sau khi bạn nhập số lượng vào thì thực hiện lệnh array như vậy thú vị hơn là chọn 2 điểm và hỏi số lượng hết rồi mới vẽ 1 lần xong lun.
(defun c:doanthang ()
(setq a (getpoint "\nChon diem: "))
(setq b (getpoint a"\nChon diem: "))
(command ".line" a b "")
(setq c (list (/ (+ (car a) (car b)) 2) (/ (+ (cadr a) (cadr b)) 2)))
(command ".circle" c a)
(command ".circle" a b)
(setq sl (getstring "\nSo luong:"))
(command ".array" "last" "" "p" c sl "" "")
(princ))
Chạy thử sẽ thấy sau khi chọn 2 điểm trên màn hình lisp sẽ vẻ ra:
-Đường thẳng từ a đến b.
-Đường tròn tâm c đường kính ab.
-Đường tròn tâm a bán kính ab. Lúc này lisp dừng lại và hỏi số lượng bạn nhập vào lisp tiếp tục array cái hình tròn này ra theo số mà bạn nhập vào và kết thúc lệnh.

Không có nhận xét nào:

Đăng nhận xét

Người theo dõi