Đến nội dung


Hình ảnh
- - - - -

Lisp nối Line thành Pline ?


  • Please log in to reply
80 replies to this topic

#41 Tot77

Tot77

    biết lệnh adcenter

  • Members
  • PipPipPipPipPipPipPip
  • 990 Bài viết
Điểm đánh giá: 498 (tốt)

Đã gửi 07 April 2014 - 02:40 PM

cái này chỉ có thể sai khi bạn cho cái khoảng cách kc lớn hơn  chiều dài ngắn nhất của line,arc

Còn cái vụ tìm start hay end thi trong hàm noithem đã tính rồi.


  • 1

#42 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 5448 Bài viết
Điểm đánh giá: 2624 (tuyệt vời)

Đã gửi 07 April 2014 - 02:47 PM

Bạn thử chọn ss theo thứ tự 1, 2, 3. Với kc=2.

Khi đó nó "treo" luôn. Mặc dầu thực tế đúng là phải xếp theo thứ tự 2, 3, 1.

http://www.cadviet.c...29_noi_duoi.dwg


  • 1

* Chỉ nên yêu cầu Lisp khi bạn làm việc đó mất cả ngày nhưng họ chỉ viết 1 giờ. Đừng nêu yêu cầu Lisp khi bạn chỉ làm 1 giờ nhưng bắt họ phải mất cả ngày.

* Nhờ viết lisp cũng như đi khám bệnh. Chỉ gởi căn cước và than sắp chết thì không bác sỹ nào cứu sống được.


#43 Tot77

Tot77

    biết lệnh adcenter

  • Members
  • PipPipPipPipPipPipPip
  • 990 Bài viết
Điểm đánh giá: 498 (tốt)

Đã gửi 07 April 2014 - 03:19 PM

Có vẻ hàm equal so sánh khoảng cách 2 điểm không đúng bằng hàm distance, sửa lại hàm noithem như sau :

 

 

(defun noithem(d v kc tr / tm tm1)
    (if (setq tm (car (vl-remove nil
(mapcar '(lambda(x) (if (and (/= v (cadar x))
    (or (<= (distance d (car x)) kc) (<= (distance d (last x)) kc))) x nil)) L1))))
      (if (or (and tr (<= (distance d (car tm)) kc)) 
     (and (not tr) (<= (distance d (last tm)) kc)))
(setq ng t tm1 (reverse tm))
(setq ng nil tm1 tm)))
  )

 


  • 1

#44 Polyline

Polyline

    biết lệnh mirror

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

Đã gửi 07 April 2014 - 03:38 PM

Có vẻ như với KC=0 thì nó không chạy được bạn ạ!


  • 0

#45 sgcq

sgcq

    Hội Hai Lúa

  • Members
  • PipPipPipPipPipPipPip
  • 1880 Bài viết
Điểm đánh giá: 692 (tốt)

Đã gửi 07 April 2014 - 03:40 PM

:D :D :D

2 lúa cần 1 option nhưng không tìm thấy trong lisp, bác nào vui lòng chỉ giúp:

Mô tả option:

Khi gõ lệnh "nn" lisp sẽ tự tìm các line/polyline chưa được nối và nối chúng với nhau, người dùng không cần chỉ định line/polyline.

:D :D :D


  • -1

12728974_230210507314169_718723558582070 HỘI HAI LÚA

           fanpage: https://www.facebook.com/HoiHaiLua/

 

 

 

 

 

 


#46 Tot77

Tot77

    biết lệnh adcenter

  • Members
  • PipPipPipPipPipPipPip
  • 990 Bài viết
Điểm đánh giá: 498 (tốt)

Đã gửi 07 April 2014 - 03:49 PM

@sgcq :cái đó để khi khác ở topic khác, ở đây bạn polyline chỉ cần cái giải thuật thôi.

@polyline : không hiểu bạn cho kc=0 ở cái hình nào, nếu ở file doan van ha đưa lên thì dĩ nhiên không chạy được vì 3 đoạn đó tách rời ra mà, làm sao bằng kc=0 mà chạy được. Còn ở file bạn đưa thì chạy tốt. Bạn thử đưa thêm file khác xem sao.


  • 0

#47 phamthanhbinh

phamthanhbinh

    biết lệnh adcenter

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

Đã gửi 07 April 2014 - 03:54 PM

Mình có 2 đối tượng này mà không nối bằng lệnh Pedit được.

 

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

 

Mình cũng đang viết một lisp để nối các (0 . "*LINE,ARC") lại với nhau mà không cần sử dụng lệnh PEDIT.

