Thứ Tư, 7 tháng 4, 2010

Hướng dẩn viết lisp bài 17:

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ự!

*Khi chọn đối tượng lại nảy sinh vấn đề nếu lisp hỏi chọn đối tượng mà không có đối tượng nào được chọn hết lúc này doituong có giá trị là nil mà lisp vẩn tiếp tục chạy thì sẽ phát sinh lổi. Nên cần có hàm điều kiện kiểm tra nếu doituong khác nil thì tiếp tục chạy nếu doituong là nil thì báo là không có đối tượng nào và kết thúc lệnh:
-Hàm If là hàm điều kiện nếu như mà là thì. Cú pháp như sau:

(if (điều kiện 1) (PROGN

thì làm công tác 1
)
)
(IF (điều kiện 2) (PROGN
Thì làm công tác 2
)
)

*Các hàm so sánh:
< nhỏ hơn.
> lớn hơn.
<= nhỏ hơn hoặc bằng.
>= lớn hơn hoặc bằng.
= bằng.
/= không bằng.

Bây giờ áp dụng vào lisp trên để kiểm tra đối tượng chọn có giá trị hay không để đưa ra quyết định kết thúc lệnh hay thực hiện lệnh.

(defun c:tlkt ()
(princ "\nChon doi tuong")
(Setq doituong (Ssget))
(if (= doituong nil) (PROGN
(princ "\nKhong tim thay doi tuong nao!")
)
)
(IF (/= doituong nil) (PROGN
(setq a (getpoint "\nChon diem goc: "))
(setq b (getpoint a"\nChon diem den: "))
(setq so (getreal "\nSo lan di chuyen: "))
(setq daiab (distance a b))
(setq dodai (/ daiab so))
(setq gocab (angle a b))
(setq c (polar a gocab dodai))
(setq sol (fix so))
(repeat sol
(command "DELAY" "5000" "")
(command ".MOVE" doituong "" a c)
)
)
)
(princ)
)

-Chạy lệnh:
+Chọn 1 vùng trống nào đó lisp sẽ kết thúc và báo: Khong tim thay doi tuong nao!.
+Chọn có đối tượng lisp sẽ thực hiện như lisp lúc nảy.

Hướng dẩn viết lisp bài 16:

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ờ dùng cái lisp trên sửa lại như sau:
Chọn 1 hoặc nhiều đối tượng có sẳn trên màn hình. Chọn điểm gốc a, chọn điểm đến b, hỏi số lần di chuyển. Move cái đối tượng vừa chọn từ a đến b từ từ với số đoạn di chuyển là số lần vừa nhập.
-Cần biết cú pháp để chọn đối tượng bằng lisp:
(Setq doituong (Ssget))
-Khi dùng dòng trên các đối tượng được chọn sẽ gán cho biến doituong. Để cho đẹp thêm dòng (princ "\nChon doi tuong") trước dòng chọn đối tượng để ghi dòng Chon doi tuong ra dòng lệnh trước khi chọn đối tượng.

(defun c:tlkt ()
(princ "\nChon doi tuong")
(Setq doituong (Ssget))
(setq a (getpoint "\nChon diem goc: "))
(setq b (getpoint a"\nChon diem den: "))
(setq so (getreal "\nSo lan di chuyen: "))
(setq daiab (distance a b))
(setq dodai (/ daiab so))
(setq gocab (angle a b))
(setq c (polar a gocab dodai))
(setq sol (fix so))
(repeat sol
(command "DELAY" "5000" "")
(command ".MOVE" doituong "" a c)
)
(princ)
)

