Đến nội dung


Hình ảnh
* * * - - 17 Bình chọn

Hỏi về Lisp (thuật toán, ý tưởng, coding,...)


  • Please log in to reply
2851 replies to this topic

#1 Jin Yong

Jin Yong

    biết lệnh group

  • Vip
  • PipPipPipPipPipPip
  • 498 Bài viết
Điểm đánh giá: 334 (khá)

Đã gửi 27 March 2007 - 11:33 PM

Jin muốn hỏi về một vài lệnh trong Lisp
Ví dụ như Jin có một xâu như sau abcd45e263
Ở trong Lisp, lệnh để lấy ra xâu con cd45e từ xâu trên là gì?
  • 2

Phát triển phần mềm thiết kế Kết cấu Việt Nam - http://www.ketcausoft.com


#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 27 March 2007 - 11:54 PM

Không có hàm chuẩn của Lisp để làm điều này.
Nhưng chúng ta có thể định nghĩa một hàm pos để tìm ra vị trí của một chuỗi trong chuỗi khác:
(defun pos (sub st / l1 l2 index)
; khởi tạo biến
(setq index 1
l1 (strlen sub)
l2 (strlen st)
)
(while
; Quét qua tất cả các đoạn của chuỗi mẹ để xem có trùng với chuỗi con không? nếu không thì quét tiếp, nếu có thì thoát.
(and (<= (+ index l1 -1) l2) (/= sub (substr st index l1)))
(setq index (1+ index))
)
; Nếu chuỗi con trùng với một đoạn của chuỗi mẹ thì trả về vị trí bắt đầu trùng, còn không thì trả về nil
(if (= sub (substr st index l1))
index
nil
)
)

Cú pháp dùng lệnh: (pos sub st)
- sub là chuỗi con.
- st là chuỗi mẹ.
- Nếu có chuỗi con trong chuỗi mẹ thì hàm trả về vị trí bắt đầu (vị trí đầu tiên tương đương với 1). Nếu không xuất hiện thì hàm trả về nil.
  • 1

#3 Jin Yong

Jin Yong

    biết lệnh group

  • Vip
  • PipPipPipPipPipPip
  • 498 Bài viết
Điểm đánh giá: 334 (khá)

Đã gửi 28 March 2007 - 12:13 AM

Jin muốn tách ra để xác định, chứ không phải chỉ muốn tìm vị trí của chuổi đó
Điều Jin muốn là lấy ra một chuỗi con nằm trong chuỗi mẹ - bao gồm các ký tự từ thứ 3 đến ký tự thứ 7 của chuỗi mẹ
Như trong chuỗi abcd45e263, chuỗi con cần lấy ra là cd45e
Chuỗi trên chỉ là ví dụ, ý Jin muốn trích một chuỗi con từ chuỗi mẹ
  • 0

Phát triển phần mềm thiết kế Kết cấu Việt Nam - http://www.ketcausoft.com


#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 28 March 2007 - 12:32 AM

Xin lỗi, trả lời nhầm.

Có hàm (substr st start count) trả về như Jin yêu cầu.
VD: (subst "abcd45e263" 3 5) = "cd45e"
  • 1

#5 Jin Yong

Jin Yong

    biết lệnh group

  • Vip
  • PipPipPipPipPipPip
  • 498 Bài viết
Điểm đánh giá: 334 (khá)

Đã gửi 28 March 2007 - 12:57 AM

HÌ, nốt hỏi, Jin hỏi tiếp: muốn chọn một đối tượng bằng một điểm trên đối tượng đó thì làm thế nào
Sách quảng cáo rằng hàm ENTSEL còn cho phép chọn đối tượng bằng cách nhập toạ độ điểm
Ví dụ như đường tròn gốc '(0 0) , bán kính r = 20
Jin muốn chọn đưòng tròn đó bằng điểm '(20 0), nhưng cú pháp (setq Sel1 (entsel '(20 0))) lại không mang lại kết quả
Lệnh đúng phải như thế nào vậy?
  • 0

Phát triển phần mềm thiết kế Kết cấu Việt Nam - http://www.ketcausoft.com


#6 Jin Yong

Jin Yong

    biết lệnh group

  • Vip
  • PipPipPipPipPipPip
  • 498 Bài viết
Điểm đánh giá: 334 (khá)