Tuy nhiên mình đang bí về thuật toán. Sau khi chọn "một cục" đối tượng xong, mình không biết làm sao để sắp xếp các đối tượng theo kiểu "End to End", nghĩa là các đối tượng này "nối đuôi" nhau (các điểm có thể trùng nhau hoặc cách nhau một đoạn cho trước).

 

Mong được sự giúp đỡ của các bác!

Hề hề hề,

Khi pedit thì nếu chọn cái lwpolyline đỏ trước cad sẽ bào lỗi là: The object is not parallel to the UCS.

Mặc dù mã 38 của lwpolyline này vẫn là 0.

Vì vậy mà nó không joint được. Bác thử flaten nó coi sao.

Command: _pedit Select polyline or [Multiple]:
 
Command: _pedit Select polyline or [Multiple]:

  • 0
Chúc các quý Anh trên diễn đàn luôn khỏe, đẻ thêm được nhiều thứ để mót.

#48 Tot77

Tot77

    biết lệnh adcenter

  • Members
  • PipPipPipPipPipPipPip
  • 990 Bài viết
Điểm đánh giá: 498 (tốt)

Đã gửi 07 April 2014 - 04:04 PM

à tôi hiểu tại sao kc=0 mà không chạy dc rồi. vì khi bạn cho kc= 0 thì hai điểm phải tuyệt đối trùng lên nhau, thực tế nhiều khi mắt mình thấy trùng nhưng nó không trùng, distance giữa nó vẫn >0, do đó không chạy được. Khoảng cách kc là cái sai số tối thiểu để nó nối, bạn cho = 0 thì là bạn ép nó quá không cho nó thở, làm sao nó làm việc? :blink:


  • 0

#49 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 5448 Bài viết
Điểm đánh giá: 2624 (tuyệt vời)

Đã gửi 07 April 2014 - 04:14 PM

Polyme có thể tham khảo thêm lisp này để modify thành cái của mình.

http://www.cadviet.c...=0


  • 1

* Chỉ nên yêu cầu Lisp khi bạn làm việc đó mất cả ngày nhưng họ chỉ viết 1 giờ. Đừng nêu yêu cầu Lisp khi bạn chỉ làm 1 giờ nhưng bắt họ phải mất cả ngày.

* Nhờ viết lisp cũng như đi khám bệnh. Chỉ gởi căn cước và than sắp chết thì không bác sỹ nào cứu sống được.


#50 ndtnv

ndtnv

    biết lệnh minsert

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

Đã gửi 07 April 2014 - 04:29 PM

Hàm không có điều kiện dừng khi có 1 phần tử không nối thêm được


  • 0

#51 Tot77

Tot77

    biết lệnh adcenter

  • Members
  • PipPipPipPipPipPipPip
  • 990 Bài viết
Điểm đánh giá: 498 (tốt)

Đã gửi 07 April 2014 - 06:00 PM

Nhân đề nghị của anh 2 lúa cad nông dân bên trên tôi làm thêm 1 bước nữa, chỉ cần đánh lệnh test nó sẽ tự động nối line,arc.

Nhưng tôi chưa có file line arc số lượng lớn để test, bạn nào có file lớn đưa lên để test thử. File lisp như sau:

 

 

