Chuyển đến nội dung
Diễn đàn CADViet
hai_1401

Lisp căn lề tâm cho đuờng tròn

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

Em muốn nhờ các bác xem giúp em mấy cái lisp sau:

- Em có nhiều hình tròn, muốn sắp xếp chúng nằm thẳng hàng, tức là tâm của chúng sẽ thẳng hàng (với các đuờng tròn có đuờng kính khác nhau). Còn nếu đuờng kính bằng nhau, có thể là tâm thẳng hàng hoặc điểm ngoài cùng bên trái hoặc bên phải sẽ thẳng hàng.

- Sau khi sắp xếp chúng thẳng hàng xong, có thể định khoảng cách cho chúng đều nhau, như là khoảng cách từ tâm đuờng tròn này đến tâm đuờng tròn nọ là 500 chẳng hạn.

Áp dụng với cả chiều nằm ngang đối với 2 yêu cầu trên nữa ạ.

Có thể mở rộng ra đối với các Object khác không, như là mũi tên mình tự tạo bằng Polyline hoặc cái j khác ko ạ?

Có bác nào biết thì chỉ em với nhá, em chẳng biết j về Lisp cả, thanks các bác nhiều nhiều :(

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 2 ngày ko đụng đến mà cũng chẳng có bác nào chịu giúp, bó tay :(

- Thứ nhất: yêu cầu của bạn nên bổ sung thêm hình ảnh hay bản vẽ. Như vậy sẽ sẽ dễ dàng cho người muốn giúp bạn hơn.

- Thứ 2 : Ai cũng có công việc của người đấy. Có thời gian rảnh thì mới giúp được. Hơn nữa việc của bạn muốn giúp nhưng không đủ khả năng thì sao? Bạn nói: chẳng có bác nào chịu giúp, bó tay đã có suy nghĩ kỹ chưa?

Mình có lăn tăn 2 vấn đề trên. Mình sẽ giúp bạn nếu bạn giúp mình giải quyết 2 cái lăn tă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
Em muốn nhờ các bác xem giúp em mấy cái lisp sau:

- Em có nhiều hình tròn, muốn sắp xếp chúng nằm thẳng hàng, tức là tâm của chúng sẽ thẳng hàng (với các đuờng tròn có đuờng kính khác nhau). Còn nếu đuờng kính bằng nhau, có thể là tâm thẳng hàng hoặc điểm ngoài cùng bên trái hoặc bên phải sẽ thẳng hàng.

- Sau khi sắp xếp chúng thẳng hàng xong, có thể định khoảng cách cho chúng đều nhau, như là khoảng cách từ tâm đuờng tròn này đến tâm đuờng tròn nọ là 500 chẳng hạn.

Áp dụng với cả chiều nằm ngang đối với 2 yêu cầu trên nữa ạ.

Có thể mở rộng ra đối với các Object khác không, như là mũi tên mình tự tạo bằng Polyline hoặc cái j khác ko ạ?

Có bác nào biết thì chỉ em với nhá, em chẳng biết j về Lisp cả, thanks các bác nhiều nhiều :(

-Cái gạch 1 của bạn thì giải quyết được nhanh chóng.

-Cái gạch 2 và mở rộng của bạn khó đấy.

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 muốn nhờ các bác xem giúp em mấy cái lisp sau:

- Em có nhiều hình tròn, muốn sắp xếp chúng nằm thẳng hàng, tức là tâm của chúng sẽ thẳng hàng (với các đuờng tròn có đuờng kính khác nhau). Còn nếu đuờng kính bằng nhau, có thể là tâm thẳng hàng hoặc điểm ngoài cùng bên trái hoặc bên phải sẽ thẳng hàng.

- Sau khi sắp xếp chúng thẳng hàng xong, có thể định khoảng cách cho chúng đều nhau, như là khoảng cách từ tâm đuờng tròn này đến tâm đuờng tròn nọ là 500 chẳng hạn.

Áp dụng với cả chiều nằm ngang đối với 2 yêu cầu trên nữa ạ.

Có thể mở rộng ra đối với các Object khác không, như là mũi tên mình tự tạo bằng Polyline hoặc cái j khác ko ạ?

Có bác nào biết thì chỉ em với nhá, em chẳng biết j về Lisp cả, thanks các bác nhiều nhiều :(

Bạn sử dụng đoạn Code mà Tue_NV mới viết xem :

Cái này có thể canh lê text và dãn dòng Text được. Bạn thử xem :

(defun c:stron()
(setq oldos (getvar "osmode"))
(setvar "osmode" 0)
(setq ss (ssget '((0 . "CIRCLE,TEXT")))
lst (ss2ent ss)
lst (vl-sort lst
'(lambda (e1 e2)
(>
(caddr (assoc 10 (entget e1)))
(caddr (assoc 10 (entget e2)))
)
)
)
)
(setq kc (getdist "\n Nhap khoang cach giua cac Circle :"))
(setq ddau (cdr(assoc 10 (entget(car lst))))
i 0)

(foreach e lst
(setq ent (entget e))
(setq dcuoi (cdr(assoc 10 ent)))
(setq ddauu (list (car ddau) (- (cadr ddau) (* i kc)) 0))
(command "move" e "" dcuoi ddauu)  
(setq i (1+ i))
)
(setvar "osmode" oldos)
(Princ)
)

(defun ss2ent (ss / sodt index lstent)
(setq
sodt (if ss (sslength ss) 0)
index 0
)
(repeat sodt
(setq ent (ssname ss index)
index (1+ index)
lstent (cons ent lstent)
)
)
(reverse lstent)
)

  • 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
- Thứ nhất: yêu cầu của bạn nên bổ sung thêm hình ảnh hay bản vẽ. Như vậy sẽ sẽ dễ dàng cho người muốn giúp bạn hơn.

- Thứ 2 : Ai cũng có công việc của người đấy. Có thời gian rảnh thì mới giúp được. Hơn nữa việc của bạn muốn giúp nhưng không đủ khả năng thì sao? Bạn nói: chẳng có bác nào chịu giúp, bó tay đã có suy nghĩ kỹ chưa?

Mình có lăn tăn 2 vấn đề trên. Mình sẽ giúp bạn nếu bạn giúp mình giải quyết 2 cái lăn tăn đó :(

Bác làm j mà ghê thế, em chỉ nói thế thôi chứ có í j đâu :(.

Em thấy cái yêu cầu của em cũng ko quá phức tạp, với cả em đã miêu tả khá rõ rồi, chắc ai đọc cũng hiểu thôi.

Dù sao cũng thanks bác đã góp ý. Thanks luôn cả bác Tue đã viết hộ cái lisp, bác thật là pro :(.

Nhưng em muốn tách 2 phần là phần căn thẳng hàng đường tròn và phần cách đều các đường tròn ra làm 2 lệnh khác nhau có được ko ạ? Với cả em chưa thấy áp dùng được cho các đường tròn nằm ngang, chỉ căn thẳng đứng thôi à?

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ác làm j mà ghê thế, em chỉ nói thế thôi chứ có í j đâu :(

Ok. Tại mình cũng khó tính. Bỏ qua nhé.

Cái đường tròn thì mình hiểu ý bạn, nhưng cái mũi tên hoặc đối tượng khác thì nhiều kiểu lắm. Mình muốn bạn có file mẫu thì nó sẽ dễ hình dung. Đối với đường tròn thì bạn căn theo tâm, vậy với mũi tên tự tạo sẽ căn theo vị trí nào trong mũi tên, và đối tượng khác là đối tượng nào, căn vị trí nào...

Cái lisp của bác Tue là mở rộng của lisp căn hàng text nên không áp dụng tốt vào trường hợp bạn muốn đượ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ọn các đối tượng linh tinh khác cũng khó thật, thôi thế này cũng được rồi ạ, các bác bỏ quá cho, em được cái tính tham, được voi đòi hai bà trưng í 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
Bạn sử dụng đoạn Code mà Tue_NV mới viết xem :

Cái này có thể canh lê text và dãn dòng Text được. Bạn thử xem :

(setq ss (ssget '((0 . "CIRCLE,TEXT")))

Tue_NV để ý nhé nếu trường hợp người dùng bao vùng chọn có cả CIRCLE và TEXT thì cả 2 loại đối tượng này đều được chọn lẩn lộn với nhau và ........... tèn tén ten!

  • 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
Tue_NV để ý nhé nếu trường hợp người dùng bao vùng chọn có cả CIRCLE và TEXT thì cả 2 loại đối tượng này đều được chọn lẩn lộn với nhau và ........... tèn tén ten!

Thế thì cũng không được nhỉ, có cách nào tách riêng 2 cái ấy ra ko ạ?

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ác làm j mà ghê thế, em chỉ nói thế thôi chứ có í j đâu :(.

Em thấy cái yêu cầu của em cũng ko quá phức tạp, với cả em đã miêu tả khá rõ rồi, chắc ai đọc cũng hiểu thôi.

Dù sao cũng thanks bác đã góp ý. Thanks luôn cả bác Tue đã viết hộ cái lisp, bác thật là pro :(.

Nhưng em muốn tách 2 phần là phần căn thẳng hàng đường tròn và phần cách đều các đường tròn ra làm 2 lệnh khác nhau có được ko ạ? Với cả em chưa thấy áp dùng được cho các đường tròn nằm ngang, chỉ căn thẳng đứng thôi à?

Đoạn Code trên là căn thẳng hàng đường tròn và phần cách đều các đường tròn theo trục y

Còn đoạn COde này chỉ căn thẳng hàng đường tròn không có phần cách đều : (theo trục Y )

(defun c:stron()
(setq oldos (getvar "osmode"))
(setvar "osmode" 0)
(setq ss (ssget '((0 . "CIRCLE")))
lst (ss2ent ss)
lst (vl-sort lst
'(lambda (e1 e2)
(>
(caddr (assoc 10 (entget e1)))
(caddr (assoc 10 (entget e2)))
)
)
)
)

(setq ddau (cdr(assoc 10 (entget(car lst))))
i 0)

(foreach e lst
(setq ent (entget e))
(setq dcuoi (cdr(assoc 10 ent)))
(setq ddauu (list (car ddau) (cadr dcuoi) 0))
(command "move" e "" dcuoi ddauu) 
(setq i (1+ i))
)
(setvar "osmode" oldos)
(Princ)
)

(defun ss2ent (ss / sodt index lstent)
(setq
sodt (if ss (sslength ss) 0)
index 0
)
(repeat sodt
(setq ent (ssname ss index)
index (1+ index)
lstent (cons ent lstent)
)
)
(reverse lstent)
)

 

Đoạn Code này là căn thẳng hàng đường tròn và phần cách đều các đường tròn theo trục X

(defun c:stron()
(setq oldos (getvar "osmode"))
(setvar "osmode" 0)
(setq ss (ssget '((0 . "CIRCLE")))
lst (ss2ent ss)
lst (vl-sort lst
'(lambda (e1 e2)
((cadr (assoc 10 (entget e1)))
(cadr (assoc 10 (entget e2)))
)
)
)
)
(setq kc (getdist "\n Nhap khoang cach giua cac Circle :"))
(setq ddau (cdr(assoc 10 (entget(car lst))))
i 0)

(foreach e lst
(setq ent (entget e))
(setq dcuoi (cdr(assoc 10 ent)))
(setq ddauu (list (+ (car ddau) (* i kc)) (cadr ddau) 0))
(command "move" e "" dcuoi ddauu) 
(setq i (1+ i))
)
(setvar "osmode" oldos)
(Princ)
)

(defun ss2ent (ss / sodt index lstent)
(setq
sodt (if ss (sslength ss) 0)
index 0
)
(repeat sodt
(setq ent (ssname ss index)
index (1+ index)
lstent (cons ent lstent)
)
)
(reverse lstent)
)

 

Còn đoạn COde này chỉ căn thẳng hàng đường tròn không có phần cách đều : (theo trục X)

(defun c:stron()
(setq oldos (getvar "osmode"))
(setvar "osmode" 0)
(setq ss (ssget '((0 . "CIRCLE")))
lst (ss2ent ss)
lst (vl-sort lst
'(lambda (e1 e2)
((cadr (assoc 10 (entget e1)))
(cadr (assoc 10 (entget e2)))
)
)
)
)

(setq ddau (cdr(assoc 10 (entget(car lst))))
i 0)

(foreach e lst
(setq ent (entget e))
(setq dcuoi (cdr(assoc 10 ent)))
(setq ddauu (list (car dcuoi) (cadr ddau) 0))
(command "move" e "" dcuoi ddauu) 
(setq i (1+ i))
)
(setvar "osmode" oldos)
(Princ)
)

(defun ss2ent (ss / sodt index lstent)
(setq
sodt (if ss (sslength ss) 0)
index 0
)
(repeat sodt
(setq ent (ssname ss index)
index (1+ index)
lstent (cons ent lstent)
)
)
(reverse lstent)
)

To Hai_1401 : Nếu trong dòng (setq ss (ssget '((0 . "CIRCLE"))) mà bạn sử thành (setq ss (ssget '((0 . "TEXT"))) thì Lisp trở thành canh lề trái và dãn đoạn cho TEXT.

TB: Bạn nên suy nghĩ trước khi nói. Bạn Nataca nói hoàn toàn đúng : "Ai cũng có công việc của người đấy. Có thời gian rảnh thì mới giúp được. Hơn nữa việc của bạn muốn giúp nhưng không đủ khả năng thì sao? Bạn nói: chẳng có bác nào chịu giúp, bó tay đã có suy nghĩ kỹ chưa?". Nataca và Tue_NV nói là góp ý cho bạn đấy. Chúc bạn vui

 

Tue_NV để ý nhé nếu trường hợp người dùng bao vùng chọn có cả CIRCLE và TEXT thì cả 2 loại đối tượng này đều được chọn lẩn lộn với nhau và ........... tèn tén ten!

Cái này thì em biết anh Duy à. Vì Tue_NV sử dụng Code là có chủ đích, chỉ chọn riêng TEXT hoặc riêng CIRCLE để canh lề và dãn dòng thôi. Còn néu như chỉ chọn riêng thì điều này không khó, chỉ cần thay dòng này :

(setq ss (ssget '((0 . "CIRCLE,TEXT")))

bằng dòng : (setq ss (ssget '((0 . "CIRCLE"))) : Nếu chỉ chọn Circle

bằng dòng : (setq ss (ssget '((0 . "TEXT"))) : Nếu chỉ chọn TEXT

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
Đoạn Code trên là căn thẳng hàng đường tròn và phần cách đều các đường tròn theo trục y

Còn đoạn COde này chỉ căn thẳng hàng đường tròn không có phần cách đều : (theo trục Y )

(defun c:stron()
(setq oldos (getvar "osmode"))
(setvar "osmode" 0)
(setq ss (ssget '((0 . "CIRCLE")))
lst (ss2ent ss)
lst (vl-sort lst
'(lambda (e1 e2)
(>
(caddr (assoc 10 (entget e1)))
(caddr (assoc 10 (entget e2)))
)
)
)
)

(setq ddau (cdr(assoc 10 (entget(car lst))))
i 0)

(foreach e lst
(setq ent (entget e))
(setq dcuoi (cdr(assoc 10 ent)))
(setq ddauu (list (car ddau) (cadr dcuoi) 0))
(command "move" e "" dcuoi ddauu) 
(setq i (1+ i))
)
(setvar "osmode" oldos)
(Princ)
)

(defun ss2ent (ss / sodt index lstent)
(setq
sodt (if ss (sslength ss) 0)
index 0
)
(repeat sodt
(setq ent (ssname ss index)
index (1+ index)
lstent (cons ent lstent)
)
)
(reverse lstent)
)

 

Đoạn Code này là căn thẳng hàng đường tròn và phần cách đều các đường tròn theo trục X

(defun c:stron()
(setq oldos (getvar "osmode"))
(setvar "osmode" 0)
(setq ss (ssget '((0 . "CIRCLE")))
lst (ss2ent ss)
lst (vl-sort lst
'(lambda (e1 e2)
((cadr (assoc 10 (entget e1)))
(cadr (assoc 10 (entget e2)))
)
)
)
)
(setq kc (getdist "\n Nhap khoang cach giua cac Circle :"))
(setq ddau (cdr(assoc 10 (entget(car lst))))
i 0)

(foreach e lst
(setq ent (entget e))
(setq dcuoi (cdr(assoc 10 ent)))
(setq ddauu (list (+ (car ddau) (* i kc)) (cadr ddau) 0))
(command "move" e "" dcuoi ddauu) 
(setq i (1+ i))
)
(setvar "osmode" oldos)
(Princ)
)

(defun ss2ent (ss / sodt index lstent)
(setq
sodt (if ss (sslength ss) 0)
index 0
)
(repeat sodt
(setq ent (ssname ss index)
index (1+ index)
lstent (cons ent lstent)
)
)
(reverse lstent)
)

 

Còn đoạn COde này chỉ căn thẳng hàng đường tròn không có phần cách đều : (theo trục X)

(defun c:stron()
(setq oldos (getvar "osmode"))
(setvar "osmode" 0)
(setq ss (ssget '((0 . "CIRCLE")))
lst (ss2ent ss)
lst (vl-sort lst
'(lambda (e1 e2)
((cadr (assoc 10 (entget e1)))
(cadr (assoc 10 (entget e2)))
)
)
)
)

(setq ddau (cdr(assoc 10 (entget(car lst))))
i 0)

(foreach e lst
(setq ent (entget e))
(setq dcuoi (cdr(assoc 10 ent)))
(setq ddauu (list (car dcuoi) (cadr ddau) 0))
(command "move" e "" dcuoi ddauu) 
(setq i (1+ i))
)
(setvar "osmode" oldos)
(Princ)
)

(defun ss2ent (ss / sodt index lstent)
(setq
sodt (if ss (sslength ss) 0)
index 0
)
(repeat sodt
(setq ent (ssname ss index)
index (1+ index)
lstent (cons ent lstent)
)
)
(reverse lstent)
)

To Hai_1401 : Nếu trong dòng (setq ss (ssget '((0 . "CIRCLE"))) mà bạn sử thành (setq ss (ssget '((0 . "TEXT"))) thì Lisp trở thành canh lề trái và dãn đoạn cho TEXT.

TB: Bạn nên suy nghĩ trước khi nói. Bạn Nataca nói hoàn toàn đúng : "Ai cũng có công việc của người đấy. Có thời gian rảnh thì mới giúp được. Hơn nữa việc của bạn muốn giúp nhưng không đủ khả năng thì sao? Bạn nói: chẳng có bác nào chịu giúp, bó tay đã có suy nghĩ kỹ chưa?". Nataca và Tue_NV nói là góp ý cho bạn đấy. Chúc bạn vui

Cái này thì em biết anh Duy à. Vì Tue_NV sử dụng Code là có chủ đích, chỉ chọn riêng TEXT hoặc riêng CIRCLE để canh lề và dãn dòng thôi. Còn néu như chỉ chọn riêng thì điều này không khó, chỉ cần thay dòng này :

(setq ss (ssget '((0 . "CIRCLE,TEXT")))

bằng dòng : (setq ss (ssget '((0 . "CIRCLE"))) : Nếu chỉ chọn Circle

bằng dòng : (setq ss (ssget '((0 . "TEXT"))) : Nếu chỉ chọn TEXT

Chào bác Tue_NV,

Bác có thể giải thích giùm mình dòng code này được không?

sodt (if ss (sslength ss) 0)

Mục đích của dòng code này là gì và tại sao cú pháp lại kỳ kỳ như vậy? Bác có thể viết lại đoạn code đó cho dễ hiểu hơn không ạ???

Thú thực là mình chưa hiểu rõ lắm nên chưa dám xài bác ạ.

Cám ơn bác trước và chúc bác vui.

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ác Tue_NV,

Bác có thể giải thích giùm mình dòng code này được không?

sodt (if ss (sslength ss) 0)

Mục đích của dòng code này là gì và tại sao cú pháp lại kỳ kỳ như vậy? Bác có thể viết lại đoạn code đó cho dễ hiểu hơn không ạ???

Thú thực là mình chưa hiểu rõ lắm nên chưa dám xài bác ạ.

Cám ơn bác trước và chúc bác vui.

(defun ss2ent (ss / sodt index lstent)
(setq
sodt (if ss (sslength ss) 0)
index 0
)
(repeat sodt
(setq ent (ssname ss index)
index (1+ index)
lstent (cons ent lstent)
)
)
(reverse lstent)
)

Em xin mạn phép trả lời trước :(

(setq sodt (if ss (sslength ss) 0)) là để tránh trường hợp nếu ss = nil sẽ gây ra lỗi .

(if ss

___(sslength ss) -> trả về trường hợp này nếu ss khác nil (tức là tồn tại ss)

___0 -> nếu ss = nil hoặc là 1 tập hợp rỗng

)

Thực ra có cách giải quyết hàm ss2ent nhanh hơn là: (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss)))

Tuy nhiên cách này sử dụng thư viện hàm vl nên sẽ ko dùng được cho cad14

  • 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ác Tue_NV,

Bác có thể giải thích giùm mình dòng code này được không?

sodt (if ss (sslength ss) 0)

Mục đích của dòng code này là gì và tại sao cú pháp lại kỳ kỳ như vậy? Bác có thể viết lại đoạn code đó cho dễ hiểu hơn không ạ???

Thú thực là mình chưa hiểu rõ lắm nên chưa dám xài bác ạ.

Cám ơn bác trước và chúc bác vui.

.

 

Đúng như bạn Nataca nói.

(Setq sodt (if ss (sslength ss) 0)) là để tránh trường hợp nếu ss = nil sẽ gây ra lỗi

(if ss (sslength ss) 0)

Ở đây điều kiện kiểm tra của hàm if là : ss . Tức là nếu (/= ss nil) thì gán giá trị (sslength ss) cho biến sodt

(ELSE) : nếu (= ss nil) (hoặc ss = rỗng) thì gán giá trị 0 cho biến sodt.

Nếu viết lại cho dễ hiểu thì viết lại như thế này :

(Setq sodt (if (/= ss nil) (sslength ss) 0))

  • 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

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

×