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

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

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ài trước mình đã giới thiệu vòng lặp repeat là vòng lặp đơn giản nhất. Hôm nay mình giới thiệu tiếp vòng lặp có điều kiện. Hàm WHILE.
-Cú pháp như sau:
(while (điều kiện)
(các thao tác lặp lại)
)
-Cách dùng đơn giản nhất như sau:
(while
(các thao tác lặp lại)
)
Đoạn trên có tác dụng nếu nhấn enter thì vòng lặp sẽ dừng lại nếu không các thao tác sẽ được lặp lại. Ví dụ với lisp sau:
-Đây là lisp nguyên mẫu:
(defun c:doanthang ()
(setq a (getpoint "\nChon diem: "))
(setq b (getpoint a"\nChon diem: "))
(command ".line" a b "")
(princ)
)
-Tác dụng hỏi chọn 2 điểm và vẽ đoạn thẳng qua 2 điểm, kết thúc lệnh. Bây giờ bạn muốn lisp tiếp tục hỏi chọn điểm và tiếp tục vẽ đoạn thẳng khi nào nhấn enter thì kết thúc lệnh (giống lệnh line của cad)

(defun c:doanthang ()
(setq a (getpoint "\nChon diem: "))
(setq b (getpoint a"\nChon diem: "))
(command ".line" a b "")
(setq a b)
(while
(setq b (getpoint a"\nChon diem tiep theo : "))
(command ".line" a b "")
(setq a b)
)
(princ)
)
-Hai đoạn lisp trên mình tạm thời bỏ qua phần lưu bắt điểm và undo để bạn dể nhận ra sự thay đổi.
-Bạn lưu ý dòng (setq a b) có tác dụng sau khi vẽ đoạn thẳng từ a tới b thì gán điểm b cho biến a lúc này điểm b trở thành điểm a sau đó chọn tiếp điểm b lại vẽ từ a tới b, lại gán b cho a cứ như vậy. Khi bạn enter thì vòng lặp kết thúc, kết thúc lệnh.
-Tương tự bạn có thể sửa lại lisp đánh cos làm cho chọn được nhiều điểm đánh cao độ trong 1 lần gọi lệnh như sau:





(defun c:cos ()
(command "undo" "be")
(setq motmet (getreal "\nMot met ban ve bang bao nhieu: "))
(setq luubatdiem (getvar "osmode"))
(setq a (getpoint "\nChon diem muon danh cos: "))
(setvar "osmode" 128)
(setq b (getpoint a"\nChon cao do 0.000: "))
(setvar "osmode" 0)
(setq daiab (distance a b))
(setq giatri (/ daiab motmet))
(setq c (list (- (car a) 250) (+ (cadr a) 410)))
(setq trenduoi (- (cadr a) (cadr b)))
(if (= trenduoi 0) (PROGN
(setq dau "%%p ")
)
)
(if (> trenduoi 0) (PROGN
(setq dau "+ ")
)
)
(if (< trenduoi 0) (PROGN
(setq dau "- ")
)
)
(setq noidung (strcat dau (rtos giatri 2 3)))
(command "-style" "tlkt" "VNI-HELVE" "0" "1" "0" "n" "n")
(command ".TEXT" c 250 0 noidung)
(setq timfile (findfile "c:\\tailieukythuat\\dwg\\caodo.dwg"))
(if (= timfile nil) (PROGN
(princ "\nKhong tim thay file caodo.dwg")
)
)
(if (/= timfile nil) (PROGN
(command "INSERT" "c:\\tailieukythuat\\dwg\\caodo.dwg" a 1 1 0)
)
)
(setvar "osmode" luubatdiem)
(while
(setq a (getpoint b"\nChon diem muon danh cos : "))
(setq luubatdiem (getvar "osmode"))
(setvar "osmode" 0)
(setq daiab (distance a b))
(setq giatri (/ daiab motmet))
(setq c (list (- (car a) 250) (+ (cadr a) 410)))
(setq trenduoi (- (cadr a) (cadr b)))
(if (= trenduoi 0) (PROGN
(setq dau "%%p ")
)
)
(if (> trenduoi 0) (PROGN
(setq dau "+ ")
)
)
(if (< trenduoi 0) (PROGN
(setq dau "- ")
)
)
(setq noidung (strcat dau (rtos giatri 2 3)))
(command "-style" "tlkt" "VNI-HELVE" "0" "1" "0" "n" "n")
(command ".TEXT" c 250 0 noidung)
(setq timfile (findfile "c:\\tailieukythuat\\dwg\\caodo.dwg"))
(if (= timfile nil) (PROGN
(princ "\nKhong tim thay file caodo.dwg")
)
)
(if (/= timfile nil) (PROGN
(command "INSERT" "c:\\tailieukythuat\\dwg\\caodo.dwg" a 1 1 0)
)
)
(setvar "osmode" luubatdiem)
)
(command "undo" "end")
(princ)
)