Đã gửi 28 March 2007 - 01:10 AM

:lol:
Jin vừa nhận ra là trường hợp này dung hàm SSGET thì đẹp hơn!
  • 1

Phát triển phần mềm thiết kế Kết cấu Việt Nam - http://www.ketcausoft.com


#7 Jin Yong

Jin Yong

    biết lệnh group

  • Vip
  • PipPipPipPipPipPip
  • 498 Bài viết
Điểm đánh giá: 334 (khá)

Đã gửi 04 April 2007 - 11:02 PM

Jin muốn hỏi lệnh Lisp để tạo một Text Style có đặc tính sau:
Font Name là: RomanS.SHX
Font Style là: VNS.SHX
Lệnh trong Lisp là gì vậy?
  • 1

Phát triển phần mềm thiết kế Kết cấu Việt Nam - http://www.ketcausoft.com


#8 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 05 April 2007 - 08:12 AM

Jin đọc thêm bài viết tại trang tin nói về big font.

Cách làm rất đơn giản là dùng lệnh style, tham số đầu tiên là tên style, nếu chưa có thì ACAD sẽ tạo, tiếp đến là font và big font (nêu đủ cả tên đuôi) cách nhau bằng dấu phẩy, cuối cùng là 6 dấu enter:
(command ".style" "cadvietstyle" "romans.shx,vns.shx" "" "" "" "" "" "")
  • 3

#9 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 05 April 2007 - 08:51 AM

Jin đọc thêm bài viết tại trang tin nói về big font.

Cách làm rất đơn giản là dùng lệnh style, tham số đầu tiên là tên style, nếu chưa có thì ACAD sẽ tạo, tiếp đến là font và big font (nêu đủ cả tên đuôi) cách nhau bằng dấu phẩy, cuối cùng là 6 dấu enter:
(command ".style" "cadvietstyle" "romans.shx,vns.shx" "" "" "" "" "" "")


Bác Hoành thừa 1 dấu Enter, chỉ có 5 thôi!

Mẹo vặt:
Muốn biết Acad yêu cầu những thành phần gì đối với một lệnh, bạn hãy nhập trực tiếp vào dòng nhắc command của Acad:
Command: (command "tên lệnh" pause)

Ví dụ trên:
Command: (command "style" pause) - Enter
Căn cứ vào các yêu cầu tiếp theo của Acad, bạn khắc biết phải đáp ứng cái gì thay thế cho pause để có một biểu thức lisp hoàn chỉnh. Nếu chấp nhận các giá trị mặc định, chỉ việc thay bằng "" (Enter).
  • 2

#10 Jin Yong

Jin Yong

    biết lệnh group

  • Vip
  • PipPipPipPipPipPip
  • 498 Bài viết
Điểm đánh giá: 334 (khá)

Đã gửi 05 April 2007 - 09:28 PM

Tuyệt vời, cảm ơn anh Hoành
Mẹo của SSG quả nhiên vô cùng hữu ích!
  • 0

Phát triển phần mềm thiết kế Kết cấu Việt Nam - http://www.ketcausoft.com


#11 xvinh

xvinh

    biết pan

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

Đã gửi 07 April 2007 - 08:20 PM

Các bạn cho tôi hỏi tại sao tôi sau khi tôi sử dụng lisp vẽ cửa chuyển sang lệnh khác thì tất cả các phương thức băt điểm lại tự động bị tắt hết (mở os thì không có cách nào được chọn)? Các bạn chỉ giáo giúp nhé,Càng sớm càng tốt. Xin chân thành cảm ơn! :lol: :lol:
Đoạn Lisp như sau:


