Đến nội dung


Hình ảnh
- - - - -

Hỏi về LISP


  • Please log in to reply
22 replies to this topic

#1 ustoichivost

ustoichivost

    biết vẽ circle

  • Members
  • PipPip
  • 33 Bài viết
Điểm đánh giá: 6 (bình thường)

Đã gửi 15 August 2007 - 09:25 PM

Mình mới học AutoLISP viết một chương trình đơn giản,nhưng không hiểu lỗi ở chỗ nào.Các bạn giúp mình với nhé.Cảm ơn nhiều:

(defun c:Triangle(/ P1 P2 P3)
(setq P1 (getpoint "\n Vao dinh thu nhat"))
(setq P2 (getpoint "\n Vao dinh thu hai"))
(setq P3 (getpoint "\n Vao dinh thu ba "))
(command "line" P1 P2 P3 "c")
)
;the end
  • 0

#2 Nguyen Hoanh

Nguyen Hoanh

    biết lệnh adcenter

  • Moderator
  • PipPipPipPipPipPipPip
  • 4105 Bài viết
Điểm đánh giá: 4495 (đỉnh cao)

Đã gửi 15 August 2007 - 10:15 PM

Mình mới học AutoLISP viết một chương trình đơn giản,nhưng không hiểu lỗi ở chỗ nào.Các bạn giúp mình với nhé.Cảm ơn nhiều:

(defun c:Triangle(/ P1 P2 P3)
(setq P1 (getpoint "\n Vao dinh thu nhat"))
(setq P2 (getpoint "\n Vao dinh thu hai"))
(setq P3 (getpoint "\n Vao dinh thu ba "))
(command "line" P1 P2 P3 "c")
)
;the end

Chạy tốt, chẳng lỗi ở chỗ nào cả!
  • 0

#3 ustoichivost

ustoichivost

    biết vẽ circle

  • Members
  • PipPip
  • 33 Bài viết
Điểm đánh giá: 6 (bình thường)

Đã gửi 16 August 2007 - 12:15 PM

Chạy tốt, chẳng lỗi ở chỗ nào cả!


Nhưng tạo sao em load thì xuất hiện thông báo sau:
_appload triangle.lsp successfully loaded
; error: syntax error

Thế là thế nào ạ?
  • 0

#4 Nguyen Hoanh

Nguyen Hoanh

    biết lệnh adcenter

  • Moderator
  • PipPipPipPipPipPipPip
  • 4105 Bài viết
Điểm đánh giá: 4495 (đỉnh cao)

Đã gửi 16 August 2007 - 12:45 PM

Nhưng tạo sao em load thì xuất hiện thông báo sau:
_appload triangle.lsp successfully loaded
; error: syntax error

Thế là thế nào ạ?

Bạn thử download (bằng cách phải chuột rồi chọn save link as hoặc save target as) file này về rồi appload xem sao: http://www.cadviet.com/upfiles/triangle.lsp
Đây là file mã lệnh của bạn tôi đã save thành 1 file lisp. Tôi load file này không có một lỗi nào cả.
  • 0

#5 ustoichivost

ustoichivost

    biết vẽ circle

  • Members
  • PipPip
  • 33 Bài viết
Điểm đánh giá: 6 (bình thường)

Đã gửi 16 August 2007 - 02:21 PM

Bạn thử download (bằng cách phải chuột rồi chọn save link as hoặc save target as) file này về rồi appload xem sao: http://www.cadviet.com/upfiles/triangle.lsp
Đây là file mã lệnh của bạn tôi đã save thành 1 file lisp. Tôi load file này không có một lỗi nào cả.


Cam on anh nha.OK rui!
Nhân đây em cũng xin hỏi luôn là nếu như em muốn biết các thông số của các lệnh trong AutoCad thì phải làm thế nào? Chẳng hạn như là em muốn dùng AutoLisp để vẽ một đường tròn khi biết bán kính và tâm thì có thể viết:

(command "circle" P1 r)
; P1 -tam duong tron
;r-ban kinh duong tron
;được không ạ?
; hay là phải tìm hiểu các biến hệ thống của AutoCad như Chamfera hay la chamferb chamferc chamferd của lệnh Chamfer ạ?
  • 0

#6 ssg

ssg

    biết lệnh adcenter

  • Vip
  • PipPipPipPipPipPipPip
  • 1228 Bài viết
Điểm đánh giá: 1087 (rất tốt)

Đã gửi 17 August 2007 - 07:48 AM

