Đến nội dung


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

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


  • Please log in to reply
497 replies to this topic

#81 ndtnv

ndtnv

    biết lệnh minsert

  • Members
  • PipPipPipPipPipPip
  • 437 Bài viết
Điểm đánh giá: 384 (khá)

Đã gửi 14 April 2009 - 02:37 PM

Chào bác gia_bach, bạn Tue_NV
Sau khi thử chạy lisp vào file Cad kèm dưới dây thì kết quả là:

Chữ có kiểu gõ tiếng Anh --> chữ có kiểu gõ tiếng Nhật.
Chữ có kiểu gõ tiếng Nhật --> chữ có kiểu gõ tiếng Nhật.

Số có kiểu gõ tiếng Anh --> số có kiểu gõ tiếng Nhật.
Số có kiểu gõ tiếng Nhật --> xxx

Vậy những con số tiếng Nhật này làm lisp chạy không ổn định, không biết có cách khắc phục không.

http://www.cadviet.c...Drawing2_14.dwg

@Bạn Tue_NV
Mình có thử viết thêm chút ít để lisp chạy cho 1 tập hợp text, bạn xem thử góp ý cho mình với nhe.

http://www.cadviet.c...iles/STRR_1.lsp

Lisp của bạn tôi sửa đã khắc phục lỗi số có kiểu gõ tiếng Nhật như sau:
(defun c:STRR ( / ss i j str stri n te te1 asc)
(setq ss (ssget '((0 . "TEXT,MTEXT"))) j 0 )

(while
(< j (sslength ss))
(setq stri (ssname ss j) stri (entget stri) )
(setq str (cdr(assoc 1 stri)))
(setq n (strlen str) i 1 te "")

(while (<= i n)
(setq te1 (substr str i 1) asc (ascii te1))
(if (and (> asc 127)(or (< asc 160) (> asc 223)))
(setq te1 (substr str i 2) i (1+ i))
(progn
(if (= te1 "1") (setq te1 "1"))(if (= te1 "7") (setq te1 "7"))
(if (= te1 "2") (setq te1 "2"))(if (= te1 "8") (setq te1 "8"))
(if (= te1 "3") (setq te1 "3"))(if (= te1 "9") (setq te1 "9"))
(if (= te1 "4") (setq te1 "4"))(if (= te1 "-") (setq te1 "-"))
(if (= te1 "5") (setq te1 "5"))(if (= te1 "x") (setq te1 "x"))
(if (= te1 "6") (setq te1 "6"))(if (= te1 "0") (setq te1 "0"))

(if (= te1 "A") (setq te1 "A"))(if (= te1 "N") (setq te1 "N"))
(if (= te1 "B") (setq te1 "B"))(if (= te1 "O") (setq te1 "O"))
(if (= te1 "C") (setq te1 "C"))(if (= te1 "P") (setq te1 "P"))
(if (= te1 "D") (setq te1 "D"))(if (= te1 "Q") (setq te1 "Q"))
(if (= te1 "E") (setq te1 "E"))(if (= te1 "R") (setq te1 "R"))
(if (= te1 "F") (setq te1 "F"))(if (= te1 "S") (setq te1 "S"))
(if (= te1 "G") (setq te1 "G"))(if (= te1 "T") (setq te1 "T"))
(if (= te1 "H") (setq te1 "H"))(if (= te1 "U") (setq te1 "U"))
(if (= te1 "I") (setq te1 "I"))(if (= te1 "V") (setq te1 "V"))
(if (= te1 "J") (setq te1 "J"))(if (= te1 "W") (setq te1 "W"))
(if (= te1 "K") (setq te1 "K"))(if (= te1 "X") (setq te1 "X"))
(if (= te1 "L") (setq te1 "L"))(if (= te1 "Y") (setq te1 "Y"))
(if (= te1 "M") (setq te1 "M"))(if (= te1 "Z") (setq te1 "Z"))
)
)
(setq te (strcat te te1))
(setq i (1+ i))
)
(setq stri (subst (cons 1 te) (assoc 1 stri) stri))
(entmod stri)

(setq j (+ j 1))

)

(princ)
)
Hoặc dùng lisp này vừa ngắn, lại đầy đủ hơn
(defun c:STRRnew ( / ss i j k str stri n te te1 asc)
(setq En "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-(){}/.,?~!@#$%^&*()_=" )
(setq Jp "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ー(){}/。、~?!@#$%^&*()_=" )
(setq ss (ssget '((0 . "TEXT,MTEXT"))) j 0 )

(while
(< j (sslength ss))
(setq stri (ssname ss j) stri (entget stri) )
(setq str (cdr(assoc 1 stri)))
(setq n (strlen str) i 1 te "")

(while (<= i n)
(setq te1 (substr str i 1) asc (ascii te1))
(if (and (> asc 127)(or (< asc 160) (> asc 223)))
(setq te1 (substr str i 2) i (1+ i))
(if (setq k (vl-string-search te1 En))
(setq te1 (substr Jp (+ k k 1) 2))
)
)
(setq te (strcat te te1))
(setq i (1+ i))
)
(setq stri (subst (cons 1 te) (assoc 1 stri) stri))
(entmod stri)

(setq j (+ j 1))

)
(princ)
)

  • 3

#82 tuan_thietkedien

tuan_thietkedien

    biết lệnh mirror

  • Members
  • PipPipPip
  • 153 Bài viết
Điểm đánh giá: 15 (tàm tạm)

Đã gửi 22 April 2009 - 11:50 AM

Xin Chào.

Nhờ các pác cao thủ giúp em cách tạo 1 lisp mới từ 2 lisp sau

1.Lisp chèn Block vào giao điểm các đoạn thẳng.
http://www.cadviet.c..._doan_thang.lsp

2.Lisp cắt đoạn thẳng tại giao điểm các đoạn thẳng
http://www.cadviet.c..._doan_thang.lsp

Em muốn tạo 1 lisp mới (lisp12)có khả năng khi mình quét khối vùng chọn, lisp12 sẽ tìm ra các giao điểm của đoạn thẳng ( theo cách của lisp 1), sau đó lisp12 sẽ cắt tại các giao điểm ấy theo cách của lisp 2.

Nếu có chỗ nào chưa rõ xin phản hồi lại, xin cám ơn nhiều.
  • 0

#83 Tue_NV

Tue_NV

    KS Võ Quang Tuệ

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

Đã gửi 22 April 2009 - 12:58 PM

Xin Chào.

Nhờ các pác cao thủ giúp em cách tạo 1 lisp mới từ 2 lisp sau

1.Lisp chèn Block vào giao điểm các đoạn thẳng.
http://www.cadviet.c..._doan_thang.lsp

2.Lisp cắt đoạn thẳng tại giao điểm các đoạn thẳng
http://www.cadviet.c..._doan_thang.lsp

Em muốn tạo 1 lisp mới (lisp12)có khả năng khi mình quét khối vùng chọn, lisp12 sẽ tìm ra các giao điểm của đoạn thẳng ( theo cách của lisp 1), sau đó lisp12 sẽ cắt tại các giao điểm ấy theo cách của lisp 2.

Nếu có chỗ nào chưa rõ xin phản hồi lại, xin cám ơn nhiều.

Tue_NV chưa hiểu ý của bạn lắm.
Có lẽ bạn nên trình bày thật rõ ràng, thật chi tiết trong 1 file .dwg rồi upload lên đây.
Bạn nhớ mô tả kỹ nhé : kiểu cắt X, Y, khoảng cách cắt : là gì......
Mục đích bạn muốn đạt được, dữ liệu đầu vào -> xử lý -> dữ liệu đầu ra. (Lisp 1 , Lisp2, Lisp 12)
Bạn nhớ trình bày thật đủ, rõ ràng và chi tiết, tránh làm mất thời gian. Bạn làm như thế nào thì làm miễn sao để ai đọc cũng hiểu được ý của bạn muốn nói cái gì và mục đích sau cùng bạn muốn đạt được.
Chào bạn. Chúc bạn vui.
  • 1

#84 tuan_thietkedien

tuan_thietkedien

    biết lệnh mirror

  • Members
  • PipPipPip
  • 153 Bài viết
Điểm đánh giá: 15 (tàm tạm)

Đã gửi 22 April 2009 - 01:51 PM

Tue_NV chưa hiểu ý của bạn lắm.
Có lẽ bạn nên trình bày thật rõ ràng, thật chi tiết trong 1 file .dwg rồi upload lên đây.
Bạn nhớ mô tả kỹ nhé : kiểu cắt X, Y, khoảng cách cắt : là gì......
Mục đích bạn muốn đạt được, dữ liệu đầu vào -> xử lý -> dữ liệu đầu ra. (Lisp 1 , Lisp2, Lisp 12)
Bạn nhớ trình bày thật đủ, rõ ràng và chi tiết, tránh làm mất thời gian. Bạn làm như thế nào thì làm miễn sao để ai đọc cũng hiểu được ý của bạn muốn nói cái gì và mục đích sau cùng bạn muốn đạt được.
Chào bạn. Chúc bạn vui.


Mình sẽ giải thích về lisp 2
- Nhập lệnh : cat
- Nhập kiểu cắt :
* X là cắt đoạn thằng nằm ngang , giống như trục X vậy.
* Y là cắt đoạn thằng nằm dọc , giống như trục Y vậy.
- Nhập khoảng cách cắt : 100 ( tùy ý người dùng )
- Chọn đối tượng :
* Nếu kiểu cắt là X phải chọn đối tượng theo phương X
* Nếu kiểu cắt là Y phải chọn đối tượng theo phương Y
- Nhập điểm ( là điểm giao nhau các đoạn thẳng )
--> Kết quả tham khảo file đính kèm. http://www.cadviet.c...Drawing2_17.dwg

Cái nhược điểm ở cái lisp 2 là sau khi nhập kiểu cắt và khoảng cách cắt,
người dùng phải chọn đoạn thẳng , rồi chọn từng giao điểm của các đoạn thẳng.
Vậy nếu có mấy chục cái giao điểm thì làm rất lâu.

Do đó, mình thấy có cái lisp 1 tự động tìm giao điểm của đường thẳng,
nhưng mày mò hoài cũng không tài nào ghép 2 cái lisp này với nhau được.

Rút kinh nghiệm về sau phải cố gắng giải thích thật kỹ cho mọi người dễ hiểu.
Chắc mình không làm giáo viên được rùi quá. hihi

Còn chỗ nào chưa rõ xin phản hồi lại nha.

Cám ơn.
  • 0

#85 Tue_NV

Tue_NV

    KS Võ Quang Tuệ

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

Đã gửi 22 April 2009 - 02:52 PM

Mình sẽ giải thích về lisp 2
- Nhập lệnh : cat
- Nhập kiểu cắt :
* X là cắt đoạn thằng nằm ngang , giống như trục X vậy.
* Y là cắt đoạn thằng nằm dọc , giống như trục Y vậy.
- Nhập khoảng cách cắt : 100 ( tùy ý người dùng )
- Chọn đối tượng :
* Nếu kiểu cắt là X phải chọn đối tượng theo phương X
* Nếu kiểu cắt là Y phải chọn đối tượng theo phương Y
- Nhập điểm ( là điểm giao nhau các đoạn thẳng )
--> Kết quả tham khảo file đính kèm. http://www.cadviet.c...Drawing2_17.dwg

Cái nhược điểm ở cái lisp 2 là sau khi nhập kiểu cắt và khoảng cách cắt,
người dùng phải chọn đoạn thẳng , rồi chọn từng giao điểm của các đoạn thẳng.
Vậy nếu có mấy chục cái giao điểm thì làm rất lâu.

Do đó, mình thấy có cái lisp 1 tự động tìm giao điểm của đường thẳng,
nhưng mày mò hoài cũng không tài nào ghép 2 cái lisp này với nhau được.

Rút kinh nghiệm về sau phải cố gắng giải thích thật kỹ cho mọi người dễ hiểu.
Chắc mình không làm giáo viên được rùi quá. hihi

Còn chỗ nào chưa rõ xin phản hồi lại nha.

Cám ơn.

Bạn hãy đọc những đoạn Code này của mình. Hy vọng bạn tự xây dựng được chương trình :
Hỏi về lệnh Break
Chúc thành công nhé :cheers:
  • 1

#86 phamthanhbinh

phamthanhbinh

    biết lệnh adcenter

  • Moderator
  • PipPipPipPipPipPipPip
  • 6007 Bài viết
Điểm đánh giá: 3113 (tuyệt vời)

Đã gửi 22 April 2009 - 07:45 PM

Bạn hãy đọc những đoạn Code này của mình. Hy vọng bạn tự xây dựng được chương trình :
Hỏi về lệnh Break
Chúc thành công nhé :cheers:

Chào bạn Tuan_thietkeden,
Để thực hiện việc ghep lisp này bạn cần lưu ý tới những vấn đề như sau:
1/- Việc tạo và sử dụng các hàm con trong hàm chính
2/- Các biến toàn cục và biến cục bộ trong các hàm con
3/- Các hàm lặp.

Với yêu cầu của bạn, theo mình bạn có thể tách toàn bộ yêu cầu của bạn thành từng nhiệm vụ độc lập tức là các hàm con như sau:
Bước 1: Chọn đối tượng
Bước 2: Lấy tập hợp các điểm giao nhau.(dùng lisp 1, bỏ phần insert block đi)
Bước 3: Chọn các đối tượng muốn cắt theo hướng X và các đối tượng muốn cắt theo hướng Y
Bước 4: Thực hiện lệnh cắt (dùng lisp2 kết hợp với các vòng lặp qua tất cả các điểm căt và qua tất cả các đối tượng theo mỗi hướng cắt.)
Cần lưu ý các biến toàn cục trong hàm con phải được khai báo đầy đủ trong hàm chính.

Bạn thử xem nhé, sau đó post lên, có gì mình sẽ cùng xem xét.
  • 1
Chúc các quý Anh trên diễn đàn luôn khỏe, đẻ thêm được nhiều thứ để mót.

#87 tuan_thietkedien

tuan_thietkedien

    biết lệnh mirror

  • Members
  • PipPipPip
  • 153 Bài viết
Điểm đánh giá: 15 (tàm tạm)

Đã gửi 23 April 2009 - 11:43 AM

Bạn hãy đọc những đoạn Code này của mình. Hy vọng bạn tự xây dựng được chương trình :
Hỏi về lệnh Break
Chúc thành công nhé :cheers:


Chào bạn Tue_NV, bạn phamthanhbinh

Cái lệnh Break của bạn Tue_NV mình thấy hay hay nên mình mạo muội sửa chút đỉnh theo ý của mình
nhưng nó chạy không ổn định. Nó không cắt được cho 1 tập hợp, với lại đôi khi nó không cắt chính xác thì phải.

http://www.cadviet.c...pfiles/new2.lsp
http://www.cadviet.c...iles/test_1.dwg

Bạn Tue và bạn bình góp ý cho mình với nhé.
  • 0

#88 tuan_thietkedien

tuan_thietkedien

    biết lệnh mirror

  • Members
  • PipPipPip
  • 153 Bài viết
Điểm đánh giá: 15 (tàm tạm)

Đã gửi 23 April 2009 - 02:41 PM

Chào bạn Tuan_thietkeden,
Để thực hiện việc ghep lisp này bạn cần lưu ý tới những vấn đề như sau:
1/- Việc tạo và sử dụng các hàm con trong hàm chính
2/- Các biến toàn cục và biến cục bộ trong các hàm con
3/- Các hàm lặp.

Với yêu cầu của bạn, theo mình bạn có thể tách toàn bộ yêu cầu của bạn thành từng nhiệm vụ độc lập tức là các hàm con như sau:
Bước 1: Chọn đối tượng
Bước 2: Lấy tập hợp các điểm giao nhau.(dùng lisp 1, bỏ phần insert block đi)
Bước 3: Chọn các đối tượng muốn cắt theo hướng X và các đối tượng muốn cắt theo hướng Y
Bước 4: Thực hiện lệnh cắt (dùng lisp2 kết hợp với các vòng lặp qua tất cả các điểm căt và qua tất cả các đối tượng theo mỗi hướng cắt.)
Cần lưu ý các biến toàn cục trong hàm con phải được khai báo đầy đủ trong hàm chính.

Bạn thử xem nhé, sau đó post lên, có gì mình sẽ cùng xem xét.


Chào bạn phamthanhbinh
Mình đã thử làm theo cách bạn gợi ý nhưng cũng chưa hoàn thiện lắm.
Cái lisp này mình tạm mặc định cho nó cắt đoạn 100 theo phương ngang.
Bạn xem rồi góp ý nha.
http://www.cadviet.c...files/new_4.lsp
http://www.cadviet.c...iles/test_1.dwg
  • 0

#89 Tue_NV

Tue_NV

    KS Võ Quang Tuệ

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

Đã gửi 23 April 2009 - 09:52 PM

Chào bạn Tue_NV, bạn phamthanhbinh

Cái lệnh Break của bạn Tue_NV mình thấy hay hay nên mình mạo muội sửa chút đỉnh theo ý của mình
nhưng nó chạy không ổn định. Nó không cắt được cho 1 tập hợp, với lại đôi khi nó không cắt chính xác thì phải.

http://www.cadviet.c...pfiles/new2.lsp
http://www.cadviet.c...iles/test_1.dwg

Bạn Tue và bạn bình góp ý cho mình với nhé.

Sau mỗi vòng lặp while bạn thực hiện break thì đôi tượng bị bẽ gãy làm đôi => như vậy biến sL sẽ bị thay đổi kéo theo các biến cL,dL, eL, hL bị thay đổi theo. Như vậy đoạn Code bạn viết ra sẽ không bao giờ cắt được cho 1 tập hợp. Vấn đề ở đây là bạn giải quyết là xác định cho được tập hợp chọn sau mỗi lần thực hiện lệnh Break sau mỗi lần lặp bằng vòng lặp while
  • 1

#90 tuan_thietkedien

tuan_thietkedien

    biết lệnh mirror

  • Members
  • PipPipPip
  • 153 Bài viết
Điểm đánh giá: 15 (tàm tạm)

Đã gửi 24 April 2009 - 10:48 AM

Sau mỗi vòng lặp while bạn thực hiện break thì đôi tượng bị bẽ gãy làm đôi => như vậy biến sL sẽ bị thay đổi kéo theo các biến cL,dL, eL, hL bị thay đổi theo. Như vậy đoạn Code bạn viết ra sẽ không bao giờ cắt được cho 1 tập hợp. Vấn đề ở đây là bạn giải quyết là xác định cho được tập hợp chọn sau mỗi lần thực hiện lệnh Break sau mỗi lần lặp bằng vòng lặp while


Cám ơn bạn Tue đã nhắc nha.
Mình đã làm được rồi. :(
Nhưng đôi khi lệnh không cắt trong hình chữ nhật màu đỏ, bạn biết nguyên nhân không.
http://www.cadviet.c...iles/new2_1.lsp
http://www.cadviet.c...les/Book1_6.xls
  • 0

#91 Tue_NV

Tue_NV

    KS Võ Quang Tuệ

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

Đã gửi 24 April 2009 - 11:07 AM

Cám ơn bạn Tue đã nhắc nha.
Mình đã làm được rồi. :(
Nhưng đôi khi lệnh không cắt trong hình chữ nhật màu đỏ, bạn biết nguyên nhân không.
http://www.cadviet.c...iles/new2_1.lsp
http://www.cadviet.c...les/Book1_6.xls

Vì hình của bạn có nhiều đối tượng => nên tắt chế độ bắt điểm đi thì Lisp chạy OK ngay.
Đây bạn :

(defun c:test ()
(setq osold (getvar "osmode"))
(setvar "osmode" 0)
(vl-load-com)
(setq TapChon (ssget '((0 . "LINE,LWPOLYLINE")))
SoDoiTuong (sslength TapChon)
cs1 0
)

(repeat SoDoiTuong
(setq DoiTuong1 (ssname TapChon cs1)
cs2 (+ cs1 1)
)
(repeat (- SoDoiTuong cs1 1)
(setq
DoiTuong2 (ssname TapChon cs2)
Giao (GiaoDT DoiTuong1 DoiTuong2)
cs2 (+ cs2 1)
)
(foreach Diem Giao
(setq
diem1 (list (- (car diem) 100) (cadr diem) 0)
diem2 (list (- (car diem) 100) (+ (cadr diem) 50))
diem3 (list (- (car diem) 100) (- (cadr diem) 50))
diem4 (list (+ (car diem) 100) (cadr diem) 0)
diem5 (list (+ (car diem) 100) (+ (cadr diem) 50))
diem6 (list (+ (car diem) 100) (- (cadr diem) 50))
)
(grdraw diem2 diem5 1 1)
(grdraw diem5 diem6 1 1)
(grdraw diem6 diem3 1 1)
(grdraw diem3 diem2 1 1)

(setq n (sslength tapchon)
i 0)
(while (< i n)
(setq sL (ssname tapchon i))
(setq cL (vlax-curve-getStartPoint sL))
(setq dL (vlax-curve-getEndPoint sL))

(setq eL (inters diem2 diem3 cL dL nil))
(setq hL (inters diem6 diem5 cL dL nil))

(if (= eL nil) (setq i (1+ i)))
(if (/= eL nil)
(progn
(Command "_Break" sL eL hL)
(setq i (1+ i))
)
)
)
)
)
(setq cs1 (+ cs1 1))
)
(setvar "osmode" osold)
(princ)
)


(defun GiaoDT (ent1 ent2)
(setq ob1 (vlax-ename->vla-object ent1)
ob2 (vlax-ename->vla-object ent2)
)
(setq g (vlax-variant-value
(vla-IntersectWith ob1 ob2 acExtendNone)
)
)
(if (/= (vlax-safearray-get-u-bound g 1) -1)
(setq g (vlax-safearray->list g))
(setq g nil)
)
(if g
(progn
(setq kq nil
sd (fix (/ (length g) 3))
)
(repeat sd
(setq kq (append kq (list (list (car g) (cadr g) (caddr g))))
g (cdddr g)
)
)
kq
)
nil
)

)

Với Code của bạn thì khoảng cách cắt là 200 chứ không phải 100 đâu nhé. Mỗi bên bạn cắt 100. Vị chi 2 bên là 200 phải không bạn ?
Bạn nên bổ sung khoảng cách cắt là một biến và khai báo biến này bằng hàm getdist
  • 1

#92 tuan_thietkedien

tuan_thietkedien

    biết lệnh mirror

  • Members
  • PipPipPip
  • 153 Bài viết
Điểm đánh giá: 15 (tàm tạm)

Đã gửi 24 April 2009 - 11:33 AM

Vì hình của bạn có nhiều đối tượng => nên tắt chế độ bắt điểm đi thì Lisp chạy OK ngay.
Đây bạn :


(defun c:test ()
(setq osold (getvar "osmode"))
(setvar "osmode" 0)
(vl-load-com)
(setq TapChon (ssget '((0 . "LINE,LWPOLYLINE")))
SoDoiTuong (sslength TapChon)
cs1 0
)

(repeat SoDoiTuong
(setq DoiTuong1 (ssname TapChon cs1)
cs2 (+ cs1 1)
)
(repeat (- SoDoiTuong cs1 1)
(setq
DoiTuong2 (ssname TapChon cs2)
Giao (GiaoDT DoiTuong1 DoiTuong2)
cs2 (+ cs2 1)
)
(foreach Diem Giao
(setq
diem1 (list (- (car diem) 100) (cadr diem) 0)
diem2 (list (- (car diem) 100) (+ (cadr diem) 50))
diem3 (list (- (car diem) 100) (- (cadr diem) 50))
diem4 (list (+ (car diem) 100) (cadr diem) 0)
diem5 (list (+ (car diem) 100) (+ (cadr diem) 50))
diem6 (list (+ (car diem) 100) (- (cadr diem) 50))
)
(grdraw diem2 diem5 1 1)
(grdraw diem5 diem6 1 1)
(grdraw diem6 diem3 1 1)
(grdraw diem3 diem2 1 1)

(setq n (sslength tapchon)
i 0)
(while (< i n)
(setq sL (ssname tapchon i))
(setq cL (vlax-curve-getStartPoint sL))
(setq dL (vlax-curve-getEndPoint sL))

(setq eL (inters diem2 diem3 cL dL nil))
(setq hL (inters diem6 diem5 cL dL nil))

(if (= eL nil) (setq i (1+ i)))
(if (/= eL nil)
(progn
(Command "_Break" sL eL hL)
(setq i (1+ i))
)
)
)
)
)
(setq cs1 (+ cs1 1))
)
(setvar "osmode" osold)
(princ)
)
(defun GiaoDT (ent1 ent2)
(setq ob1 (vlax-ename->vla-object ent1)
ob2 (vlax-ename->vla-object ent2)
)
(setq g (vlax-variant-value
(vla-IntersectWith ob1 ob2 acExtendNone)
)
)
(if (/= (vlax-safearray-get-u-bound g 1) -1)
(setq g (vlax-safearray->list g))
(setq g nil)
)
(if g
(progn
(setq kq nil
sd (fix (/ (length g) 3))
)
(repeat sd
(setq kq (append kq (list (list (car g) (cadr g) (caddr g))))
g (cdddr g)
)
)
kq
)
nil
)

)

Với Code của bạn thì khoảng cách cắt là 200 chứ không phải 100 đâu nhé. Mỗi bên bạn cắt 100. Vị chi 2 bên là 200 phải không bạn ?
Bạn nên bổ sung khoảng cách cắt là một biến và khai báo biến này bằng hàm getdist


Mình làm được rồi bạn Tue ơi.
Cám ơn bạn đã tận tình chỉ giáo nha.
Mình làm lisp chạy thử nên để mặc định biến chạy cho lẹ, chứ khi áp dụng mình sẽ cho khai báo 1 số biến.
:(
  • 0

#93 tuan_thietkedien

tuan_thietkedien

    biết lệnh mirror

  • Members
  • PipPipPip
  • 153 Bài viết
Điểm đánh giá: 15 (tàm tạm)

Đã gửi 24 April 2009 - 11:38 AM

Chào bạn Tuan_thietkeden,
Để thực hiện việc ghep lisp này bạn cần lưu ý tới những vấn đề như sau:
1/- Việc tạo và sử dụng các hàm con trong hàm chính
2/- Các biến toàn cục và biến cục bộ trong các hàm con
3/- Các hàm lặp.

Với yêu cầu của bạn, theo mình bạn có thể tách toàn bộ yêu cầu của bạn thành từng nhiệm vụ độc lập tức là các hàm con như sau:
Bước 1: Chọn đối tượng
Bước 2: Lấy tập hợp các điểm giao nhau.(dùng lisp 1, bỏ phần insert block đi)
Bước 3: Chọn các đối tượng muốn cắt theo hướng X và các đối tượng muốn cắt theo hướng Y
Bước 4: Thực hiện lệnh cắt (dùng lisp2 kết hợp với các vòng lặp qua tất cả các điểm căt và qua tất cả các đối tượng theo mỗi hướng cắt.)
Cần lưu ý các biến toàn cục trong hàm con phải được khai báo đầy đủ trong hàm chính.

Bạn thử xem nhé, sau đó post lên, có gì mình sẽ cùng xem xét.


Chào bạn phamthanhbinh
Mình đã làm lại cái lisp này chạy cũng OK lắm.
Bạn xem thử nha.
Bạn hướng dẫn mình viết theo từng hàm con nhưng mình không quen nên không làm được, bạn gợi ý thêm cho mình nha.
http://www.cadviet.c...les/new_4_1.lsp
  • 0

#94 tuan_thietkedien

tuan_thietkedien

    biết lệnh mirror

  • Members
  • PipPipPip
  • 153 Bài viết
Điểm đánh giá: 15 (tàm tạm)

Đã gửi 24 April 2009 - 03:53 PM

Bạn Tue ơi
Mình cho biến dcat (khoảng cách cắt) dựa vào tỉ lệ bản vẽ.
Nếu tỉ lệ bản vẽ = 1/50 --> dcat = 50
Nếu tỉ lệ bản vẽ = 1/100 --> dcat = 100
Nếu tỉ lệ bản vẽ = 1/200 --> dcat = 200

Nhưng mình gặp rắc rối chỗ này, cái vòng while này khó chịu thật.
(setq taptext (ssget "x" '((0 . "TEXT")))
j 0 t1 0
)
(while (< j (sslength taptext))
(setq
e (ssname taptext j)
d (entget e)
d1 (cdr (assoc 1 d))
)
(if (= d1 "1/50") (setq dcat 50))
(if (= d1 "1/100") (setq dcat 100))
(if (= d1 "1/200") (setq dcat 200))
(if (and (/= d1 "1/50")(/= d1 "1/100")(/= d1 "1/200"))
(setq t1 (1+ t1)))
(setq j (1+ j))
)
(if (> t1 0)
(setq dcat (getint "\nTong chieu dai muon cat: ")))

Bạn giúp mình gỡ rối chỗ này nha.
http://www.cadviet.c...les/new_2_1.lsp
  • 0

#95 phamthanhbinh

phamthanhbinh

    biết lệnh adcenter

  • Moderator
  • PipPipPipPipPipPipPip
  • 6007 Bài viết
Điểm đánh giá: 3113 (tuyệt vời)

Đã gửi 24 April 2009 - 04:07 PM

Chào bạn phamthanhbinh
Mình đã thử làm theo cách bạn gợi ý nhưng cũng chưa hoàn thiện lắm.
Cái lisp này mình tạm mặc định cho nó cắt đoạn 100 theo phương ngang.
Bạn xem rồi góp ý nha.
http://www.cadviet.c...files/new_4.lsp
http://www.cadviet.c...iles/test_1.dwg

Chào bạn Tuan_thietkedien,
Mình đã đọc cái lisp bạn viết . Thấy có vấn đề như sau:
1/- Bạn chưa lập được tập hợp các giao điểm trong hàm lây giao điểm mà mới chỉ lấy được các giao điểm trong từng bước lặp. Do đó kết thúc vòng lặp của bạn chỉ trả về được các giao điểm tron bước lặp cuối cùng chứ chưa phải toàn bộ các giao điểm bạn ạ.
Để giải quyết việc này bạn có thể sử dụng hàm append để gán các giao điểm của mỗi lần lặp vào một list tập hợp giao điểm bạn ạ.
2/- Trong hàm (cat) đối tượng dt của bạn lại phải chọn lại là vì sao? Sao bạn không lấy từ các phần tử được chọn trong tập các đối tượn mà bạn đã tìm giao điểm?
Trong hàm này bạn cũng chưa phân biệt việc cắt theo các hướng x và y.
3/- Theo mình bạn nên cấu trúc lại chương trình lisp. Nên cho việc chọn đối tượng vào hàm chính và các hàm con sẽ thực hiện các nhiệm vụ riêng với các đối tượng được chọn trong hàm chính.
Việc phân loại đối tượng cắt theo hướng x và y cũng nên phân loại ngay từ trong hàm chính cho dễ bạn ạ.
Hàm con cat nên phân biết thành hai hàm là catx và caty chẳng hạn. Điều này sẽ thuận lợi hơn khi lập trình cho hàm chính.
Các hàm con catx, caty nên được sử dụng ngay trong vòng lặp tìm giao điểm bạn ạ cùng với các điều kiện. Như vậy chương trình sẽ gọn hơn đỡ phải làm thêm vòng lặp (foreach diemgiao Tapgiaodiem ......) bạn ạ.

Bạn thử viết lại nhé.
  • 1
Chúc các quý Anh trên diễn đàn luôn khỏe, đẻ thêm được nhiều thứ để mót.

#96 phamthanhbinh

phamthanhbinh

    biết lệnh adcenter

  • Moderator
  • PipPipPipPipPipPipPip
  • 6007 Bài viết
Điểm đánh giá: 3113 (tuyệt vời)

Đã gửi 24 April 2009 - 04:38 PM

Chào bạn phamthanhbinh
Mình đã làm lại cái lisp này chạy cũng OK lắm.
Bạn xem thử nha.
Bạn hướng dẫn mình viết theo từng hàm con nhưng mình không quen nên không làm được, bạn gợi ý thêm cho mình nha.
http://www.cadviet.c...les/new_4_1.lsp

Chào bạn Tuan_thietkedien,
Mình vừa post bài xong thì thấy bài mới của bạn. Trong lisp mới của bạn, bạn đã đi đúng hướng mình nói rồi đó, bạn đã đưa việc cat vào trong vòng lặp tìm giao điểm rồi. Tuy nhiên bạn chưa cat theo hai phương được mà mới chỉ cát theo phương x thôi. Đối tượng cắt của bạn là doituong2. Như vậy sẽ có vấn đề là do việc tìm giao điểm là theo trật tự đối tượng trong tập hợp đã chọn nên có thể doituong2 của bạn không phải là đối tượng bạn muốn cắt theo phương x, khi đó thì sao???
Với các line thì tapgiaodiem của bạn sẽ chỉ có 1 điểm duy nhất, còn vói các polyline có thể Tapgiaodiem của bạn sẽ có nhiều điểm. Lúc này bạn chỉ cắt doituong2 có còn hợp lý không???
Với các line hay polyline nằm trong tập chọn nhưng không song song với các trục tọa độ thì bạn có cần cắt không nhỉ?
Bạn xem thêm bài post trước của mình để bổ sung phần cat theo hướng trục y bạn nhé. Sụ dụng hai hàm con catx và caty kết hợp với hàm điều kiện bạn ạ.
Việc viết hàm con không quá khó, chỉ cần bạn lưu ý cách sử dụng các biến của hàm con mà thôi, khi nào dùng biến toàn cục, khi nào dùng biến cục bộ. Tất cả các biến toàn cục của hàm con phải được khai báo đấy đủ trong hàm chính, nếu không lisp sẽ bị lỗi too few argument bạn ạ.
  • 1
Chúc các quý Anh trên diễn đàn luôn khỏe, đẻ thêm được nhiều thứ để mót.

#97 tuan_thietkedien

tuan_thietkedien

    biết lệnh mirror

  • Members
  • PipPipPip
  • 153 Bài viết
Điểm đánh giá: 15 (tàm tạm)

Đã gửi 24 April 2009 - 04:52 PM

Chào bạn Tuan_thietkedien,
Mình vừa post bài xong thì thấy bài mới của bạn. Trong lisp mới của bạn, bạn đã đi đúng hướng mình nói rồi đó, bạn đã đưa việc cat vào trong vòng lặp tìm giao điểm rồi. Tuy nhiên bạn chưa cat theo hai phương được mà mới chỉ cát theo phương x thôi. Đối tượng cắt của bạn là doituong2. Như vậy sẽ có vấn đề là do việc tìm giao điểm là theo trật tự đối tượng trong tập hợp đã chọn nên có thể doituong2 của bạn không phải là đối tượng bạn muốn cắt theo phương x, khi đó thì sao???
Với các line thì tapgiaodiem của bạn sẽ chỉ có 1 điểm duy nhất, còn vói các polyline có thể Tapgiaodiem của bạn sẽ có nhiều điểm. Lúc này bạn chỉ cắt doituong2 có còn hợp lý không???
Với các line hay polyline nằm trong tập chọn nhưng không song song với các trục tọa độ thì bạn có cần cắt không nhỉ?
Bạn xem thêm bài post trước của mình để bổ sung phần cat theo hướng trục y bạn nhé. Sụ dụng hai hàm con catx và caty kết hợp với hàm điều kiện bạn ạ.
Việc viết hàm con không quá khó, chỉ cần bạn lưu ý cách sử dụng các biến của hàm con mà thôi, khi nào dùng biến toàn cục, khi nào dùng biến cục bộ. Tất cả các biến toàn cục của hàm con phải được khai báo đấy đủ trong hàm chính, nếu không lisp sẽ bị lỗi too few argument bạn ạ.


Chào bạn phamthanhbinh
Bạn phân tích kỹ lưỡng thật.
Thật sự nhiều khi mình viết theo kiểu hên xui đó bạn, có những lúc mình nghĩ hoài mà cũng không ra giải pháp,
bèn viết đại, nếu không đúng sửa lại chút đỉnh. Do đó nhiều khi mình viết được 1 lisp mà không chắc là hiểu nó hết 100%.
Những cái bạn hướng dẫn mình sẽ cố gắng thực hiện, nếu không được nhờ bạn thêm nha.
Trước mắt mình không hiểu biến cục bộ và biến toàn cục đó bạn.
Ví dụ :
(defun c:test ( x / y)
Vậy biến x và y , cái nào là biến cục bộ , cái nào là biến toàn cục.
Bạn giải thích thêm chỗ này tí nha.
:(
  • 0

#98 phamthanhbinh

phamthanhbinh

    biết lệnh adcenter

  • Moderator
  • PipPipPipPipPipPipPip
  • 6007 Bài viết
Điểm đánh giá: 3113 (tuyệt vời)

Đã gửi 24 April 2009 - 05:19 PM

Bạn Tue ơi
Mình cho biến dcat (khoảng cách cắt) dựa vào tỉ lệ bản vẽ.
Nếu tỉ lệ bản vẽ = 1/50 --> dcat = 50
Nếu tỉ lệ bản vẽ = 1/100 --> dcat = 100
Nếu tỉ lệ bản vẽ = 1/200 --> dcat = 200

Nhưng mình gặp rắc rối chỗ này, cái vòng while này khó chịu thật.

(setq taptext (ssget "x" '((0 . "TEXT")))
j 0 t1 0
)
(while (< j (sslength taptext))
(setq
e (ssname taptext j)
d (entget e)
d1 (cdr (assoc 1 d))
)
(if (= d1 "1/50") (setq dcat 50))
(if (= d1 "1/100") (setq dcat 100))
(if (= d1 "1/200") (setq dcat 200))
(if (and (/= d1 "1/50")(/= d1 "1/100")(/= d1 "1/200"))
(setq t1 (1+ t1)))
(setq j (1+ j))
)
(if (> t1 0)
(setq dcat (getint "\nTong chieu dai muon cat: ")))

Bạn giúp mình gỡ rối chỗ này nha.
http://www.cadviet.c...les/new_2_1.lsp

Chào bạn Tuan_thietkedien,
Cái vướng của bạn có phải là nó luôn đòi bạn nhập tong chieu dai muon cat không?
Cái đó là do trong vòng lặp while bạn đã cho biến t1 chạy tăng dần mỗi khi gặp text khác với các giá trị 1/50, 1/100, 1/200. Mà trong bản vẽ của bãn sẽ có ti tỉ cái text này. Vì thế kết thúc vòng lặp này biến t1 của bạn chắc chắn lớn hơn 0 rồi. Và thế là thằng cu if tiếp theo nó sẽ thực hiện nhiệm vụ của nó là hỏi bạn thôi.
Theo mình thì cái biến t1 của bạn ở đây không được việc gì cả, quẳng béng nó đi bạn ạ. Còn nếu bạn muốn nhập cái tổng chiều dài muốn cắt khi tỷ lệ bản vẽ khác với các tỷ lệ 1/50, 1/100, 1/200 thì chỉ cần đơn giản là sau khi kết thúc vòng lặp while, bạn viết hàm (if (= 0 dcat) (setq ......)) là được bạn ạ.
Trước khi vào vòng lặp while bạn nên đặt trước biến dcat bằng 0 cho chắc ăn.
Hy vọng mình đoán mò đúng cái chỗ bạn vướng.
Chúc bạn thành công.
  • 2
Chúc các quý Anh trên diễn đàn luôn khỏe, đẻ thêm được nhiều thứ để mót.

#99 Tue_NV

Tue_NV

    KS Võ Quang Tuệ

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

Đã gửi 25 April 2009 - 07:56 AM

Bạn Tue ơi
Mình cho biến dcat (khoảng cách cắt) dựa vào tỉ lệ bản vẽ.
Nếu tỉ lệ bản vẽ = 1/50 --> dcat = 50
Nếu tỉ lệ bản vẽ = 1/100 --> dcat = 100
Nếu tỉ lệ bản vẽ = 1/200 --> dcat = 200

Nhưng mình gặp rắc rối chỗ này, cái vòng while này khó chịu thật.

(setq taptext (ssget "x" '((0 . "TEXT")))
j 0 t1 0
)
(while (< j (sslength taptext))
(setq
e (ssname taptext j)
d (entget e)
d1 (cdr (assoc 1 d))
)
(if (= d1 "1/50") (setq dcat 50))
(if (= d1 "1/100") (setq dcat 100))
(if (= d1 "1/200") (setq dcat 200))
(if (and (/= d1 "1/50")(/= d1 "1/100")(/= d1 "1/200"))
(setq t1 (1+ t1)))
(setq j (1+ j))
)
(if (> t1 0)
(setq dcat (getint "\nTong chieu dai muon cat: ")))

Bạn giúp mình gỡ rối chỗ này nha.
http://www.cadviet.c...les/new_2_1.lsp

Chưa hiểu ý của bạn lắm. Hãy upload file .dwg và nói rõ hơn bạn nhé.
Qua cái ý của bạn PhamthanhBinh thì hoàn toàn chính xác đấy
  • 1

#100 tuan_thietkedien

tuan_thietkedien

    biết lệnh mirror

  • Members
  • PipPipPip
  • 153 Bài viết
Điểm đánh giá: 15 (tàm tạm)

Đã gửi 25 April 2009 - 08:31 AM

Chào bạn Tuan_thietkedien,
Cái vướng của bạn có phải là nó luôn đòi bạn nhập tong chieu dai muon cat không?
Cái đó là do trong vòng lặp while bạn đã cho biến t1 chạy tăng dần mỗi khi gặp text khác với các giá trị 1/50, 1/100, 1/200. Mà trong bản vẽ của bãn sẽ có ti tỉ cái text này. Vì thế kết thúc vòng lặp này biến t1 của bạn chắc chắn lớn hơn 0 rồi. Và thế là thằng cu if tiếp theo nó sẽ thực hiện nhiệm vụ của nó là hỏi bạn thôi.
Theo mình thì cái biến t1 của bạn ở đây không được việc gì cả, quẳng béng nó đi bạn ạ. Còn nếu bạn muốn nhập cái tổng chiều dài muốn cắt khi tỷ lệ bản vẽ khác với các tỷ lệ 1/50, 1/100, 1/200 thì chỉ cần đơn giản là sau khi kết thúc vòng lặp while, bạn viết hàm (if (= 0 dcat) (setq ......)) là được bạn ạ.
Trước khi vào vòng lặp while bạn nên đặt trước biến dcat bằng 0 cho chắc ăn.
Hy vọng mình đoán mò đúng cái chỗ bạn vướng.
Chúc bạn thành công.


Bạn bình gãi đúng chỗ ngứa của mình rồi. :(
Để mình thử lại theo bạn hướng dẫn hoặc up file lên cho anh em nghiên cứu ha.
  • 0