(defun c:cu()
(setvar "osmode" 512 )
(setq p1 (getpoint "\nfirst point :"))
(if (= nil p1)(sdor)(odor))
)
(defun odor ()
(setq p2 (getpoint p1 "\nsecond point width open :"))
(setvar "osmode" 128 )
(setq p3 (getpoint p2 "\npick in wall :")
p31 (polar p1 (angle p2 p3) (distance p2 p3))
)
(setvar "osmode" 0 )
(command "line" p1 p31 "")
(setq s1 (entlast));de copy ve do cua so
(command "line" p2 p3 "" "trim" "c" p3 p1 ""
(polar p1 (angle p1 p2) (/ (distance p1 p2) 2))
(polar p31 (angle p1 p2) (/ (distance p1 p2) 2)) ""
)
(setq sel (strcase (getstring "\nWin Open <Dor> :")))
(cond ((= sel "W")(openwin))
((= sel "")(opendor))
(T (princ))
)
(princ)
)
(defun sdor ()
(setvar "osmode" 1 )
(setq p1 (getpoint "\nfirst point :"))
(setq p2 (getpoint p1 "\nsecond point width open :"))
(setvar "osmode" 128 )
(setq p3 (getpoint p2 "\npick in wall :")
p31 (polar p1 (angle p2 p3) (distance p2 p3))
)
(setvar "osmode" 0 )
(command "line" p1 p31 "")
(setq s1 (entlast)) ;de copy ve do cua so
(setq sel (strcase (getstring "\nWin Open <Dor> :")))
(cond ((= sel "W")(openwin))
((= sel "")(opendor))
(T (princ))
)
(princ)
)
;-----------
(defun opendor ()
(setq ang (getangle (polar p1 (angle p1 p2) (/ (distance p1 p2) 2)) "\ndirection open :")
nsegdor (getint "\nnumber seg dor 2 4 <1> :")
)
(cond ((= nsegdor 2)(dor2 p1 p2 ang))
((= nsegdor 4)(dor4 p1 p2 ang))
(T (dor p1 p2 ang))
)
)
;----------
(defun dor4 (p1 p2 ang)
(setq p12 (polar p1 (angle p1 p2) (/ (distance p1 p2) 2)))
(setq p112 (polar p1 (angle p1 p12) (/ (distance p1 p12) 2)))
(setq p122 (polar p12 (angle p1 p12) (/ (distance p1 p12) 2)))
(dor p1 p112 ang)(dor p112 p12 ang)(dor p2 p122 ang)(dor p122 p12 ang)
)
;----------
(defun dor2 (p1 p2 ang)
(setq p12 (polar p1 (angle p1 p2) (/ (distance p1 p2) 2)))
(dor p1 p12 ang)(dor p2 p12 ang)
)
;----------
(defun dor (p1 p2 ang)
(setq ps1 (polar p1 (angle p1 p2) 0.5)
ps2 (polar ps1 ang (distance p1 p2))
ps3 (polar ps2 (angle p2 p1) 0.5)
)
(command "pline" ps3 ps2 ps1 p1 ps3 ps2 "a" p2 "" )
)
;----------
(defun openwin ()
(command "line" p1 p2 "" "line" p31 p3 ""
"line" (polar p1 (angle p2 p3) (/ (distance p2 p3) 2))
(polar p2 (angle p2 p3) (/ (distance p2 p3) 2)) ""
)
(setq nsegwin (getint "\nnumber seg win :")
disseg (/ (distance p1 p2) nsegwin)
)
(setq lispoiseg nil)
(repeat (- nsegwin 1)
(setq lispoiseg (append lispoiseg (list (polar p1 (angle p1 p2) (* (- nsegwin 1) disseg))))
nsegwin (- nsegwin 1)
)
)
(command "copy" s1 "" "m" p1)
(foreach p lispoiseg (command p))
(command "")
)
(PRINC)

  • 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 07 April 2007 - 08:35 PM

Có 2 cách để giải quyết vấn đề trên.

Cách 1: Bạn bỏ dòng lệnh (setvar "osmode" 0) đi, lúc này lệnh cu sẽ thực hiện sai với một số trường hợp (do bắt nhầm điểm).

