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

ngokiet

Thành viên
  • Số lượng nội dung

    403
  • Đã tham gia

  • Lần ghé thăm cuối

  • Ngày trúng

    43

Bài đăng được đăng bởi ngokiet


  1. 3 giờ trước, Doan Nguyen Van đã nói:

    Cái này gặp lỗi với các list dạng số 

    Lisp dạng số là sao? So sánh string mà.

    Mà cách trên viết suy nghĩ theo hướng của leemac với đệ quy nên hơi rối 

    Dùng cách mới này thử xem. Ai test thử xem có trường hợp nào không đúng không?

     

    (defun ssnt(s1 s2 / t1 t2)
      (while (and (/= s1 "") (/= s2 "") (eq (ascii s1) (ascii s2)))
        (setq s1 (substr s1 2) s2 (substr s2 2)))
      (setq t1 (atoi (strcat "1" s1))
    	t2 (atoi (strcat "1" s2)))
      (If (eq t1 t2) (< (ascii s1) (ascii s2)) (< t1 t2)))

    Test 

    (vl-sort '("T1A" "AS2" "AS10" "T10B" "T1" "AS1" "T2" "T10" "T2A" "T2AC" "T2AB" "T10A" "T2A1" "T1B" "T2B") 'ssnt)
    (vl-sort '("1" "10" "10C" "10A" "10B" "A" "2" "20" "25" "3" "4") 'ssnt)       

    • Like 1

  2. Vào lúc 17/7/2023 tại 09:54, Duong Nhat Duy đã nói:

    Cảm ơn bác nhưng ý mình là viết tổng quát để gọi nó ra trong function của hàm vl-sort á bác, list trên là 1 ví dụ thôi, giả sử 1 list khác là các text entity list, mình muốn sort theo giá trị string thì lại phải sửa hàm con chỗ (mapcar 'LM:splitstring (mapcar '(lambda (x) (car x)) lst)) thành ... (cdr (assoc 1 (entget x))), nó hơi bất tiện ấy bác. Mình muốn nó hoạt động như thế này (mình ko biết có thể viết đc kiểu đó ko vì mình quá gà :((( ):

    
    (vl-sort lst '(lambda (a b) (< (convert (cdr (assoc 1 (entget a)))) (convert (cdr (assoc 1 (entget b)))))))

    lst là list các Text entity

    (convert) là hàm chế từ hàm sắp xếp của leemac

    Code trên chỉ là ý tưởng của mình do mình chưa biết kết quả cuối cùng sẽ phải ra sao, mong các bạn thông cảm và giúp đỡ.

    Mình có viết thử cho vui

    Test   (vl-sort '("1" "10" "10C" "10A" "10B" "2" "20" "25" "3" "4") 'ssnt)

    hay (vl-sort lst '(lambda(a b) (ssnt (cdr(assoc 1 a)) (cdr(assoc 1 b))))

     

     

    (defun ssnt(s1 s2 / t1 t2)
      (if (/= s1 "")
        (if (/= s2 "")
          (if (< 47 (ascii s1) 58)      
    	(if (< 47 (ascii s2) 58)
    	  (if (eq (setq t1 (atoi s1)) (setq t2 (atoi s2)))
    	    (ssnt (vl-string-left-trim "0123456789" s1) (vl-string-left-trim "0123456789" s2))
    	    (< t1 t2)))
    	(if (eq (ascii s1) (ascii s2))
    	  (ssnt (substr s1 2) (substr s2 2))
    	  (or (< 47 (ascii s2) 58) (< (ascii s1) (ascii s2))))))))

     

    • Like 1

  3. 57 phút trước, 7o7 đã nói:

    Lisp của bác ngokiet ra kết quả gọn hơn nhưng thiếu điểm p, không biết nhóm q nào thuộc p nào.

    (((336.772 -7.8267 0.0) (338.109 20.063 0.0) (364.877 15.7599 0.0) (356.379 -0.0402154 0.0)) ; 4 điểm 
    ((310.629 60.9931 0.0) (299.425 35.0906 0.0) (321.144 41.0719 0.0)) ; 3 điểm
    ((216.235 53.6172 0.0) (209.065 32.4893 0.0) (221.222 14.2109 0.0) (246.062 51.0546 0.0) (243.672 24.8284 0.0))) ; 5 điểm

    12  điểm trên đều là điểm q mà không có p

    Hi hi. Mình chi viết theo suy nghĩ thôi chứ không chạy test. Ý tưởng là điểm nào tính xong thì remove đi để khỏi tính lại thôi.

    Còn kết quả thì ra các nhóm điểm Q theo thứ tự nhóm P. Chứ không thêm P vào nhóm.

    Giống như bác Hà viết thôi.

    Cách này tuy giảm tính toán so với bác Hà nhưng cũng hơi nhiều so với cách viết mỗi diêm Q tìm P gần nhất sau đó xắp xếp lại. Nhưng viết dài dòng hơn.

    • Like 1

  4. Vào lúc 16/6/2023 tại 11:12, Doan Van Ha đã nói:

    Đúng vậy. Hôm qua viết được rồi nhưng dài (nên dở), nay viết lại như vậy chắc ngắn hơn. Cám ơn mọi người đã quan tâm.

    
    (defun Group(dsp dsq / x y z)
     (foreach p (reverse dsp) 
      (setq y nil)
      (foreach q dsq 
       (setq x (car (vl-sort (mapcar '(lambda(p) (list p q (distance q p))) dsp) '(lambda(ds1 ds2) (< (caddr ds1) (caddr ds2))))))
       (if (equal (car x) p 1e-5) (setq y (cons x y))))
       (setq z (cons y z))))
    

     

    (defun group(dsp dsq / len)
      (mapcar '(lambda(p / y)
             (setq dsp (cdr dsp)
               dsq (vl-remove-if '(lambda(q)
                        (setq len (distance p q))
                        (if (vl-every '(lambda(x) (>= (distance x q) len)) dsp)
                          (setq y (cons q y))))
                 dsq))
             y)
          dsp))

     

    Viết lại theo kiểu của bác để bớt chút xíu số lượng tinh toán.

    • Like 1
    • Vote tăng 1

  5. 48 phút trước, nguyennguyen12121212 đã nói:

    Em chào cả nhà!

    Hiện nay trên mạng đang có lisp convertfont sử dụng tốt cho Autocad 2021 trở về trước. Tuy nhiên các đời cao từ CAD 2021 trở lên thì không sử dụng được. Vì vậy cho em xin lisp sử dụng cho cad 2021 được không ạ?

    Bạn đánh lispsys đặt bằng 0 thì lisp cũ chạy bình thường nhé.


  6. 20 giờ trước, TRUNGNGAMY đã nói:

    Cám ơn bạn. Bạn viết rất ngắn gọn, độc đáo mà chính xác. Mình cũng nghĩ phải viết theo kiểu đệ qui nhưng không viết được

    Cách viết này đơn giản là tính từng phần tử 1. Chứ không tính 1 lần được. Có cách khác là đổi lisp mẫu thành hàm và dùng eval nếu dữ liệu lớn.

     

    Sửa lại lỗi nth tính từ 0

     

    (Defun test(mau mt / dq)
      (Defun dq(m)
        (mapcar '(lambda(x) (if (numberp x) (nth (1- x) n) (dq x))) m))
      (mapcar '(lambda(n) (dq mau)) mt))
    
    (Defun test1(mau mt / dq)
      (Defun dq(m)
        (cons 'list 
    	  (mapcar '(lambda(x) (if (numberp x) (list 'nth (1- x) 'x) (dq x))) m)))
      (setq mau (dq mau))
      (mapcar '(lambda(x) (eval mau)) mt))

     

     

    • Like 2

  7. Lisp của bac không sai. 

    Cad cũng không có lỗi. Nó tính đúng.

    Vấn đề ở đường spline kia. nó có 2 đỉnh số 6 và 7 trùng nhau. điểm số 8 nó lệch xuống 1 chút.

    Nếu bác đo góc 2 điểm số 7 và 8 thì nó gần vuông góc với kêt quả lisp chạy ra được. Chỉ là không quan sát được nên bác nghĩ lisp lỗi thôi.

    • Like 1

  8. 22 giờ trước, nh0cxip0 đã nói:

    Chào các bác mình muốn thống kê chiều dài các đoạn pline vào bảng.

    Nên nhờ nhờ mọi người viết giúp lisp copy dim đó vào đối tượng dtext

    Chọn dim -> space -> chọn text muốn dán -> space (dán và kết thúc)
    Hoặc có cách nào nhanh hơn thì mong mọi người giúp mình.

    KHUNG LUOI NHOM.dwg

     

    Sái thử. Viết sơ vừa đủ chạy cho vui thôi . Không chắc dim khác chạy tốt nhe

     

    Nếu bạn làm nhiều và thường xuyên thì nên bỏ ra ít tiền cho ai đó viết cho 1 lisp. Chỉ càn vẽ xong chọn tất cả là nó tự dim và lạp bảng cho bạn luôn.

    (defun c:ct(/ en1 en2 st)
      (if (and (setq en1 (car (entsel "/nChon dim:")))
    	   (eq (cdr (assoc 0 (setq en1 (entget en1)))) "DIMENSION")
    	   (setq en2 (car (entsel "/nChon text:")))
    	   (wcmatch (cdr (assoc 0 (entget en2))) "TEXT,MTEXT"))
        (entmod (list (cons -1 en2)
    		  (cons 1 (rtos (cdr (assoc 42 en1)) 2 1)))))
      (princ))

     

    • Like 1

  9. 10 giờ trước, trungkien8338 đã nói:

    (defun c:hh()
        (setq obj (vlax-ename->vla-object(car (entsel)))) ; đối tượng được chọn là một block có nhiều attribute
         ;lay attribute
        (setq sal (vlax-safearray->list (vlax-variant-value (vla-getattributes obj))))
        (setq i 0)
        (repeat (length sal)
            (princ (vlax-get-property (nth i sal) 'TextString )) ; chỗ này lấy ra phần tiếng việt bị lỗi font
            (princ "\n")
            (setq i (+ 1 i))
        )
        
    )

    NHỜ CÁC BÁC XEM GIÚP.

    Như lisp bạn viết thì đổi dòng 

     (princ (vlax-get-property (nth i sal) 'TextString ))

    Thành (princ (cdr(assoc 1 (entget(vlax-vla-object->ename (nth i sal))))))

     

     

    Còn mỉnh thì viết như vậy

    (defun c:hh(/ en eg)
      (setq en (car(entsel)))
      (while (eq (cdr (assoc 0 (setq en (entnext en)
    				 eg (entget en))))
    	     "ATTRIB")
        (princ (strcat (cdr (assoc 1 eg)) "\n")))
      (princ))

     

    • Vote tăng 1

  10. 22 giờ trước, trungkien8338 đã nói:

    đúng rồi bạn, mình đọc giá trị của attribute bằng autolisp. vậy là không có lisp nào khắc phục được lỗi này sao bạn.

    Autolisp giờ bao gồm thêm visual lisp là các lệnh bắt đầu là vla/vlax. muốn ko lỗi thì thay vì dùng vla-object thì dùng ename để đọc thì không lỗi.

    Bác muốn hỏi kỹ thì phải đưa lisp bác lên mới chỉ chỗ sửa dc.


  11. Vào lúc 28/10/2016 tại 12:25, vandv đã nói:

    Khi copy block từ bản vẽ này [1] sang bản vẽ khác [2] đã có sẵn block trùng tên thì block trong bản vẽ 2 vẫn giũ nguyên. Làm thế nào thay thế block của bản vẽ [2] bằng block của bản vẽ [1] mà không phải đổi tên block không. Mình update bản vẽ copy nhiêu block qua bản vẽ khác cùng lúc nên đổi tên từng block khá mất thời gian. Giúp mình với

    Làm ngược lại. Lấy bản vẽ 1 xóa sạch rồi chen bàn vẽ 2 vào. Nếu sửa nhiều block.

    Còn không thì wblock đó ra rồi các bàn vẽ khác kéo thả block đó vào.

     

    Còn có 1 cách nữa là nhấn Ctrl+2. mở tới bản vẽ 1 - blocks . Nhán nút phải trên block đã sửa chọn redefine only

     

    image.png

    • Like 2

  12. 21 phút trước, Huyminer đã nói:

    tập hợp các điểm của mình không đơn thuần là nó chạy theo trục XY

    Các tập điểm có thể chạy xiên như này chứ không thẳng hàng nên phép chiếu và so sánh các điểm với trục x và y mình đã thử rồi và không thành công

     

    Ít nhất bạn phải có file cho người ta test chứ.

    Trong các điểm bạn đưa thì gần như không có quy luật nào chính xác. Bạn phải tìm 1 quy luật tương đối gần đúng với nó nhất để sort.

    Bạn dề xuất sort theo x+y thì không đúng rồi. Theo mình thấy là nên xoay trục tọa đô rồi sort

     

×