2 nhận xét:

  1. Học hỏi từ hướng dẫn của anh Duy và tham khảo các lisp khác mình viết lisp ghi cao độ. Mình viết gặp lỗi chỗ nào thì khắc phục chố đó nên nó có phần hơi rối rắm. Nhưng đã test thủ chạy ổn mọi người góp ý chỉnh sửa để có thể ngắn gọn và trong sáng hơn.
    PS: block caodo.dwg mình đổi thành cos.dwg
    (defun c:cos (/)
    (command "undo" "be")
    (setq lastos (getvar "osmode"))
    (setq diemchuan (getpoint "\nChon Diem Chuan:"))
    (while (= diemchuan nil)
    (setq diemchuan (getpoint "\nChon Diem Chuan:"))
    )
    (setq tyle (getreal "\nChon Ty Le:"))
    (while (= tyle nil)
    (setq tyle (getreal "\nChon Ty Le Dung:"))
    )
    (setq caodochuan (getreal "\nNhap Cao Do Chuan:"))
    (while (= caodochuan nil)
    (setq caodochuan (getreal "\nNhap Cao Do Chuan:"))
    )
    (while
    (setq diemcaodo (getpoint "\nChon Diem Can Ghi Cao Do:"))
    (while (= diemcaodo nil)
    (setq diemcaodo (getpoint "\nChon Diem Can Ghi Cao Do:"))
    )
    (setq trenduoi (- (cadr diemcaodo) (cadr diemchuan)))
    (if(= trenduoi 0)(progn
    (setq dau "%%p")
    )
    )
    (if(> trenduoi 0)(progn
    (setq dau "+")
    )
    )
    (if(< trenduoi 0)(progn
    (setq dau "")
    )
    )
    (setq caodocantim (+ caodochuan (/ (* trenduoi tyle) 1000)))
    (setq diemghi (list (+ (car diemcaodo) (/ (* 8 tyle) 1000)) (+ (cadr diemcaodo) (/ (* 5 tyle ) 1000))))
    (setq textheight (/ (* 2 tyle) 1000))
    (command "-style" "caodo" "vn_vni.shx" "0" "1" "0" "n" "n" "n")
    (setq timfile (findfile "c:\\dwg\\cos.dwg"))
    (if(= timfile nil)(progn
    (princ "chua tao folder c:\dwg,hay copy file cos.dwg vao thu muc c:\dwg")
    )
    )
    (if(/= timfile nil)(progn
    (command ".text" "j" "m" diemghi textheight "0" (strcat dau (rtos caodocantim 2 3)))
    (command "INSERT" "c:\\dwg\\cos.dwg" diemcaodo (/ tyle 1000) (/ tyle 1000) 0)
    )
    )
    )
    (setvar osmode "lastos")
    (command "undo" "end")
    (princ)
    )

    Trả lờiXóa
  2. Mình đang tập tành viết lisp. Viết lisp bo rồi offset vào trong 110.
    (DEFUN C:bn(/ p1 el)
    (setvar "cmdecho" 0)
    (COMMAND ".-boundary" (SETQ P1 (GETPOINT "\nPICK DIEM :")) "")
    (setq el (entlast))
    (COMMAND "OFFSET" 110 el "_non" p1 "e")
    (command "erase" el "")
    (princ)
    )

    Mình đang muốn cho nó vào vòng lặp while đoạn :
    (While
    (COMMAND ".-boundary" (SETQ P1 (GETPOINT "\nPICK DIEM :")) "")
    (setq el (entlast))
    (COMMAND "OFFSET" 110 el "_non" p1 "e")
    (command "erase" el "")
    )

    Mà nó không chạy nữa. Mình muốn pick vào vùng kín nó offset 110, lại pick sang ô tiếp theo lại 110. Nếu không pick mà nhấn enter thì kết thúc lệnh. Các bác chỉ em với

    Trả lờiXóa

Khi viết nhận xét mong bạn không đứng vai trò nặc danh! Bạn có thể chọn Name/Url trong đó Url là http://duy782006.blogspot.com/ như vậy hay hơn nặc danh bạn nhé.