Cách 2: Nếu bạn muốn giữ dòng lệnh (setvar "osmode" 0) để cu thực hiện đúng trong mọi trường hợp, bạn phải thêm đoạn mã lưu biến osmode gốc tại khởi đầu của lệnh cu:
(setq old_osmode (getvar "osmode")
old_autosnap (getvar "autosnap")
)
Và trước khi kết thúc lệnh, bạn thêm vào đoạn mã trả về giá trị osmode ban đầu:
(if old_osmode (setvar "osmode" old_osmode))
(if old_autosnap (setvar "autosnap" old_autosnap))
Như vậy, đoạn mã lệnh của bạn sẽ trở thành:
(defun c:cu()
[color="#0000FF"](setq old_osmode (getvar "osmode")
old_autosnap (getvar "autosnap")
)[/color]
(setvar "osmode" 512 )
(setq p1 (getpoint "\nfirst point :"))
(if (= nil p1)(sdor)(odor))
[color="#0000FF"](if old_osmode (setvar "osmode" old_osmode))
(if old_autosnap (setvar "autosnap" old_autosnap))
[/color]
)
(defun odor ()
(setq p2 (getpoint p1 "\nsecond point width open :"))
(setvar "osmode" 128 )
(setq p3 (getpoint p2 "\npick in wall :")
p31 (polar p1 (angle p2 p3) (distance p2 p3))
)
(setvar "osmode" 0 )
(command "line" p1 p31 "")
(setq s1 (entlast));de copy ve do cua so
(command "line" p2 p3 "" "trim" "c" p3 p1 ""
(polar p1 (angle p1 p2) (/ (distance p1 p2) 2))
(polar p31 (angle p1 p2) (/ (distance p1 p2) 2)) ""
)
(setq sel (strcase (getstring "\nWin Open :")))
(cond ((= sel "W")(openwin))
((= sel "")(opendor))
(T (princ))
)
(princ)
)
(defun sdor ()
(setvar "osmode" 1 )
(setq p1 (getpoint "\nfirst point :"))
(setq p2 (getpoint p1 "\nsecond point width open :"))
(setvar "osmode" 128 )
(setq p3 (getpoint p2 "\npick in wall :")
p31 (polar p1 (angle p2 p3) (distance p2 p3))
)
(setvar "osmode" 0 )
(command "line" p1 p31 "")
(setq s1 (entlast)) ;de copy ve do cua so
(setq sel (strcase (getstring "\nWin Open :")))
(cond ((= sel "W")(openwin))
((= sel "")(opendor))
(T (princ))
)
(princ)
)
;-----------
(defun opendor ()
(setq ang (getangle (polar p1 (angle p1 p2) (/ (distance p1 p2) 2)) "\ndirection open :")
nsegdor (getint "\nnumber seg dor 2 4 <1> :")
)
(cond ((= nsegdor 2)(dor2 p1 p2 ang))
((= nsegdor 4)(dor4 p1 p2 ang))
(T (dor p1 p2 ang))
)
)
;----------
(defun dor4 (p1 p2 ang)
(setq p12 (polar p1 (angle p1 p2) (/ (distance p1 p2) 2)))
(setq p112 (polar p1 (angle p1 p12) (/ (distance p1 p12) 2)))
(setq p122 (polar p12 (angle p1 p12) (/ (distance p1 p12) 2)))
(dor p1 p112 ang)(dor p112 p12 ang)(dor p2 p122 ang)(dor p122 p12 ang)
)
;----------
(defun dor2 (p1 p2 ang)
(setq p12 (polar p1 (angle p1 p2) (/ (distance p1 p2) 2)))
(dor p1 p12 ang)(dor p2 p12 ang)
)
;----------
(defun dor (p1 p2 ang)
(setq ps1 (polar p1 (angle p1 p2) 0.5)
ps2 (polar ps1 ang (distance p1 p2))
ps3 (polar ps2 (angle p2 p1) 0.5)
)
(command "pline" ps3 ps2 ps1 p1 ps3 ps2 "a" p2 "" )
)
;----------
(defun openwin ()
(command "line" p1 p2 "" "line" p31 p3 ""
"line" (polar p1 (angle p2 p3) (/ (distance p2 p3) 2))
(polar p2 (angle p2 p3) (/ (distance p2 p3) 2)) ""
)
(setq nsegwin (getint "\nnumber seg win :")
disseg (/ (distance p1 p2) nsegwin)
)
(setq lispoiseg nil)
(repeat (- nsegwin 1)
(setq lispoiseg (append lispoiseg (list (polar p1 (angle p1 p2) (* (- nsegwin 1) disseg))))
nsegwin (- nsegwin 1)
)
)
(command "copy" s1 "" "m" p1)
(foreach p lispoiseg (command p))
(command "")
)
(PRINC)


Vấn đề mà bạn nêu ra rất điển hình, mọi chương trình lisp sử dụng hàm command và tác động vào điểm của AutoCAD luôn gặp phải. Đoạn mã theo cách 2 trên được thực hiện trong hầu hết các lisp để giải quyết khó khăn này.
  • 0

#13 xvinh

xvinh

    biết pan

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

Đã gửi 07 April 2007 - 08:51 PM