Khi dùng dòng (Setq doituong (Ssget)) để chọn đối tượng thì tất cả các kiểu đối tượng được quét qua sẽ chọn hết nhưng có đôi lúc bạn có nhu cầu chỉ chọn 1 kiểu đối tượng nào đó thôi ví dụ: line, dimension, hatch, insert. . . thì dùng dòng sau:
(setq doituong (ssget '((0 . "text"))))
-Lúc này trong vùng quét của bạn chỉ nhận các đối tượng có kiểu nằm trong ngoặc kép (dòng trên cụ thể là đối tượng kiểu text) là được chọn thôi .

Hướng dẩn viết lisp bài 15:

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ạn lại muốn số lần move text là do bạn nhập vào kia. Áp dụng hàm getreal xem nào:

(defun c:tlkt ()
(setq a (getpoint "\nChon diem viet: "))
(setq b (getpoint a"\nChon diem den: "))
(setq so (getreal "\nSo lan di chuyen: "))
(setq dolon (getvar "viewsize"))
(setq dolonchu (/ dolon 30))
(setq daiab (distance a b))
(setq dodai (/ daiab so))
(setq gocab (angle a b))
(setq c (polar a gocab dodai))
(command "-style" "tlkt" "VNI-HELVE" "0" "1" "0" "n" "n")
(command ".TEXT" "m" a dolonchu 0 "tailieukythuat.com")
(setq sol (fix so))
(repeat sol
(command "DELAY" "5000" "")
(command ".MOVE" "last" "" a c)
)
(command "DELAY" "5000" "")
(command ".ERASE" "last" "")
(princ)
)

Nếu bạn thay dòng:
(setq so (getreal "\nSo lan di chuyen: "))
Bằng dòng:
(setq so (getstring "\nSo lan di chuyen: "))
Thì lisp sẽ lổi ngay mặc dù bạn vẩn nhập vào là số nhưng chuổi thu được bằng hàm getstring không dùng để tính toán với các hàm + - * / được nên dòng
(setq dodai (/ daiab so))
Sẽ không lượng giá được, xuất hiện lổi và xẹtttttttttttttt lisp hỏng. Đây là điểm rất cần lưu ý trong viết lisp.
-Bạn thấy có 1 dòng lạ nửa:
(setq sol (fix so))
Vì vòng lặp repeat đòi hỏi đối số là số nguyên nghĩa là không có phẩy phiếc gì hết. Trong khi bạn nhập số lần di chuyển bằng hàm getreal kết quả lại là số thực ví dụ nhập 10 thì thực chất nó biểu diển trong lisp là dạng 10,000000000000000000000000000000... Bạn dùng hàm fix sẽ làm mất toàn bộ các ký tự sau dấu phẩy lúc này mới dùng kết quả thu được này cung cấp cho vòng lặp repeat được.

Thứ Ba, 6 tháng 4, 2010

Hướng dẩn viết lisp bài 14:

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ự!

Dòm lại cái lisp bài trên bạn sẽ thấy đoạn lặp đi lặp lại 10 lần là quá dài cần có giải pháp thích hợp hơn. Giới thiệu với bạn 1 vòng lặp đơn giản nhất: Vòng lặp Rpeat cú pháp như sau:

(repeat solan
Nội dung cần lặp lại
)
Như vậy đoạn lisp sẽ sửa lại như sau.

(defun c:tlkt ()
(setq a (getpoint "\nChon diem viet: "))
(setq b (getpoint a"\nChon diem den: "))
(setq dolon (getvar "viewsize"))
(setq dolonchu (/ dolon 30))
(setq daiab (distance a b))
(setq dodai (/ daiab 10))
(setq gocab (angle a b))
(setq c (polar a gocab dodai))
(command "-style" "tlkt" "VNI-HELVE" "0" "1" "0" "n" "n")
(command ".TEXT" "m" a dolonchu 0 "tailieukythuat.com")
(repeat 10
(command "DELAY" "5000" "")
(command ".MOVE" "last" "" a c)
)
(command "DELAY" "5000" "")
(command ".ERASE" "last" "")
(princ)
)

Hướng dẩn viết lisp bài 13:

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ự!

Vấn đề là bây giờ bạn muốn cái text đi từ từ thôi nghĩa là khoảng cách di chuyển nhỏ lại nhưng lại mới biết cách xác định trung điểm từ hai điểm. Sau đây mình trình bày thêm 1 cách xác định 1 điểm bằng lisp nửa. Hàm Polar cú pháp như sau:
(setq c (polar a goc dodai)) xác định điểm c từ điểm a với goc và dodai.
Cũng cái lisp trên nhưng bây giờ mổi lần move cái text đi bằng 1/10 khoảng cách ab thôi:

(defun c:tlkt ()
(setq a (getpoint "\nChon diem viet: "))
(setq b (getpoint a"\nChon diem den: "))
(setq dolon (getvar "viewsize"))
(setq dolonchu (/ dolon 30))
(setq daiab (distance a b))
(setq dodai (/ daiab 10))
(setq gocab (angle a b))
(setq c (polar a gocab dodai))
(command "-style" "tlkt" "VNI-HELVE" "0" "1" "0" "n" "n")
(command ".TEXT" "m" a dolonchu 0 "tailieukythuat.com")
(command "DELAY" "5000" "")
(command ".MOVE" "last" "" a c)
(command "DELAY" "5000" "")
(command ".MOVE" "last" "" a c)
(command "DELAY" "5000" "")
(command ".MOVE" "last" "" a c)
(command "DELAY" "5000" "")
(command ".MOVE" "last" "" a c)
(command "DELAY" "5000" "")
(command ".MOVE" "last" "" a c)
(command "DELAY" "5000" "")
(command ".MOVE" "last" "" a c)
(command "DELAY" "5000" "")
(command ".MOVE" "last" "" a c)
(command "DELAY" "5000" "")
(command ".MOVE" "last" "" a c)
(command "DELAY" "5000" "")
(command ".MOVE" "last" "" a c)
(command "DELAY" "5000" "")
(command ".MOVE" "last" "" a c)
(command "DELAY" "5000" "")
(command ".ERASE" "last" "")
(princ)
)

Giải thích:
-Chọn điểm đầu tiên là a, điểm thứ hai là b.
-Đo độ cao màn hình gán cho dolon.
-Lấy dolon chia cho 30 gán cho biến dolonchu.
-Do khoảng cách từ a tới b gán cho biến daiab.
-Chia daiab cho 10 gán cho biến dodai.
-Đo góc ab tạo với trục x gán cho biến gocab.
-Dùng hàm Polar xác định điểm c từ điểm a, đi theo góc gocab với khoảng cách dodai
-Tạo text Style và viết dòng chử tại điểm a độ lớn bằng dolonchu nội dung tailieukythuat.com.
-Dừng 1 lát.
-Move cái text đó từ a đến c.
-Làm hai bước trên 10 lần.
-Dừng 1 lát.
-Xóa cái text đó đi.

Hướng dẩn viết lisp bài 12:

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 từng trường hợp cụ thể bạn có thể định chiều cao chử cho phù hợp với mục đích của bạn bằng cách mặc định độ lớn hoặc hỏi nhập độ lớn. Nhưng khi bạn muốn dùng text để hiển thị 1 thông báo gì đó thì làm sao?
Lúc này phải giải quyết 2 vấn đề:
-Độ lớn của text so với màn hình hiện hành là đảm bảo cho người dùng đọc được thông báo của bạn.
-Sau 1 thời gian nhất định text này phải bị xóa đi.
Mình cung cấp hai hàm để giải quyết:
(setq dolon (getvar "viewsize")) đo kích thước chiều cao màn hình và gán cho biến dolon.
(command "DELAY" "1000" "") dừng lisp trong thời gian nhất định (cứ 1000 là 1 giây, hồi máy cũ thì mình thấy đúng vậy còn cái máy bây giờ mới nó chạy như giặc vậy mình cũng không rỏ là bao lâu nhưng gán đến 10000 thì nó không chịu nửa) sau đó chạy tiếp các dòng lisp phía dưới.

Bây giờ mình viết 1 đoạn lisp vui vui thế này nhé:

(defun c:tlkt ()
(setq a (getpoint "\nChon diem viet: "))
(setq b (getpoint a"\nChon diem den: "))
(setq dolon (getvar "viewsize"))
(setq dolonchu (/ dolon 30))
(setq c (list (/ (+ (car a) (car b)) 2) (/ (+ (cadr a) (cadr b)) 2)))
(command "-style" "tlkt" "VNI-HELVE" "0" "1" "0" "n" "n")
(command ".TEXT" "m" a dolonchu 0 "tailieukythuat.com")
(command "DELAY" "5000" "")
(command ".MOVE" "last" "" a c)
(command "DELAY" "5000" "")
(command ".MOVE" "last" "" a c)
(command "DELAY" "5000" "")
(command ".ERASE" "last" "")
(princ)
)

Giải thích:
-Chọn điểm đầu tiên là a, điểm thứ hai là b.
-Đo độ cao màn hình gán cho dolon.
-Lấy dolon chia cho 30 gán cho biến dolonchu.
-Từ a và b suy ra điểm c là trung điểm ab.
-Tạo text Style và viết dòng chử tại điểm a độ lớn bằng dolonchu nội dung tailieukythuat.com.
-Dừng 1 lát.
-Move cái text đó từ a đến c.
-Dừng 1 lát.
-Lại Move cái text đó từ a đến c. Lúc này cái text đang nằm ở c nên nó sẽ được chuyển đến b.
-Dừng 1 lát.
-Xóa cái text đó đi.

Hướng dẩn viết lisp bài 11:

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ờ trước dòng text thể hiện khoảng cách này bạn muốn thêm chử L= ví dụ L=3621.025 thì sao???
-Giải pháp dùng hàm ghép chuổi, hàm: strcat cú pháp như sau:
(setq ndthem (strcat "L=" ndlc))
Trong đó phần trong ngoặc kép là phần muốn thêm vào chuổi.


(defun c:doanthang ()
(setq a (getpoint "\nChon diem: "))
(setq b (getpoint a"\nChon diem: "))
(setq dt (getstring "\nDo lon:"))
(setq nd (distance a b))
(setq ndlc (rtos nd 2 3))
(setq ndthem (strcat "L=" ndlc))
(setq c (list (/ (+ (car a) (car b)) 2) (/ (+ (cadr a) (cadr b)) 2)))
(command "-style" "tlkt" "VNI-HELVE" "0" "1" "0" "n" "n")
(command ".TEXT" "m" b dt 0 ndthem)
(princ)
)

Với bây nhiêu thứ bạn có thể viết được cái lisp đánh cao độ rồi đấy. Linh hoạt 1 chút với vài hàm tính toán + - * / là xong ngay. (Phần viết lisp đánh cos mình sẽ quay lại sau, đến khi nào nói đến các hàm điều kiện đã).


Nhân nói về text và chuổi mình cung cấp thêm 1 vài hàm liên quan:
(setq so (getreal "\nNhap so: ")) nhập vào 1 chuổi dạng số có thể dùng để tính toán bằng các hàm + - * / .

(setq nd (getstring "\nNoi dung:")) nhập vào 1 chuổi dạng text có thể là số nhưng không dùng để tính toán được.

(setq sochu (strlen chuoicandem)) lấy ra giá trị số lượng ký tự của chuổi chuoicandem.

(setq chuoicon (substr chuoime vitridoc sokytudoc)) lấy chuoicon từ chuoime vị trí lấy bắt đầu từ vitridoc với số lượng trích bằng sokytudoc. Ví dụ
(setq chuoicon (substr "www.tailieukythuat.com" 5 14)) thì chuoicon = tailieukythuat

(setq ndhoa (strcase ndgoc)) làm chuổi ndgoc trở thành ký tự viết hoa toàn bộ. Ví dụ:
(setq kyhieu (strcase (getstring 5"\nTen truc: "))) lúc này chuổi nhập vào dù bạn gỏ hoa hay thường điều thành chử hoa hết. (cái này áp dụng cho lisp đánh trục kích thước vì trục kích thước thì các chữ luôn viết hoa).