Chuyển đến nội dung
Diễn đàn CADViet
ssg

Hướng dẫn lập trình Lisp

Các bài được khuyến nghị

Bác cho cái "u" vào hàm bẫy lỗi luôn xem có được không ^^

Cái "u" này cho vào hàm bẫy lỗi thì nó:

1). Giải quyết được vấn đề: khi chương trình tự gây lỗi nó sẽ OK.

2). Không giải quyết được vấn đề: khi user bấm esc nó chẳng chịu OK.

Mà tại sao biến hệ thống thì U được còn các lệnh thì không U được nhỉ???

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Bác ngó qua cái ví dụ này xem sao :

(defun c:test ()
(setvar "cmdecho" 0)
(command "undo" "Begin")

(defun testerr (s)
(if (/= s "Function cancelled")
(princ (strcat "\nError: " s))
)
(command "undo" "End")

(command "U")
(command "U")
(command "ucs" "")
(setq *error* olderr)
(princ " \n..........Tro ve nhu truoc ne....
")
(princ)
)

(setq olderr *error*
*error* testerr)



(command "circle" '(5.0 6.0) 4.0)
(command "polygon" "" '(6.0 4.0) "" 2.0)
(command "circle" '(6.0 4.0) 5.0)
(command "extrude" "L" "" 6.0 "")
(setq cx (entlast))
(command "slice" cx "" '(6.0 4.0 0.0) '(6.0 6.0 0.0) '(6.0 4.0 1.0) '(4.0
4.0 0.0))
;; (rotate3d cx "" '(6.0 4.0 0.0) '(6.0 5.0 0.0) 15)
(command "move" cx "" '(6.0 4.0) '(9.0 4.0))
(command "vpoint" "-1,-1,1")
(command "ucs" "v")
(command "circle" '(1.0 2.0) 3.0)
(command "circle" '(3.0 3.0) 2.0)
(princ "\n .....Bac an Esc xem no nhu the nao :")
(command "circle" pause pause)
(command "ucs" "")
(command "plan" "")
(command "undo" "End")
)

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Bác ngó qua cái ví dụ này xem sao :

(defun c:test ()
(setvar "cmdecho" 0)
(command "undo" "Begin")

(defun testerr (s)
(if (/= s "Function cancelled")
(princ (strcat "\nError: " s))
)
(command "undo" "End")

(command "U")
(command "U")
(command "ucs" "")
(setq *error* olderr)
(princ " \n..........Tro ve nhu truoc ne....
")
(princ)
)

(setq olderr *error*
*error* testerr)



(command "circle" '(5.0 6.0) 4.0)
(command "polygon" "" '(6.0 4.0) "" 2.0)
(command "circle" '(6.0 4.0) 5.0)
(command "extrude" "L" "" 6.0 "")
(setq cx (entlast))
(command "slice" cx "" '(6.0 4.0 0.0) '(6.0 6.0 0.0) '(6.0 4.0 1.0) '(4.0
4.0 0.0))
;; (rotate3d cx "" '(6.0 4.0 0.0) '(6.0 5.0 0.0) 15)
(command "move" cx "" '(6.0 4.0) '(9.0 4.0))
(command "vpoint" "-1,-1,1")
(command "ucs" "v")
(command "circle" '(1.0 2.0) 3.0)
(command "circle" '(3.0 3.0) 2.0)
(princ "\n .....Bac an Esc xem no nhu the nao :")
(command "circle" pause pause)
(command "ucs" "")
(command "plan" "")
(command "undo" "End")
)

Ketxu thử nhấn esc thật nhanh trước khi "Bac an Esc xem no nhu the nao" xem nó như thế nào. Chưa được Ket ơi!

Thân thương!

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Hệch hệch, cái này ket nghiên cứu, chỉ lấy ví dụ thôi. Bác thử định nghĩa lại luôn *error*, không cần reset nữa, rồi để hàm đó load bên ngoài xem sao..Bác ấn nhanh quá có khi cái hàm testerr chẳng kịp được load, hoặc chẳn kịp được gán cũng nên. Với lại Undo nó cũng khó hiểu lắm ^^

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

a ssg ơi cho em hỏiem mới tâp tành vào nghề XD trình độ cad của em còn yếu,nên em muốn hỏi anh em nên bắt đầu lisp từ đâu và học lisp có được ko xin bác chỉ giáo cho em nhé,em cám ơn nhiều.nếu bác nào biết chỉ cho em nha,em cám ơn mọi người

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

a ssg ơi cho em hỏiem mới tâp tành vào nghề XD trình độ cad của em còn yếu,nên em muốn hỏi anh em nên bắt đầu lisp từ đâu và học lisp có được ko xin bác chỉ giáo cho em nhé,em cám ơn nhiều.nếu bác nào biết chỉ cho em nha,em cám ơn mọi người

Hề hề hề,

Muốn học lisp thời nên bắt đầu học từ ..... CAD, và học thời chắc chắn là được, lâu mau ấy là còn tùy vào tinh thần và thái độ học tập của bạn.

Bạn cố gắng hiểu kỹ các thủ thuật trong CAD, đọc thêm các ví dụ về lisp được ứng dụng vào CAD để từ đó hiểu ra cách tạo ra một lisp. Thế rồi lọ mọ làm lisper vài cái linh tinh cho nó sướng cái bụng, và cứ thế , cứ thế. sẽ thành công.

Hề hề hề,.

Các tài liệu về lisp thì có khá nhiều, ngay diễn đàn này cũng có kha khá đấy. Bạn thử search xem nhé. Cứ gỏ từ khóa AUTOLISP rồi enter sẽ ra một đống, tùy bạn chọn.

Hề hề hề,....

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Các bác giúp e tí,e có 1 đoạn lisp như sau:

(setq btbvc 30)

(setq BV (getreal (strcat "Chieu day lop bao ve < " (itoa btbvc) " >: ")))

Đoạn này thì tự nó hiện lên con số 30 theo ý của e,chỉ enter là đưọc.Nhưng nếu e đổi lại như dưới đây:

(setq btbvc 30)

(setq BV (* (getreal (strcat "Chieu day lop bao ve < " (itoa btbvc) " >: ")) 5))

Nó vẫn hiện 30 nhưng enter luôn thì nó báo lỗi.Phải nhập số vào thì nó mới hiểu.Mong các bác xem giúp giùm.Thanks.

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Không đoạn nào của bạn đúng ý đồ cả. Lisp thực hiện từ trong ra ngoài. Vậy hãy xem thứ tự những gì xảy ra :

(setq btbvc 30) ; Gán btbvc = 30

(itoa btbvc) ; Lấy String của btbvc : "30"

(strcat "Chieu day lop bao ve < " (itoa btbvc) " >: ") ; Nối chuỗi "Chieu day lop bao ve < " + "30" + " >: " thành

"Chieu day lop bao ve < 30 >: "

(getreal (strcat "Chieu day lop bao ve < " (itoa btbvc) " >: ")) ;Lấy giá trị Real với dòng nhắc "Chieu day lop bao ve < 30 >: "

Ở bước này, nếu bạn Enter luôn, ta sẽ được Nil

Và đến bước tiếp theo :

(* (getreal (strcat "Chieu day lop bao ve < " (itoa btbvc) " >: "))5)

;Máy sẽ thực hiện phép tính (* nil 5) => Lỗi, nil không phải là số nên không nhân được

Để thực hiện đúng, bạn cần tách nó ra thêm bước kiểm tra giá trị nhập vào là Nil hay không 1 cách dễ hiểu như sau :

(setq btbvc 30)

(If (setq BV (getreal (strcat "Chieu day lop bao ve < " (itoa btbvc) " >: "))) ;Kiểm tra BV = Nil hay không

(setq BV (* BV 5)) ; Nếu Không, nhân nó với 5

(setq BV (* btbvc 5)) ; Nếu BV = Nil, đặt lại giá trị cho nó bằng btbvc * 5 (hoặc gì đó tùy bạn)

)

Hoặc :

(setq BV (* 5 (cond ((getreal (strcat "Chieu day lop bao ve < " (itoa btbvc) " >: "))) (btbvc))))
  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

cho em hỏi bác tí.e mói tập autolisp.Em có 1 đường thẳng qua p1 p2.em muốn dùng hàm ssget để chọn đường thẳng này sau đó offset nó về phía bên phải với khoảng cách là 100 thì viết như thế nào ạ.

-Câu hỏi thứ 2 là tại sao em dùng hàm array thì nó cho chọn đối tượng là last(tức đối tượng vừa tạo ra)còn hàm offset lại không cho chọn đối tượng last ạ

(command ".line" p9 p10 "" )

(command "offset" 100 "last" p2 ""),

Nếu bây giờ e dùng hàm array thay hàm offset thì e muốn array các đối tượng này theo góc pi/2 thì điền thông số này vào đâu trong hàm ạ

(command ".line" p9 p10 "" )

(command ".array" "last" ???? "")

Cảm ơn mấy bác.Mong mấy bác giúp đỡ

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Chào bạn ^^

Đi qua 2 điểm mà lại là 2 đường thẳng cơ à bạn :)

- SSget để chọn nhiều Line : (ssget (list (cons 0 "LINE")))

- Chọn 1 Line 2 đầu đã biết : (ssget p1 p2)

- CHọn 1 đối tượng : (car (entsel) )

- Bên phải của bạn CAD không xác định được

- Thay vì dùng "last" bạn hãy dùng (entlast)

- Với các hàm dùng (command...) bạn hãy thao tác lệnh như ý bạn muốn, rồi bật F2 để xem các bước nhập của nó, rồi ghi lại vào hàm

Chúc bạn thành công

  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

hi.em nhầm.1 đường thui.cảm ơn bác nhìu.

-Nhân đây e muốn hỏi e có 3 đường thẳng d1,d2,d3 cắt nhau.Em muốn trim đường d1 đoạn nằm trong 2 đường kia.Nhưng em không biết định hướng sao để nó biết trim bên trong hay bên ngoài.cảm ơn các bác

-Thứ 2 nữa là e muốn ghi một text dọc theo 2 đường d1,d2 với khoang cách nhất định thì thường làm theo cách nào hả các bác.Với lại cái text này dc ghi theo một số nhập vào từ trước nên nó ra hàng thập phân lên đến 14 chữ số 0.Phài làm sao nhỉ??

-Cuối cùng e muốn hỏi là em muốn ghi kích thước theo ý muốn của mình (chứ không phải số đo thực)thì dùng lệnh gì nhỉ

Cảm ơn các bác

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

cho em hỏi cách thực hiện các lệnh cad trong lisp,vd: ( command "lệnhcad" các thông số) ,các thông số của lệnh rất đa dạng,em có thể tìm ở đâu ạ

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

cho em hỏi cách thực hiện các lệnh cad trong lisp,vd: ( command "lệnhcad" các thông số) ,các thông số của lệnh rất đa dạng,em có thể tìm ở đâu ạ

Bạn thực hiện thao tác thủ công lệnh đó. Các thông số chính là các bước bạn nhập vào :)

Ví dụ lệnh Circle đơn giản, CAD yêu cầu bạn nhập vào tâm, rồi đến bán kính

=> (command "CIRCLE" Tâm Bán_Kính)

- Ở đây Tâm là 1 điểm trên màn hình CAD. Vậy bạn có thể lấy điểm này bằng cách chỉ định Point cho tâm bằng hàm getpoint

=> Tâm = (getpoint "\nTam")

- Bán kính là 1 số thực, bạn có thể nhập trực tiếp vào hoặc lấy bằng hàm getreal, getdist

=> Bán kính = (getreal "\nBan kinh :")

Cuối cùng cái bạn cần là :

(command "circle" (getpoint "\nTam") (getdist "\nBan kinh :"))

Hoặc đơn giản là chỉ định luôn giá trị của 2 thông số :

(command "circle" '(0 0 0) 10) ; Tạo đường tròn bán kính 10 tại tâm 0,0,0

Gluck :wub:

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Tự tay mình lập một chương trình Lisp có gì khác so với nhờ ai đó làm? Chưa cần xét kết quả, điểm khác nhau rất cơ bản là bạn sẽ có được cái cảm giác rất là khoái chí (không thể diễn tả) khi chạy thử chương trình.

Ssg lập topic này không ngoài mục đích tạo điều kiện cho các bạn tự mình tìm hiểu và khám phá cái cảm giác "khoái chí không thể diễn tả" nói trên.

Với tinh thần "Share is Receive", ssg cũng mong các bạn đã thành thạo Lisp quan tâm giúp đỡ các bạn mới để cộng đồng Lisp của CadViet ngày càng đông vui và tạo được nhiều chương trình hữu ích.

Để bắt đầu, ssg post lại một bài viết cũ, nhưng có lẽ vẫn còn mới đối với một số bạn. Hy vọng sẽ giúp được chút gì đó cho các bạn mới tiếp cận với Lisp:

 

http://www.cadviet.c...les/Relax_1.zip

 

Download, giải nén rồi đọc file *.doc

cám ơn anh ssg rất nhiều!

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Mình có được đoạn code này ở trang 10.

 

(defun gocmin (p lst / goc gmin pluu)
 (foreach p1 lst
(setq goc (angle p p1))
(if (or (not gmin) (> gmin goc))
 	(setq gmin goc
	pluu p1
 	)
)
 )
 pluu
)
;;;-------------------------------------------
(defun SS-aobjlst (ss / c L)
 (setq c -1)
 (repeat (sslength ss)
(setq L (cons (vlax-ename->vla-object (ssname ss (setq c (1+ c))))
L
	)
)
 )
 (reverse L)
)
;;;-------------------------------------------
(defun entmkLine (p1 p2)
 (entmake (list '(0 . "line")
  (cons 10 p1)
  (cons 11 p2)
)
 )
)
;;;-------------------------------------------
(defun c:dglo (/ ss objlst tap_ins pd pc pt pchk1 Lst)
 (command "undo" "be")
 (command "ucs" "")
 (setq ss (ssget '((0 . "POINT")))
tap_ins (list)
 )
 (setq objlst (SS-aobjlst ss))
 (setq tap_ins (mapcar '(lambda (x) (vlax-get x 'Coordinates)) objlst))
 (setq tap_ins (mapcar '(lambda (x) (trans x 0 1)) tap_ins))
(setq tap_ins (vl-sort tap_ins
'(lambda (x y)
(if (= (cadr x) (cadr y))
(< (car x) (car y))
(< (cadr x) (cadr y))
)
)
)
)
 (setq pd	(car tap_ins)
pc	(last tap_ins)
pt	pd
pchk1 nil
 )
 (while (not (eq pchk1 pc))
(setq lst (vl-remove pt tap_ins))
(setq pchk1 (gocmin pt lst))
(entmkLine pt pchk1)
(setq pt pchk1)
 )
 (while (not (eq pchk1 pd))
(setq lst (vl-remove pt tap_ins))
(setq pchk1 (gocmin pt lst))
(entmkLine pt pchk1)
(setq pt pchk1)
(foreach p tap_ins
 	(if (<= (cadr pt) (cadr p))
(setq tap_ins (vl-remove p tap_ins))
 	)
)
 )
 (command "undo" "en")
 (princ)
)

 

Các bạn giúp mình tạo 1 hàm con vẽ đa giác lồiLWPOLYLINE, kết quả trả về là entname của đa giác lồi vẽ bằng LWPOLYLINE

cách gọi lệnh: (dglo lst)

trong đó: dglo là tên hàm con. lst là list các tập hợp điểm.

Thanks!

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Mình có được đoạn code này ở trang 10.

...

Các bạn giúp mình tạo 1 hàm con vẽ đa giác lồiLWPOLYLINE, kết quả trả về là entname của đa giác lồi vẽ bằng LWPOLYLINE

cách gọi lệnh: (dglo lst)

trong đó: dglo là tên hàm con. lst là list các tập hợp điểm.

Thanks!

Đây bạn:

(defun dglo (lst)
(entmakex (append (list (cons 0 "LWPOLYLINE") (cons 100 "AcDbEntity") (cons 100 "AcDbPolyline") (cons 90 (length lst)) (cons 70 1))
                               	(mapcar (function (lambda (p) (cons 10 p))) lst))))

  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Đây bạn:

......

 

Hehe. sorry vì mình ko nói rõ ra về cái list.

Khi gọi hàm con này với đối số là 1 list tập hợp các điểm thì sẽ cho ra 1 LWPOLYLINE là đa giác lồi có diện tích lớn nhất, Bạn có thể chạy thử lisp trên mình post để hiểu rõ hơn. Thank bạn.

 

Mình chưa có Cad để thử lisp của bạn nhưng đọc nó thì mình thấy nếu trong lst mà các điểm xếp lộn xộn thì có thể kết quả ko đúng.

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Hehe. sorry vì mình ko nói rõ ra về cái list.

Khi gọi hàm con này với đối số là 1 list tập hợp các điểm thì sẽ cho ra 1 LWPOLYLINE là đa giác lồi có diện tích lớn nhất, Bạn có thể chạy thử lisp trên mình post để hiểu rõ hơn. Thank bạn.

Mình chưa có Cad để thử lisp của bạn nhưng đọc nó thì mình thấy nếu trong lst mà các điểm xếp lộn xộn thì có thể kết quả ko đúng.

Có phải ý bạn là: tạo đa giác lồi, có diện tích nhỏ nhất, chứa tất cả các điểm của lst (các điểm của lst có thể nằm ở đỉnh, nằm trên cạnh, hoặc nằm bên trong đa giác lồi, nhưng không được nằm ngoài)?

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Em hỏi tý, em muốn viết vòng lặp để offset 1 đường với các đoạn cho trc

vd: offset line A ra các đoạn 2000,3000,4000. Dùng vòng lặp nhưng khai báo như thế để nó hiểu là offset từ Line A thành các đoạn 2000 5000 6000 ạ

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Em hỏi tý, em muốn viết vòng lặp để offset 1 đường với các đoạn cho trc

vd: offset line A ra các đoạn 2000,3000,4000. Dùng vòng lặp nhưng khai báo như thế để nó hiểu là offset từ Line A thành các đoạn 2000 5000 6000 ạ

Với số lần lặp biết trước, bạn sử dụng vòng lặp Repeat hoặc Foreach

Bạn có thể làm như sau:

1. Khởi tạo biến (setq lst '(2000 3000 4000) i 0 kc 0)

2. Vào vòng Repeat (length lst)

- offset line A ra 1 đoạn bằng (setq kc (+ kc (nth i lst)))

- Tăng biến đếm lên 1 đơn vị (setq i (1+ i))

 

Mình viết gợi ý vậy. Bạn thử làm xem

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Như vậy ko có tối ưu thuât toán bạn ơi, với số khoảng cách chua biết và số đoạn cũng chưa biết thì hàm list ko đc, ý mình là dùng while với mỗi lần nhập khoảng cách thì sẽ tự offset 1 đoạn = kc trc đó + kc mới nhập, mình đang rối chỗ khai báo biến T_T

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Em hỏi tý, em muốn viết vòng lặp để offset 1 đường với các đoạn cho trc

vd: offset line A ra các đoạn 2000,3000,4000. Dùng vòng lặp nhưng khai báo như thế để nó hiểu là offset từ Line A thành các đoạn 2000 5000 6000 ạ

1 ví dụ để bạn dễ hình dung:

(defun C:HA ()
(setq lst '(1000 2000 3000))	;list cac khoang cach can offset.
(setq obj (vlax-ename->vla-object (car (entsel "\nChon Line de offset: "))))
(foreach n lst
 (vla-offset obj n))
(princ))

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

1 ví dụ để bạn dễ hình dung:

(defun C:HA ()
(setq lst '(1000 2000 3000))	;list cac khoang cach can offset.
(setq obj (vlax-ename->vla-object (car (entsel "\nChon Line de offset: "))))
(foreach n lst
 (vla-offset obj n))
(princ))

Cám ơn bạn đã trả lời, như vậy là các kc đã biết trc và số lần cũng vậy, ý mình là dùng while để mỗi lần nhập khoảng cách là no hiểu offset 1 đoạn = đoạn mới nhập + đoạn trc đó, Thân

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

While đây:

(defun C:HA2 ( / obj kc1 kc2)
(setq obj (vlax-ename->vla-object (car (entsel "\nChon Line de offset: "))))
(setq kc1 0)
(while (setq kc2 (getreal "\nKhoang cach offset: "))
 (vla-offset obj (setq kc1 (+ kc1 kc2))))
(princ))

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Nhập đến đâu offset đến đấy thì bạn chỉ cần thay đổi đối tượng cần offset sau mỗi vòng lặp while,, tức là đối tượng entlast, hoặc thay đổi khoảng cách. Có rất nhiều cách

;(defun c:sth()
(setq en (vlax-ename->vla-object (car (entsel "\nDoi tuong :"))))
(while (setq kc (getreal "\nKhoang cach :"))
(vla-offset en kc)
(setq en (vlax-ename->vla-object (entlast)))
)
;)end defun

  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Tạo một tài khoản hoặc đăng nhập để nhận xét

Bạn cần phải là một thành viên để lại một bình luận

Tạo tài khoản

Đăng ký một tài khoản mới trong cộng đồng của chúng tôi. Điều đó dễ mà.

Đăng ký tài khoản mới

Đăng nhập

Bạn có sẵn sàng để tạo một tài khoản ? Đăng nhập tại đây.

Đăng nhập ngay

×