Cam on anh nha.OK rui!
Nhân đây em cũng xin hỏi luôn là nếu như em muốn biết các thông số của các lệnh trong AutoCad thì phải làm thế nào? Chẳng hạn như là em muốn dùng AutoLisp để vẽ một đường tròn khi biết bán kính và tâm thì có thể viết:

(command "circle" P1 r)
; P1 -tam duong tron
;r-ban kinh duong tron
;được không ạ?
; hay là phải tìm hiểu các biến hệ thống của AutoCad như Chamfera hay la chamferb chamferc chamferd của lệnh Chamfer ạ?


Có vẻ như bạn còn lúng túng về phương pháp học lisp, ssg có vài gợi ý:
1) Có thể nhập trực tiếp biểu thức lisp tại dòng nhắc command. Ví dụ trên:
Command: (setq P1 (list 100 100) r 20). Kết quả: P1 được gán toạ độ 100, 100 và r được gán giá trị 20
Command: (command "circle" p1 r). Kết quả: Acad vẽ vòng tròn tâm (100,100) bán kính 20
2) Nếu không rõ hoặc không nhớ các tham số của một lệnh, bạn có thể dùng biến pause. Ví dụ:
Command: (command "circle" pause) . Căn cứ vào các yêu cầu tiếp theo của Acad, bạn sẽ biết nó cần tham số gì.
3) Nếu bạn đã biết về ss và entity, có thể dùng hàm entmake để tạo đối tượng thay vì dùng command. Ví dụ:
Command: (entmake (list (cons 0 "CIRCLE") (cons 10 (list 100 120)) (cons 40 30))) . Kết quả: vẽ vòng tròn tâm (100, 120), bán kính 30.
4) Lật Help ra xem, không thiếu thứ gì!
  • 0

#7 ustoichivost

ustoichivost

    biết vẽ circle

  • Members
  • PipPip
  • 33 Bài viết
Điểm đánh giá: 6 (bình thường)

Đã gửi 22 August 2007 - 06:18 PM

Em viết một đoạn Lisp chia đoạn thẳng cho trước với tỉ lệ k như sau:

(defun c:chiadt (/ k)
(setq k -1
P1 (getpoint "\n Nhap diem dau cua doan thang")
P2 (getpoint "\n Nhap diem cuoi cua doan thang")
)
(while (= k -1)
(setq k (getreal "\n Nhap ti le"))
)
(setq X1 (car P1)
Y1 (cdr P1)
Z1 (cdr (cdr P1))
X2 (car P2)
Y2 (cdr P2)
Z2 (cdr (cdr P2))
)
(setq X3 (/ (+ (* k X2) X1) (1+ k))
Y3 (/ (+ (* k Y2) Y1) (1+ k))
Z3 (/ (+ (* k Z2) Z1) (1+ k))
)
(setq P3 (list ( X3 Y3 Z3)))
(command "point" P3)
(princ)
)

;het
;nhung khong hieu sao may lai bao loi :bad argument type
;khong hiu
;cac anh xem ho em voi
  • 0

#8 vndesperados

vndesperados

    biết lệnh xref

  • Members
  • PipPipPipPipPipPipPip
  • 547 Bài viết
Điểm đánh giá: 253 (khá)

Đã gửi 24 August 2007 - 08:04 AM

Em viết một đoạn Lisp chia đoạn thẳng cho trước với tỉ lệ k như sau:

(defun c:chiadt (/ k)
(setq k -1
P1 (getpoint "\n Nhap diem dau cua doan thang")
P2 (getpoint "\n Nhap diem cuoi cua doan thang")
)
(while (= k -1)
(setq k (getreal "\n Nhap ti le"))
)
(setq X1 (car P1)
Y1 (cdr P1)
Z1 (cdr (cdr P1))
X2 (car P2)
Y2 (cdr P2)
Z2 (cdr (cdr P2))
)
(setq X3 (/ (+ (* k X2) X1) (1+ k))
Y3 (/ (+ (* k Y2) Y1) (1+ k))
Z3 (/ (+ (* k Z2) Z1) (1+ k))
)
(setq P3 (list ( X3 Y3 Z3)))
(command "point" P3)
(princ)

;het
;nhung khong hieu sao may lai bao loi :bad argument type
;khong hiu
;cac anh xem ho em voi



(setq P3 (list X3 Y3 Z3))
hoac
(setq P3 '(X3 Y3 Z3))
  • 0

#9 ustoichivost

ustoichivost

    biết vẽ circle

  • Members
  • PipPip
  • 33 Bài viết
Điểm đánh giá: 6 (bình thường)

Đã gửi 24 August 2007 - 04:25 PM

Em đã sửa nhưng mà vẫn không được.Chẳng hạn nhập vào :
Điểm đầu:P1(0,0,0)
Điểm cuối:P2(50,50,0)
Tỉ lệ :1
thì nó xuất hiện dòng báo lối như sau:

;error : bad argument type :numberp(50.0 0.0)

  • 0

#10 Nguyen Hoanh

Nguyen Hoanh

    biết lệnh adcenter

  • Moderator
  • PipPipPipPipPipPipPip
  • 4105 Bài viết
Điểm đánh giá: 4495 (đỉnh cao)

Đã gửi 24 August 2007 - 05:06 PM

Em đã sửa nhưng mà vẫn không được.Chẳng hạn nhập vào :
Điểm đầu:P1(0,0,0)
Điểm cuối:P2(50,50,0)
Tỉ lệ :1
thì nó xuất hiện dòng báo lối như sau:

;error : bad argument type :numberp(50.0 0.0)

Chữ Điểm đầu:P1 nằm đâu trong đoạn mã trên của bạn?

Sở dĩ tôi hỏi vậy là vì tôi thắc mắc không hiểu trong dòng 'Điểm cuối:P2(50,50,0)' thì đâu là dòng nhắc lệnh, đâu là mã bạn nhập vào. Nhưng cho dù thế nào đi nữa, nhập liệu tọa độ điểm từ ACAD không bao cần có dấu ngoặc - nếu có dấu ngoặc là sai.
Nếu là nhập tọa độ, bạn chỉ cần nhập 0,0,0 hoặc pick điểm.
  • 0

#11 ustoichivost

ustoichivost

    biết vẽ circle

  • Members
  • PipPip
  • 33 Bài viết
Điểm đánh giá: 6 (bình thường)

Đã gửi 24 August 2007 - 06:24 PM

À không.Ý em ở đây là :
Điểm đầu P1(0,0,0):nghĩa là khi nhập lệnh chiadt thì xuất hiện dòng nhắc:
Nhap diem dau cua doan thang:(click vào điểm P1)

Nhap diem cuoi cua doan thang:(click vào điểm P2)

Nhap ti le:1

thì xuất hiện dòng nhắc
; error: bad argument type: numberp: (50.0 0.0)

  • 0

#12 Nguyen Hoanh

Nguyen Hoanh

    biết lệnh adcenter

  • Moderator
  • PipPipPipPipPipPipPip
  • 4105 Bài viết
Điểm đánh giá: 4495 (đỉnh cao)

Đã gửi 24 August 2007 - 08:56 PM

À không.Ý em ở đây là :
Điểm đầu P1(0,0,0):nghĩa là khi nhập lệnh chiadt thì xuất hiện dòng nhắc:
Nhap diem dau cua doan thang:(click vào điểm P1)

Nhap diem cuoi cua doan thang:(click vào điểm P2)

Nhap ti le:1

thì xuất hiện dòng nhắc
; error: bad argument type: numberp: (50.0 0.0)

Bạn nhầm ở dòng mã gán Y, Z. Dòng lệnh đúng là:
(setq X1 (car P1)
[color="#0000FF"]Y1 (cdar P1);; hoac (car (cdr P1))
Z1 (caddr P1);; hoac (car (cdr (cdr P1)))[/color]
X2 (car P2)[color="#0000FF"]
Y2 (cadr P2)
Z2 (caddr cdr P2)[/color]
)
Vì (cdr '(X Y Z)) bằng '(Y Z) chứ không phải bằng Y
  • 0

#13 ustoichivost

ustoichivost

    biết vẽ circle

  • Members
  • PipPip
  • 33 Bài viết
Điểm đánh giá: 6 (bình thường)

Đã gửi 24 August 2007 - 09:34 PM

Vâng cảm ơn anh.Em áy náy quá vì mình nhầm lỗi ngớ ngẩn như vậy.Em fát hiện ra lỗi xong lên mạng thì thấy anh trả lời rồi.
Em viết lại hoàn chỉnh lisp như sau:

(defun c:cdt (/ k)
(setq P1 (getpoint "\n Dua vao diem dau :")
P2 (getpoint "\n Dua vao diem cuoi :")
k (getreal "\n Nhap ti le :")
)
(if (/= k -1)
(progn
(setq
X1 (car P1)
Y1 (cadr P1)
Z1 (cadr (cdr P1))
X2 (car P2)
Y2 (cadr P2)
Z2 (cadr (cdr P2))
X3 (/ (+ (* k X2) X1) (1+ k ))
Y3 (/ (+ (* k Y2) Y1) (1+ k ))
Z3 (/ (+ (* k Z2) Z1) (1+ k ))
P3 (list X3 Y3 Z3)
)
(command "point" P3)
)
(progn
(princ "\n Ti le phai khac -1!")
(princ )
)
)
)

Có gì không ổn,mong mấy anh chỉ giáo cho em nhé!
  • 0

#14 ustoichivost

ustoichivost

    biết vẽ circle

  • Members
  • PipPip
  • 33 Bài viết
Điểm đánh giá: 6 (bình thường)

Đã gửi 25 August 2007 - 06:14 AM

Em muốn hỏi về sự khác nhau giữa (defun c: ) và (defun)

Chẳng hạn ta xem xét đoạn lisp sau:(của anh Nguyen Hoanh):

(defun pos (sub st / l1 l2 index)
(setq index 1
l1 (strlen sub)
l2 (strlen st)
)
(while (and (<= (+ index l1 -1) l2) (/= sub (substr st index l1)))
(setq index (1+ index))
)
(if (= sub (substr st index l1))
index
nil
)
)


Nhưng nếu ở dòng một em sửa thành
(defun c:pos (sub st / l1 l2 index)

thì khi thực hiện trong cad :

Không thể nhập theo dạng :pos st sub

Thế là thế nào ạ? hay là trong những trường hợp thế này thì không nên dùng c:?
  • 0

#15 vndesperados

vndesperados

    biết lệnh xref

  • Members
  • PipPipPipPipPipPipPip
  • 547 Bài viết
Điểm đánh giá: 253 (khá)

Đã gửi 25 August 2007 - 07:18 AM

Em muốn hỏi về sự khác nhau giữa (defun c: ) và (defun)

Chẳng hạn ta xem xét đoạn lisp sau:(của anh Nguyen Hoanh):

(defun pos (sub st / l1 l2 index)
(setq index 1
l1 (strlen sub)
l2 (strlen st)
)
(while (and (<= (+ index l1 -1) l2) (/= sub (substr st index l1)))
(setq index (1+ index))
)
(if (= sub (substr st index l1))
index
nil
)
)


Nhưng nếu ở dòng một em sửa thành
(defun c:pos (sub st / l1 l2 index)

thì khi thực hiện trong cad :

Không thể nhập theo dạng :pos st sub

Thế là thế nào ạ? hay là trong những trường hợp thế này thì không nên dùng c:?


C:DEFUN là cách định nghĩa một hàm mà sau khi load được gọi như là một lệnh của AutoCAD, do vậy không thể truyền tham trị. Các tham trị hay tham biến sẽ được gọi truyền trong bản thân hàm.
DEFUN là cách định nghĩa hàm mà sau khi load sẽ được dùng bên trong một hàm khác
và cách gọi hàm giống như là một lệnh của LISP
(pos st sub)
  • 0

#16 ssg

ssg

    biết lệnh adcenter

  • Vip
  • PipPipPipPipPipPipPip
  • 1228 Bài viết
Điểm đánh giá: 1087 (rất tốt)

Đã gửi 25 August 2007 - 07:23 AM

Em muốn hỏi về sự khác nhau giữa (defun c: ) và (defun)

Chẳng hạn ta xem xét đoạn lisp sau:(của anh Nguyen Hoanh):

(defun pos (sub st / l1 l2 index)
(setq index 1
l1 (strlen sub)
l2 (strlen st)
)
(while (and (<= (+ index l1 -1) l2) (/= sub (substr st index l1)))
(setq index (1+ index))
)
(if (= sub (substr st index l1))
index
nil
)
)


Nhưng nếu ở dòng một em sửa thành
(defun c:pos (sub st / l1 l2 index)

thì khi thực hiện trong cad :

Không thể nhập theo dạng :pos st sub

Thế là thế nào ạ? hay là trong những trường hợp thế này thì không nên dùng c:?

Bạn tham khảo thêm ở đây:
http://www.cadviet.com/forum/index.php?showtopic=1032
Trong bài viết có phân tích tương đối cụ thể vấn đề này
  • 0

#17 ustoichivost

ustoichivost

    biết vẽ circle

  • Members
  • PipPip
  • 33 Bài viết
Điểm đánh giá: 6 (bình thường)

Đã gửi 04 September 2007 - 04:38 AM

Cho em hỏi hàm logand làm việc thế nào ạ?
  • 0

#18 ssg

ssg

    biết lệnh adcenter

  • Vip
  • PipPipPipPipPipPipPip
  • 1228 Bài viết
Điểm đánh giá: 1087 (rất tốt)

Đã gửi 04 September 2007 - 07:33 AM

Cho em hỏi hàm logand làm việc thế nào ạ?

Help của Acad:
(logand [int int...])
Returns the result of the logical bitwise AND of a list of integers
Examples
Command: (logand 7 15 3)
3

Bạn phải có kiến thức về hệ đếm và các phép toán logic. Hàm logand làm việc như sau:
- Chuyển toàn bộ argument sang hệ nhị phân
- Thực hiện phép toán AND cho từng bit
- Trả về kết quả tổng hợp

Ví dụ trên:
7 = 0111
15 = 1111
3 = 0011
kQ: 0011 = 3
  • 0

#19 ustoichivost

ustoichivost

    biết vẽ circle

  • Members
  • PipPip
  • 33 Bài viết
Điểm đánh giá: 6 (bình thường)

Đã gửi 15 September 2007 - 10:58 PM

Cho em hỏi lệnh textbox dùng như thế nào ạ?
(textbox <list>)???
  • 0

#20 Nguyen Hoanh

Nguyen Hoanh

    biết lệnh adcenter

  • Moderator
  • PipPipPipPipPipPipPip
  • 4105 Bài viết
Điểm đánh giá: 4495 (đỉnh cao)

Đã gửi 16 September 2007 - 03:56 PM

Cho em hỏi lệnh textbox dùng như thế nào ạ?
(textbox )???

Bạn xem ví dụ này:

(defun c:MTP ()
(defun moveone (ent p)
(setq tt (entget ent)
pt (cdr (assoc 10 tt))
gt (cdr (assoc 1 tt))
vt (vl-string-position (ascii ".") gt)
gtn (substr gt 1 (1+ vt))
ttn (subst (cons 1 gtn) (assoc 1 tt) tt)
vuong (textbox ttn)
p1 (car vuong)
p2 (cadr vuong)
dxl (- 0.0 (car p2))
dyl (- 0.0 (cadr p1))
dxt (- (car p) (car pt))
dyt (- (cadr p) (cadr pt))
dxg (+ dxt dxl)
dyg (+ dyt dyl)
xm (+ (car pt) dxg)
ym (+ (cadr pt) dyg)
pm (list xm ym (caddr pt))
tt (subst (cons 10 pm) (cons 10 pt) tt)
)
(entmod tt)
(entupd ent)
)
(princ "\nMove text point © CADViet.com")
(setq ss (ssget '((-4 . "(0 . "POINT")
(0 . "TEXT")
(-4 . "or>")
)
)
lstent (ss2ent ss)
lsttext nil
lstpoint nil
)
(foreach pp lstent
(if (= "POINT" (cdr (assoc 0 (entget pp))))
(setq
lstpoint (append lstpoint (list (cdr (assoc 10 (entget pp)))))
)
(if (vl-string-position (ascii ".") (cdr (assoc 1 (entget pp))))
(setq lsttext (append lsttext (list pp)))
)
)
)
(if (or (= (length lsttext) 0)
(= (length lstpoint) 0)
)
(princ "\nBan phai chon ca text co dau cham va point!")
(foreach ppt lsttext
(setq pmin nil
kcmin nil
)
(foreach ppp lstpoint
(if
(or (not pmin)
(> (setq tmp (distance ppp (cdr (assoc 10 (entget ppt)))))
kcmin
)
)
(setq pmin ppp
kcmin tmp
)
)
)
(moveone ppt pmin)
)
)
(princ)
)
(defun ss2ent(ss / sodt index lstent)
(setq
sodt (cond
(ss (sslength ss))
(t 0)
)
index 0
)
(repeat sodt
(setq ent (ssname ss index)
index (1+ index)
lstent (cons ent lstent)
)
)
(reverse lstent)
)

(princ "\nMTP - free lisp from www.cadviet.com")
(vl-load-com)

Đây là đoạn mã có sử dụng hàm textbox, được viết theo yêu cầu của vbao tại: http://www.cadviet.com/forum/index.php?showtopic=1571
  • 0