(defun c:test(/ kc L1 L2 tieptuc tm1 tm2 tm ng obj)
  (defun noithem(d v kc tr / tm tm1)
    (if (setq tm (car (vl-remove nil
(mapcar '(lambda(x) (if (and (/= v (cadar x))
    (or (<= (distance d (car x)) kc) (<= (distance d (last x)) kc))) x nil)) L1))))
    (if (or (and tr (<= (distance d (car tm)) kc)) 
            (and (not tr) (<= (distance d (last tm)) kc)))
    (setq ng t tm1 (reverse tm))
    (setq ng nil tm1 tm)))
  )
  
  (defun ssfrom (sl / ss0) (setq ss0 (ssadd)) (foreach v sl (ssadd v ss0)) ss0)
  ;;;
  (setq kc (getreal "\nNhap khoang ho cho phep de noi:")
L1 (mapcar '(lambda(x) (list (vlax-curve-getStartPoint (setq obj (vlax-ename->vla-object x))) x
(vlax-curve-getEndPoint obj))) (acet-ss-to-list (ssget "X" '((0 . "LINE,ARC")))))
L2 (list (car L1))
L1 (cdr L1))
  (setvar "cmdecho" 0)
  (while L1
    (setq tieptuc t)
    (while tieptuc      
      (if (setq tm1 (noithem (caar L2) (cadar L2) kc t))
        (setq L2 (cons tm1 L2) L1 (vl-remove (if ng (reverse tm1) tm1) L1)))
      (if (setq tm2 (noithem (last (last L2)) (cadr (last L2)) kc nil))
        (setq L2 (append L2 (list tm2)) L1 (vl-remove (if ng (reverse tm2) tm2) L1)))
      (if (and (not tm1)(not tm2))
(setq tieptuc nil
     tm (COMMAND ".PEDIT" "M" (ssfrom (mapcar 'cadr L2)) ""  "Y" "J" kc "")
     L2 (list (car L1))
     L1 (cdr L1)))
    )
  )
  (setvar "cmdecho" 1)
)
 

  • 1

#52 Polyline

Polyline

    biết lệnh mirror

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

Đã gửi 08 April 2014 - 10:41 AM

hehe, nhiều khi không thể nối được với lệnh PEDIT, kể cả đã nhập khoảng hở lớn (File ví dụ ở #38). Vì vậy, liệu có thể nối các PLINE, LINE và ARC mà không dùng lệnh PEDIT không?


  • 0

#53 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 5448 Bài viết
Điểm đánh giá: 2624 (tuyệt vời)

Đã gửi 08 April 2014 - 10:56 AM

hehe, nhiều khi không thể nối được với lệnh PEDIT, kể cả đã nhập khoảng hở lớn (File ví dụ ở #38). Vì vậy, liệu có thể nối các PLINE, LINE và ARC mà không dùng lệnh PEDIT không?

Ở #38 thì DXF 210 của đường vàng là default  (210 0.0 0.0 1.0), trong lúc của đường đỏ là (210 0.0 0.0 -1.0).


  • 0

* Chỉ nên yêu cầu Lisp khi bạn làm việc đó mất cả ngày nhưng họ chỉ viết 1 giờ. Đừng nêu yêu cầu Lisp khi bạn chỉ làm 1 giờ nhưng bắt họ phải mất cả ngày.

* Nhờ viết lisp cũng như đi khám bệnh. Chỉ gởi căn cước và than sắp chết thì không bác sỹ nào cứu sống được.


#54 Tot77

Tot77

    biết lệnh adcenter

  • Members
  • PipPipPipPipPipPipPip
  • 990 Bài viết
Điểm đánh giá: 498 (tốt)

Đã gửi 08 April 2014 - 10:57 AM

File ví dụ ở #38 thì đúng như bác Bình nói, nên không nối được.

Chẳng có cách nào mà không dùng pedit để tạo pline, trừ khi bạn xoá hết rồi entmake cái giống y vậy, nhưng làm thế thì tự chui đầu vào mớ bòng bong rồi.


  • 0

#55 Tot77

Tot77

    biết lệnh adcenter

  • Members
  • PipPipPipPipPipPipPip
  • 990 Bài viết
Điểm đánh giá: 498 (tốt)

Đã gửi 08 April 2014 - 11:31 AM

2 cái vàng đỏ trong #38 không cùng nằm trong 1 hệ trục toạ độ, cho nên 2 đỉnh cuối của nó tuy mắt mình thấy trùng nhưng trong dxf data của nó cách nhau rất xa ~51000 và ~-51000 nên không thể nối đc là vì vậy.

-510941.0 
1.77214e+006

  • 0

#56 Polyline

Polyline

    biết lệnh mirror

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

Đã gửi 08 April 2014 - 01:26 PM

File ví dụ ở #38 thì đúng như bác Bình nói, nên không nối được.
Chẳng có cách nào mà không dùng pedit để tạo pline, trừ khi bạn xoá hết rồi entmake cái giống y vậy, nhưng làm thế thì tự chui đầu vào mớ bòng bong rồi.

Mình tin là có thể làm được, với thuật toán như sau:
1. Khoanh vùng chọn (0 . "*LINE,ARC").
2. Convert tất cả các đối tượng không phải là Lwpolyline thành Lwpolyline (bằng lệnh Pedit hoặc Convert hoặc entmake).
3. Lấy ra một Lwpolyline.
4. Tách riêng mã DXF của đối tượng đó ra thành 3 nhóm ds1, ds2 và ds3
  (Trong đó ds2 chứa thông tin các mã 10, 40, 41, 42 của tất cả các đỉnh), ds1 và ds3 và phần còn lại trước và sau của ds2
5. Xử lý ds2 bằng cách thêm vào tất cả các đỉnh của tất cả các đối tượng còn lại.
6. Xóa hết đối tượng chọn, ngoại trừ đối tượng lấy mã DXF
7. Entmod ds1+ds2+ds3.
 
Vấn đề khó nhất nằm ở chỗ sắp xếp các điểm trong ds2 theo kiểu End-to-End.
  • 0

#57 Polyline

Polyline

    biết lệnh mirror

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

Đã gửi 08 April 2014 - 01:30 PM

2 cái vàng đỏ trong #38 không cùng nằm trong 1 hệ trục toạ độ, cho nên 2 đỉnh cuối của nó tuy mắt mình thấy trùng nhưng trong dxf data của nó cách nhau rất xa ~51000 và ~-51000 nên không thể nối đc là vì vậy.

-510941.0 
1.77214e+006

Mình nghĩ là AutoCAD hiểu được 2 điểm này trùng nhau. Vui lòng xem ảnh.

118851_222.gif


  • 0

#58 phamthanhbinh

phamthanhbinh

    biết lệnh adcenter

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

Đã gửi 08 April 2014 - 01:32 PM

2 cái vàng đỏ trong #38 không cùng nằm trong 1 hệ trục toạ độ, cho nên 2 đỉnh cuối của nó tuy mắt mình thấy trùng nhưng trong dxf data của nó cách nhau rất xa ~51000 và ~-51000 nên không thể nối đc là vì vậy.

-510941.0 
1.77214e+006

Hề hề hề,

Có cái lạ là khi view, dù xoay view kiểu gì thì hai đường này vẫn dính nhau. nhân tiện mọi người có ai rành về cái mã dxf 210 này xin giải thích giùm

Khi mình dùng subst để thay thế mã dxf 210 của nó về (210 0.0 0.0 -1.0) thì thằng cu này biến mất khỏi màn hình dù zoom all cũng chả thấy nó đâu.


  • 0
Chúc các quý Anh trên diễn đàn luôn khỏe, đẻ thêm được nhiều thứ để mót.

#59 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 5448 Bài viết
Điểm đánh giá: 2624 (tuyệt vời)

Đã gửi 08 April 2014 - 03:17 PM

Mình tin là có thể làm được, với thuật toán như sau:
1. Khoanh vùng chọn (0 . "*LINE,ARC").
2. Convert tất cả các đối tượng không phải là Lwpolyline thành Lwpolyline (bằng lệnh Pedit hoặc Convert hoặc entmake).
3. Lấy ra một Lwpolyline.
4. Tách riêng mã DXF của đối tượng đó ra thành 3 nhóm ds1, ds2 và ds3
  (Trong đó ds2 chứa thông tin các mã 10, 40, 41, 42 của tất cả các đỉnh), ds1 và ds3 và phần còn lại trước và sau của ds2
5. Xử lý ds2 bằng cách thêm vào tất cả các đỉnh của tất cả các đối tượng còn lại.
6. Xóa hết đối tượng chọn, ngoại trừ đối tượng lấy mã DXF
7. Entmod ds1+ds2+ds3.
 
Vấn đề khó nhất nằm ở chỗ sắp xếp các điểm trong ds2 theo kiểu End-to-End.

Lấy ví dụ ở bản vẽ mà Polime gởi lên:

Tại điểm mà Polime gọi là trùng nhau đấy, mã 10 của chúng khác nhau xa vời, mặc dầu ID là giống nhau, bởi mỗi thứ được xét trong 1 hệ tọa độ khác nhau. Suy ra, nếu đơn thuần chỉ lấy mã 10 gộp lại để entmod hay entmake thì không thể được.

Phải có cách khác thôi. Và tôi cũng đang hy vọng là có thể được.


  • 0

* Chỉ nên yêu cầu Lisp khi bạn làm việc đó mất cả ngày nhưng họ chỉ viết 1 giờ. Đừng nêu yêu cầu Lisp khi bạn chỉ làm 1 giờ nhưng bắt họ phải mất cả ngày.

* Nhờ viết lisp cũng như đi khám bệnh. Chỉ gởi căn cước và than sắp chết thì không bác sỹ nào cứu sống được.


#60 Polyline

Polyline

    biết lệnh mirror

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

Đã gửi 08 April 2014 - 03:35 PM

oh, thật là kỳ lạ! Đúng là mã 10 của nó khác xa nhau, nhưng lệnh ID vẫn trả về cùng một giá trị!

Có lẽ do hai vectơ chỉ hướng đối xứng nhau (210 0 0 1) và (210 0 0 -1) nên dẫn đến tọa độ X ngược dấu nhau.

Như vậy, ngoài mã 10 phải xét đến cả vectơ chỉ hướng nữa.


  • 0