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ạ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.

  • 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
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.com/upfiles/new2.lsp

http://www.cadviet.com/upfiles/test_1.dwg

 

Bạn Tue và bạn bình góp ý cho mình với 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
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.com/upfiles/new_4.lsp

http://www.cadviet.com/upfiles/test_1.dwg

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 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.com/upfiles/new2.lsp

http://www.cadviet.com/upfiles/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

  • 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
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.com/upfiles/new2_1.lsp

http://www.cadviet.com/upfiles/Book1_6.xls

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á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.com/upfiles/new2_1.lsp

http://www.cadviet.com/upfiles/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 ((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

  • 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
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.

:(

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 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.com/upfiles/new_4_1.lsp

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ạ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.com/upfiles/new_2_1.lsp

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 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.com/upfiles/new_4.lsp

http://www.cadviet.com/upfiles/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é.

  • 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
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.com/upfiles/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 ạ.

  • 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
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.

:(

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ạ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 ((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.com/upfiles/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.

  • Vote tăng 2

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ạ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 ((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.com/upfiles/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

  • 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
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.

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 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.

 

Chào bạn phamthanhbinh

Thuật toán đơn giản thế mà mình nghĩ hoài cũng không ra. :(

Nội công của mình còn yếu quá , phải tập luyện thêm thôi.

Cám ơn bạn và bạn Tue luôn giúp đỡ nha.

Chúc 2 bạn và mọi người cuối tuần vui vẻ. :(

  • 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
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.

:(

Chào bạn Tuan_thietkedien,

Trong cái ví dụ bạn đưa thì x là biến toàn cục (global) và y là biến cục bộ (local) bạn ạ.

Biến toàn cục là biến được sử dụng trong toàn bộ chương trình, sau khi kết thúc nó được lưu lại để sử dụng tiếp cho các chương trình khác có liên quan bạn ạ.

Biến cục bộ là biến chỉ được sử dụng trong chương trình chứa nó, Khi kết thúc chương trình này biến đó được trả về nil nhằm giảm bớt khối lượng làm việc của các chuong trình có liên quan bạn ạ.

Trong ví dụ của bạn, nếu bạn gán cho biến x và y các giá trị nào đó thì kết thúc chương trình giá trị của biến x vẫn giữ nguyên còn giá trị của biến y sẽ là nil bất kể bạn đã làm gì với biến y đó trong suốt quá trình chạy chương trình.

Để hiểu rõ hơn vấn đề này bạn có thể tham khảo trong tài liệu mình đã gửi bạn hoặc trên diễn đàn, bài viết của bác SSG về các biến này trong bài post đầu tiên ở mục này bạn ạ. Ngoài ra trên diễn đàn cũng có nhiều tài liệu để tham khảo về cái này nhưng mình không nhớ rõ lắm , bạn thử tìm kiếm xem nhé.

Chúc bạn vui.

  • 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
Chào bạn Tuan_thietkedien,

Trong cái ví dụ bạn đưa thì x là biến toàn cục (global) và y là biến cục bộ (local) bạn ạ.

Biến toàn cục là biến được sử dụng trong toàn bộ chương trình, sau khi kết thúc nó được lưu lại để sử dụng tiếp cho các chương trình khác có liên quan bạn ạ.

Biến cục bộ là biến chỉ được sử dụng trong chương trình chứa nó, Khi kết thúc chương trình này biến đó được trả về nil nhằm giảm bớt khối lượng làm việc của các chuong trình có liên quan bạn ạ.

Trong ví dụ của bạn, nếu bạn gán cho biến x và y các giá trị nào đó thì kết thúc chương trình giá trị của biến x vẫn giữ nguyên còn giá trị của biến y sẽ là nil bất kể bạn đã làm gì với biến y đó trong suốt quá trình chạy chương trình.

Để hiểu rõ hơn vấn đề này bạn có thể tham khảo trong tài liệu mình đã gửi bạn hoặc trên diễn đàn, bài viết của bác SSG về các biến này trong bài post đầu tiên ở mục này bạn ạ. Ngoài ra trên diễn đàn cũng có nhiều tài liệu để tham khảo về cái này nhưng mình không nhớ rõ lắm , bạn thử tìm kiếm xem nhé.

Chúc bạn vui.

Em xin đăng ký một chân đi mót bác Bình đây! mong bác đồng ý 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
Em xin đăng ký một chân đi mót bác Bình đây! mong bác đồng ý nhá!

Hì hì,

Bác cứ hay đùa dai,

Mình lọ mọ đi mót được tí chút, bác lại đòi mót lại của mình có mà ăn rễ hử bác. Bác cứ chịu khó vô cánh đồng Cadviet là tha hồ mót, lại chả bị bảo vệ chửi mắng bao giờ. Lâu lâu gặp phải mấy bác khó tính, bác cứ làm quả ofline là lại oke salem, xem xem giống bu cháu ngay ấy mà.

Cái đời đi mót nhiều khi cũng tủi lắm bác ạ. Thế nhưng mà vui ra phết. Đi mãi mới tìm được cái đồng Cadviet màu mỡ, mót mãi chửa hết bác ạ. Bác mà khoái thì cứ theo mình vào đó mót bác nhé.

Chúc bác năng nhặt chặt bị bác ạ.

  • 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

Chào bạn phamthanhbinh

 

Mình cố lắm rồi cũng chỉ giải quyết được tới đây. Lisp chỉ có thể cắt Line theo phương X hay phương Y khi các Line ấy vuông góc với nhau thôi. Còn khi nào cắt theo phương X hay phương Y mình nhờ code của bạn Tue_NV để lấy điêm đầu và điểm cuối của 1 Line. Nếu 1 Line có tung độ điểm đầu = tung độ điểm cuối thì Line ấy nằm phương X.

 

(defun c:test ( / ss SoDoiTuong i cs1 cs2 ei dd dc osold TapGiaoDiem DoiTuongY DoiTuongX 
			 sodoituongx sodoituongy pt1 pt2 taptext j e d d1 dcat )
(vl-load-com)
(setq osold (getvar "osmode"))
(setvar "osmode" 0)
(setq ss (ssget '((0 . "LINE,LWPOLYLINE")))
taptext (ssget "x" '((0 . "TEXT")))
sodoituong (sslength ss)
sodoituongx 0 sodoituongy 0 TapGiaoDiem 0 i 0 j 0 dcat 0 cs1 0 cs2 0
)
;;;So sanh so luong giua SoDoiTuongX va SoDoiTuongY
(while (< i sodoituong)
(setq ei (ssname ss i))
(setq dd (vlax-curve-getStartPoint ei))
(setq dc (vlax-curve-getEndPoint ei))
(if (= (cadr dd) (cadr dc))
(setq sodoituongx (1+ sodoituongx))
(setq sodoituongy (1+ sodoituongy))
)
(setq i (1+ i))
)
;;;Lay noi dung TEXT
(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))
(setq j (1+ j))
)
(if (= dcat 0)
(setq dcat (getint "\nTong chieu dai muon cat: ")))
;;;Cat doi tuong
(repeat SoDoiTuong
(setq DoiTuongx (ssname ss cs1)
cs2 (+ cs1 1)
)
(repeat (- SoDoiTuong cs1 1)
(setq 
DoiTuongy (ssname ss cs2)
TapGiaoDiem (GiaoDT DoiTuongx DoiTuongy)
cs2 (+ cs2 1)
)
;;;DoituongX > DoituongY --> Cat Y
(if (>= SoDoiTuongx SoDoiTuongy)
(foreach diemgiao TapGiaoDiem
(setq
pt1(list (+ (car diemgiao) dcat) (+ (cadr diemgiao) 0) 0)
pt2(list (- (car diemgiao) dcat) (+ (cadr diemgiao) 0) 0)
)
(command ".break" doituongx pt1 pt2)
(command ".break" doituongy pt1 pt2)
))
;;;DoituongX < DoituongY --> Cat X
(if (< SoDoiTuongx SoDoiTuongy)
(foreach diemgiao TapGiaoDiem
(setq
pt1(list (+ (car diemgiao) 0) (+ (cadr diemgiao) dcat) 0)
pt2(list (+ (car diemgiao) 0) (- (cadr diemgiao) dcat) 0)
)
(command ".break" doituongx pt1 pt2)
(command ".break" doituongy pt1 pt2)
))

);End repeat1
(setq cs1 (+ cs1 1))
);End repeat2

(setvar "osmode" osold)
(princ)
);End

(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
)
)

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 thấy hiện nay cad đã hỗ trợ rất nhiều trong thực hiện các lệnh phức tạp. tại sao vẫn có nhiều người đặt câu hỏi về vđ cad đã có và dùng lisp nhỉ???

vđ/ có t/c cá nhân 1 tí, các bác thông cả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

Mình thấy trên diễn đàn các bạn hay dùng hàm tìm giao điểm hai đối tượng như thế này : (vla-IntersectWith ob1 ob2 acExtendNone), nhưng chỉ với đối tượng 2D. Còn đối tượng 3D có cao độ bất kỳ thỉ dùng như thế nào, có tìm đc giao điểm không? Có thể tìm đc giao điểm của chúng trên mặt phẳng XY mà không làm thay đổi dữ liệu của chúng đc kg? Bạn nào biết, xin chỉ giúp. Cám ơ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
Chào bạn phamthanhbinh

 

Mình cố lắm rồi cũng chỉ giải quyết được tới đây. Lisp chỉ có thể cắt Line theo phương X hay phương Y khi các Line ấy vuông góc với nhau thôi. Còn khi nào cắt theo phương X hay phương Y mình nhờ code của bạn Tue_NV để lấy điêm đầu và điểm cuối của 1 Line. Nếu 1 Line có tung độ điểm đầu = tung độ điểm cuối thì Line ấy nằm phương X.

 

.....................

Chào tuan_thietkedien

Bạn tham khảo bài viết này http://www.cadviet.com/forum/index.php?sho...c=10514&hl=

chắc chắn sẽ giải quyết được vấn đề của bạn.

  • Vote tăng 2

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 tuan_thietkedien

Bạn tham khảo bài viết này http://www.cadviet.com/forum/index.php?sho...c=10514&hl=

chắc chắn sẽ giải quyết được vấn đề của bạn.

 

Chào bác gia_bach

Cái lisp này ghê ghớm thật, Line nghiêng xéo cỡ nào cũng cắt, hoàn toàn đúng ý của em.

3 chức năng cắt thật là rất hữu ích, nhất là chức năng thứ 3 í, cái đó em thích nhất. :(

Em cám ơn bác nhiều lắm.

Chúc bác luôn vui vẻ.

:(

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ái này dùng Getpoint để lấy điểm đầu và điểm cuối của một LINE nên có thể không chính xác nếu việc chọn bắt dính không chính lung tung

BÁC SSG ơi em theo chân bác cũng kha kha rồi. Em xin hỏi cách nào để biết kiểm tra trương trình của minh viết sai ko nhi?

cách cho môt dòng lệnh chay thử như thế nào?

Bác giúp em với hoặc anh em nào biết giúp cái 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

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

×