Rất xin cảm ơn Bạn Hoành về phản hồi giúp đỡ ngay, tác phong như nhà binh chúng tôi! Kiến thức của tôi rất hạn chế, biết sơ về Cad, lơ mơ về Lisp mong các bạo chỉ giáo nhiều. Tôi thấy diễn đàn của mình rất hay, bổ ích và cao hơn là tiêu chí phục vụ hết mình, chia sẻ kiến thức, kinh nghiệm quý giá "TẤT CẢ VÌ CỘNG ĐỒNG CADVIET". Xin cảm ơn nhé!
  • 1

#14 Jin Yong

Jin Yong

    biết lệnh group

  • Vip
  • PipPipPipPipPipPip
  • 498 Bài viết
Điểm đánh giá: 334 (khá)

Đã gửi 11 April 2007 - 12:14 AM

Cho Jin hỏi:
Lisp có hàm nào như kiểu hàm Trim của VB không, tác dụng là để cắt các khoảng trống hai bên chuỗi, chẳng hạn biến chuổi
" abcde efg " (có các khoảng trống hai bên) thành chuỗi "abcd efg"
  • 0

Phát triển phần mềm thiết kế Kết cấu Việt Nam - http://www.ketcausoft.com


#15 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 11 April 2007 - 06:49 AM

Lisp không có hàm kiểu như trim. Nhưng Jin có thể tự lập lấy được:

(defun trim (str)
(while (and (/= str "") (= (substr str 1 1) " "))
(setq str (substr str 2))
(while (and (/= str "") (= (substr str (strlen str) 1) " "))
(setq str (substr str 1 (1- (strlen str))))
)
)
str
)

  • 0

#16 Jin Yong

Jin Yong

    biết lệnh group

  • Vip
  • PipPipPipPipPipPip
  • 498 Bài viết
Điểm đánh giá: 334 (khá)

Đã gửi 11 April 2007 - 03:02 PM

Cho Jin hỏi tiếp:
Bằng lệnh Lisp, làm sao kiểm tra được một Layer hay một Text Style đã tồn tại hay chưa?

Chẳng hạn Jin muốn kiểm tra xem đã có Layer nào tên là "P-Thep" hay chưa?
  • 0

Phát triển phần mềm thiết kế Kết cấu Việt Nam - http://www.ketcausoft.com


#17 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 11 April 2007 - 03:25 PM

Cho Jin hỏi tiếp:
Bằng lệnh Lisp, làm sao kiểm tra được một Layer hay một Text Style đã tồn tại hay chưa?

Chẳng hạn Jin muốn kiểm tra xem đã có Layer nào tên là "P-Thep" hay chưa?


Dùng tblsearch
Ví dụ:
(tblsearch "layer" "P-Thep")
(tblsearch "style" "standard")
Nếu có, hoàn trả các properties của Layer hoặc TextStyle. Nếu không, hoàn trả nil.
  • 0

#18 bowxman

bowxman

    biết vẽ pline

  • Members
  • PipPip
  • 69 Bài viết
Điểm đánh giá: 20 (tàm tạm)

Đã gửi 12 April 2007 - 12:36 AM

Cho em hỏi 1 câu:
Em viết lisp trong cad 2007, làm sao lấy được mã đối tượng của 1 khối solid, ví dụ như tọa độ các đỉnh, chiều ngang, chiều cao....
  • 0

#19 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 12 April 2007 - 12:58 AM

Bó tay rồi!
Không phải chỉ phiên bản 2007 đâu, phiên bản nào cũng thế bọn AutoDesk giấu kín lắm.

Có một cách mà tôi vẫn làm để lấy tọa độ đỉnh của solid là export đối tượng solid ra file 3DS, sau đó import vào nó sẽ trở thành polyline mesh. Tiếp đến dùng hàm entnext để lấy tên đối tượng chứa đỉnh (VERTEX) và hàm entget để lấy tọa độ đỉnh.
  • 0

#20 bowxman

bowxman

    biết vẽ pline

  • Members
  • PipPip
  • 69 Bài viết
Điểm đánh giá: 20 (tàm tạm)

Đã gửi 12 April 2007 - 01:07 AM

Nếu vậy thì mình convert thành khối masselement nhanh hơn chớ bác, tuy nhiên khối mass có sai số
  • 0