Chuyển đến nội dung
Diễn đàn CADViet
Đăng nhập để thực hiện theo  
pdhuyxn2

Move block về đỉnh của Polyline

Các bài được khuyến nghị

22 giờ trước, pdhuyxn2 đã nói:

Nhờ các Bác viết giúp 1 lips di chuyển Block về đỉnh của Polyline Ạ. Như ví dụ dưới đây. Xin Cám ơn các Bác nhiều! 

Dichuyen Block.dwg

Đơn giản hơn là chèn block vào đỉnh pline. Còn di chuyển block về đỉnh pline nó hơi phức tạp là trường hợp có nhiều hoặc ít block hơn đỉnh pline, rồi phải so sánh block nào gần đỉnh pline hơi tốn time!

  • Like 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ào lúc 22/10/2023 tại 10:17, limfx đã nói:

Đơn giản hơn là chèn block vào đỉnh pline. Còn di chuyển block về đỉnh pline nó hơi phức tạp là trường hợp có nhiều hoặc ít block hơn đỉnh pline, rồi phải so sánh block nào gần đỉnh pline hơi tốn time!

Thuật toán move về đỉnh gần nhất rất đơn giản, bạn đừng nghĩ phức tạp làm gì

(defun c:MBP (/ ss entpl obj i p1 p2 n )
  (setq 
    ss (ssget '((0 . "INSERT")))
    entpl (vlax-ename->vla-object (Car (entsel "\nPICK PLINE")))
  )
  (repeat (setq i (sslength ss))
    (setq 
      i (1- i)
      obj (vlax-ename->vla-object (ssname ss i))
      p1 (vlax-get obj 'InsertionPoint) ;Điểm chèn Block
      n (vlax-curve-getparamatpoint entpl (vlax-curve-getclosestpointto entpl p1)) ;Parameter tại điểm gần nhất với block
      p2 (vlax-curve-getpointatparam entpl (fix (+ 0.5 n))) ;Làm tròn parameter và lấy điểm tại đó.
    )
    (vla-move obj (vlax-3d-point p1) (vlax-3d-point p2)) ;move nữa là xong
  )
  (princ)
)

 

  • Like 1
  • Vote tăng 1
  • Vote giảm 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
23 giờ trước, tannguyen291 đã nói:

Thuật toán move về đỉnh gần nhất rất đơn giản, bạn đừng nghĩ phức tạp làm gì


(defun c:MBP (/ ss entpl obj i p1 p2 n )
  (setq 
    ss (ssget '((0 . "INSERT")))
    entpl (vlax-ename->vla-object (Car (entsel "\nPICK PLINE")))
  )
  (repeat (setq i (sslength ss))
    (setq 
      i (1- i)
      obj (vlax-ename->vla-object (ssname ss i))
      p1 (vlax-get obj 'InsertionPoint) ;Điểm chèn Block
      n (vlax-curve-getparamatpoint entpl (vlax-curve-getclosestpointto entpl p1)) ;Parameter tại điểm gần nhất với block
      p2 (vlax-curve-getpointatparam entpl (fix (+ 0.5 n))) ;Làm tròn parameter và lấy điểm tại đó.
    )
    (vla-move obj (vlax-3d-point p1) (vlax-3d-point p2)) ;move nữa là xong
  )
  (princ)
)

 

image.png.a8365444fd902089de8a948976390485.png 

Lisp move thành

image.png.c80b4a6875e40e71297e1e3ea47c501e.png

  • Vote tăng 2
  • Vote giảm 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ài toán này rất thiếu các giả thiết => Lisp chỉ viết được theo cái hình trong file Cad, chứ không thể viết tổng quát được đâu.

  • 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

@limfx

Bạn yêu cầu những thứ không thiết thực. Đối với người làm thiết kế 2d thì việc di chuyển block về đỉnh và sắp xếp lại cho gọn gàng là được r.

Công cụ bạn muốn thực chất khá giống lệnh Bridge của các phần mềm 3d modeling việc tạo face mới dùng đến các thuật toán như vậy

image.png.2c4ca07055c1405885401ffb9d692ce9.png

Ngoài ra trong cad việt cũng có người viết thuật toán đấy rồi thì phải. nối các secment của 2 pline gì đó.

  • Vote giảm 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

@tannguyen291

Cũng không cần phức tạp lắm anh. Ví dụ như khi thiết kế tuyến thoát nước dịch tim tuyến đi thì những hố ga gần đỉnh sẽ về vị trí cũ. Em so sánh khoảng cách trước, nếu gần hơn thì về vị trí, sau đó đến lượt anh khác. Mày mò cũng được kết quả nè a!

(defun c:MPL ()
  (prompt "\nSelect block: ")
  (setq ss (ssget '((0 . "INSERT")))
	 plo (vlax-ename->vla-object (Car (entsel "\nPick pline: ")))
	lst nil
	lsb nil )
  (repeat (setq n (1+ (fix (vlax-curve-getEndParam plo))))
    (setq lst (cons (vlax-curve-getPointatparam plo (setq n (1- n))) lst)) )
  (repeat (setq i (sslength ss))
    (setq bo (vlax-ename->vla-object (ssname ss (setq i (1- i))))) 
    (setq lsb (cons (list bo (vlax-get bo 'InsertionPoint)) lsb)) )
  (foreach pt lst
    (setq rtnpt (car (vl-sort lsb (function (lambda ( a b ) (< (distance pt (cadr a)) (distance pt (cadr b)))))))) 
    (vlax-invoke (car rtnpt) 'Move (cadr rtnpt) pt)
    (setq lsb (vl-remove (nth (vl-position rtnpt lsb) lsb) lsb))
  )
  (princ "limfx")
);end

image.png.44c052f76567b8418465f11bb570ff01.png

  • 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ào lúc 23/10/2023 tại 09:50, Duong Nhat Duy đã nói:

Bạn thử cái này xem sao

MAG.lsp

 

Lisp này ngày trước mình viết cho Pline nè, move theo sai số khoảng cách đến đỉnh, ngoài ra còn có chế độ khác ví dụ giao cắt, trọng tâm, điểm gần nhất, ... Mà chưa thử test nhiều với các đối tượng khá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
23 giờ trước, Duong Nhat Duy đã nói:

Lisp này ngày trước mình viết cho Pline nè, move theo sai số khoảng cách đến đỉnh, ngoài ra còn có chế độ khác ví dụ giao cắt, trọng tâm, điểm gần nhất, ... Mà chưa thử test nhiều với các đối tượng khác

em test thử lisp anh bị lỗi, dù đã chọn mục đỉnh poliline nhưng nó ko đc image.thumb.png.80bbae2ea7a1577a824f2388c767d978.png

 

  • Like 1
  • Vote giảm 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
2 giờ trước, OngNguyenVanHan đã nói:

em test thử lisp anh bị lỗi, dù đã chọn mục đỉnh poliline nhưng nó ko đc image.thumb.png.80bbae2ea7a1577a824f2388c767d978.png

 

Bạn thử tăng sai số khoảng lên xem, vẫn ko đc thì tăng lên thật to nữa xem, có thể 2 đối tượng có cao độ.

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
Đăng nhập để thực hiện theo  

×