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

Doan Van Ha

Moderator
  • Số lượng nội dung

    6.220
  • Đã tham gia

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

  • Ngày trúng

    446

Bài đăng được đăng bởi Doan Van Ha


  1. Như thế này phải không?

    (defun c:vb ( / MakeRectang LST)
    (defun MakeRectang (PT1 PT2 Linetype LTScale Layer Color xdata)
    (entmakex (list '(0 . "LWPOLYLINE")
     '(100 . "AcDbEntity")
     (cons 8 (if Layer Layer (getvar "Clayer")))
     (cons 6 (if Linetype Linetype "bylayer"))
     (cons 48 (if LTScale LTScale 1))
     (cons 62 (if Color Color 256))
     '(100 . "AcDbPolyline")
     (cons 90 4)
     (cons 70 1)
     (cons 10 PT1)
     (cons 10 (list (car PT1) (cadr PT2)))
     (cons 10 PT2)
     (cons 10 (list (car PT2) (cadr PT1))))))
    (prompt "Chon cac doi tuong can ve duong bao")
    (setq LST (ACET-GEOM-SS-EXTENTS-FAST (ssget)))
    (MakeRectang (car LST) (cadr LST) nil nil nil nil nil)
    (princ))

    Chú ý: cái này vẽ đuờng bao cho mọi đối tuợng bất kỳ

    Ồ không, như thế này cơ! (http://www.cadviet.com/upfiles/3/ve_duong_bao.dwg)


  2. Tôi đang gặp 1 bài toán xuất phát từ công việc: có n đường kín (kiểu LWPOLYLINE, CIRCLE, ELLIPSE) nằm bất kỳ. Làm sao để vẽ được đường bao ngoài cho tất cả các đường này (nếu tồn tại)?

    Hoặc vẽ được đường bao cho từng nhóm m đường (với m < n) khi m đường này có chung đường bao ngoài? Nhờ các cao thủ giúp. Xin cám ơn!


  3. Đây là hệ quả của việc sử dụng lệnh COMMAND trong lập trình !

    Vì COMMAND của Cad chỉ trả về kết quả (mà không cho biết chính xác anh nào tham gia vào việc nối, anh nào bị tam thời xóa).

     

    Nếu bạn xử lí các đối tượng tuần tự thì bạn sẽ biết được chính xác "Các đối tượng tham gia vào việc nối (có database thay đổi)".

    Khi đó chả cần phải "tìm các phần tử khác không bị đánh dấu xóa (tồn tại trên bản vẽ)".

    Chiêu này đâu có gì lạ! :undecided:

    Nếu cứ nối tuần tự như Bạn và biết được các đối tượng tham gia vào việc nối thì vấn đề đã đơn giản. Đằng này có hằng hà sa số đối tượng trên bản vẽ, và cũng chẳng biết thằng nào và con nào... hun nhau mới khó. Tụi nó nếu gặp nhau là hun nhau, không gặp thì làm ngơ. Vấn đề là trong vô số đứa nhóc đó, nếu có cặp (ba, bốn...) nào yêu nhau sớm thì ta phải tìm ra được chúng để đưa đi... giáo dưỡng. Hề hề hề. Chuyện vui vậy đó. Dù sao cũng rất cám ơn Bạn.


  4. Ủa ủa? Không biết có hiểu nhầm ý mấy bác không nữa. Nhưng trừ/cộng 2 tập sao không dùng ssdel, ssadd??

    Còn nếu muốn kiểm tra 1 ename có tồn tại trên bản vẽ hay không ta dùng (enget ename)

    Kiểm tra 1 ename có tồn tại trong ss hay không ta dùng (ssmemb ename ss)

     

    Này nhé: ssme- sscon

    (setq i 0)
    (while (setq e (ssname sscon i))
       (setq ssme (ssdel e ssme))
       (setq i (1+ i))
    )

     

    ssme+sscon

    (setq i 0)
    (while (setq e (ssname sscon i))
       (setq ssme (ssadd e ssme))
       (setq i (1+ i))
    )

     

    Không biết có đúng ý của mấy bác đang bàn hay không? sorry. Chúc cuối tuần vui vẻ

    Một ý tưởng hay, dùng các hàm "cổ điển" vẫn đủ. Các bác kia dùng các hàm "hiện đại" cũng tốt luôn. Chỉ 1 vấn đề mà có rất nhiều cách viết hay. Thanks


  5. Hề hề hề,

    Tranh thủ lúc bác Tue_Nv còn bận, mình làm cái ni theo sự gợi ý của bác ấy, bạn coi thử nhé:

    (defun c:chkss ( )
    (vl-load-com)
    (if (= ss nil)
      (setq ss (ssget))
    ) 
    (setq n (sslength ss)
           i 0
           sslst (acet-ss-to-list ss)
    (while (< i n)
         (setq obj (vlax-ename->vla-object (ssname ss i)))
         (if (vlax-erased-p obj)
            (setq sslst (vl-remove (ssname ss i) sslst))
         )
         (setq i (1+ i))
    )
    (setq ss (acet-list-to-ss sslst))
    ss
    )
    

     

    @ketxu:

    Hề hề hề, bác chuẩn bị vòng hoa cho mình nhé, mũi sắp nổ rồi . hề hề hề

    Xin tỏ lòng ngưỡng mộ các siêu sao trên CADVIET, vừa giỏi, vừa nhanh, vừa tận tình. Trả lời ý của bạn GIA_BACH: lúc đầu có n đường (bất kỳ về kiểu đối tượng) được chọn, sau đó tôi nối một số đường lại với nhau, tạo thành m đường (m<=n). Các đường tham gia vào việc nối bị mất đi. Việc bây giờ là tìm cách xử lý trên m đường này, thay vì n đường ban đầu. Nếu bạn có cách gì hay hơn nữa thì tung chiêu chứ để trong bụng dạ nhiều nó... đau bụng. Thanks.


  6. Duyệt qua từng ename của ss -> Kiểm tra đối tượng đã bị xoá chưa bằng hàm vlax-erased-p

    Nếu hàm vlax-erased-p trả về T => chứng tỏ đối tượng này đã bị xoá (ename vẫn tồn tại) -> Remove ename ra khỏi tập ss

    Làm như thế cho đến ename cuối cùng trong ss

    Sẵn nhờ TUE_NV viết luôn đoạn code đó luôn vì mình... hơi ngu mấy cái hàm VLAX, ACET... Thanks!


  7. Chào bạn Doan Van Ha,

    Bạn xài thử cái này coi sao. Lưu ý là không nhất thiết tập ss1 của bạn phải là tập con của SS2 nhé. Có điều khi đó chỉ có những phần tử nào có cả trong hai tập chọn mới bị loại khỏi tập ss3.

    Trong lisp mình để ngược với bạn, tập ss1 là tập bị trừ (mẹ) và tập ss2 là tập trừ (con) bạn nhé.

    (defun c:subss (/ ss1 ss2 lst1 lst2)
    (if (= ss1 nil)
       (progn
              (alert "\n Chon tap doi tuong me")
              (setq ss1 (ssget )
                      lst1 (acet-ss-to-list ss1))
       )
    )
    (if (= ss2 nil)
      (progn
             (alert "\n Chon tap doi tuong con")
             (setq ss2 (ssget)
                     lst2 (acet-ss-to-list ss2))
       )
    )
    (foreach x lst2
          (if (member x lst1)
              (setq lst1 (vl-remove x lst1))
          )
    )
    (setq ss3 (acet-list-to-ss lst1))
    ss3
    )
    

     

    Trong trường hợp bạn đã có tập ss1 và ss2 rồi thì sẽ không phải chọn đối tượng nữa và lisp sẽ trả cho bạn tập ss3 như bạn cần.

    Chúc bạn vui.

     

    @ All: Tiện tay vời yêu cầu của bạn Doan Van Ha, mình làm luôn cái lisp cho phép gộp hai tập chọn thành một tập chọn mới để may ra có bạn nào cần dùng.

    Hề hề hề.

     

    (defun c:addss ( / ss1 ss2  lst1 lst2)
    (if (= ss1 nil)
       (progn
              (alert "\n Chon tap doi tuong me")
              (setq ss1 (ssget )
                      lst1 (acet-ss-to-list ss1))
       )
    )
    (if (= ss2 nil)
      (progn
             (alert "\n Chon tap doi tuong con")
             (setq ss2 (ssget)
                     lst2 (acet-ss-to-list ss2))
       )
    )
    (foreach x lst2
          (if (not (member x lst1))
              (setq lst1 (cons x lst1))
          )
    )
    (setq ss3 (acet-list-to-ss lst1))
    ss3
    
    )
    
    

    .

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

    Cám ơn sự nhiệt tình của cả 3 bạn. Tiện thể cho hỏi thêm: Làm sao để loại ra khỏi tập SS tất cả các đối tượng đã bị đánh dấu xóa mà ta chưa biết chúng là những thằng nào?


  8. Không hiểu ý của bạn?

    Thế nào là tất cả đã bị đánh dấu xóa (đã bị xóa khỏi bản vẽ nhưng tên tuổi vẫn còn)

    Bạn vui lòng nói rõ hơn nhé?

    Như thế này: một đối tượng khi được chọn sẽ có 1 cái tên. Sau khi chọn xong, ta xóa đối tượng đó đi nhưng tên tuổi nó vẫn còn trong cơ sở dữ liệu, gọi là phần tử đã bị đánh dấu xóa. Còn phần tử được chọn mà vẫn còn tồn tại trên bản vẽ gọi là phần tử không bị đánh dấu xóa.


  9. Tôi có 2 tập hợp chọn ss1 và ss2, trong đó:

    - Tập hợp chọn ss1 gồm n phần tử, tất cả đã bị đánh dấu xóa (đã bị xóa khỏi bản vẽ nhưng tên tuổi vẫn còn).

    - Tập hợp chọn ss2 gồm m phần tử (m>n), trong đó chứa n phần tử của ss1 và (m-n) phần tử khác không bị đánh dấu xóa (tồn tại trên bản vẽ).

    - Làm sao để tạo được tập hợp chọn ss3 chỉ chứa (m-n) phần tử không bị đánh dấu xóa. Ai biết xin chỉ giùm, rất cám ơn.


  10. Chào bạn.

    Bản chất của nó có lẽ bản vẽ được tạo ra bởi AUtocad phiên bản học tập. Có thể 1 sysvar hay objects của bản vẽ đã được autodesk cài mã nhận dạng.

    Bạn cho mình xin cái bản vẽ đó để vọc thử nhé.

    Thanks.

    Nói chung là cám ơn tất cả các bạn đã chia sẻ những hiểu biết của mình. Đây là file bị lỗi khi in.

    http://www.cadviet.com/upfiles/3/error_loi_in.dwg


  11. Chào bạn.Bài của bạn mình không thấy có chủ ngữ nào,nên k biết gọi bằng chi,thôi thì gọi bạn cho nó đẹp :undecided:

    Nếu muốn tìm hiểu nguyên nhân vấn đề trên thì bạn tìm chính xác dòng này trong mục tìm kiếm của diễn đàn nhé :wub: Hoặc là tìm bằng GG,Sẽ ra khôi khối kết quả đó :)

    PRODUCED+BY+AN+AUTODESK+EDUCATIONAL PRODUCT

     

    Tựu chung lại là mình tóm tắt như thế này : với file đã bị đóng dấu kiểu này,bạn mở file đó ra,lúc nó hỏi thì cứ ấn yes.Khi đã mở được bản vẽ ra rồi, thì bạn nhấn Ctrl + Shift + S (save As) và lưu lại file này dưới dạng CAD đời thấp hơn (ví dụ từ 07 -> 04), hoặc thông thường là lưu ở dạng file DXF tương đương (2007 dxf).Sau đó tắt cad đi.Nếu nó có hỏi có lưu bản gốc không,thì bạn cũng ok.Giờ mở file DXF đó ra,và lại nhấn Ctrl Shift S để lưu file này về định dạng bạn đang dùng( ví dụ từ 07 DXF ->07 DWG. (thường thì mình cho đè nên file gốc luôn, k bao giờ phải ngợi ^^)

    Cám ơn bạn rất nhiều. Mình đã làm được, tuy nhiên còn tức vì chưa hiểu bản chất.


  12. Khi mở bản vẽ, có dòng thông báo:

    Educational plot stam detected.

    If you continue with this operation, the drawing will be plotted with the following banner:

    "PRODUCED BY AN AUTODESK EDUCATIONAL PRODUCT"

    Do you want to continue?

    Nếu chọn "NO" thì không mở được, nếy chọn "YES" thì mở được nhưng sau đó in thì trên bản vẽ sẽ bị 4 dòng "PRODUCED BY AN AUTODESK EDUCATIONAL PRODUCT"

    chèn vào 4 phía của bản vẽ. Làm sao khắc phục?


  13. Với mã DXF Việc đấy rất khó thực hiện bạn à vì toạ độ mỗi điểm nhập của bạn cad đã tự động chuyển sang thành toạ độ đỉnh của điểm cong không theo toạ độ có sẵn của bạn, vì vậy bạn phải nghiên cứu công thức chuyển đổi đỉnh của SPLINE trước rồi mới dùng lệnh entmake được. Chúc bạn may mắn.

    Trước hết, cám ơn bạn. Tuy nhiên, cách làm theo file của bạn nếu các danh sách con đều viết trong cùng 1 hàm entmake thì tốt, chứ nếu tách ra từng danh sách hàm entmake thì không được. Trong khi nếu viết đúng mã DXF thì có thể được. Ví dụ hàm AA và BB dưới đây chạy tốt nhưng CC thì... bó tay.

    ;---------- ;Ham nay chay tot

    (defun C:AA()

    (entmake (list (cons 0 "POLYLINE")))

    (setq a (+ 1 1))

    (entmake (list (cons 0 "VERTEX") '(10 0.0 100.0 0.0)))

    (entmake (list (cons 0 "VERTEX") '(10 100.0 150.0 0.0)))

    (entmake (list (cons 0 "SEQEND"))))

    ;---------- ;Ham nay chay tot

    (defun C:BB()

    (entmake (list '(0 . "SPLINE") '(100 . "AcDbEntity") '(100 . "AcDbSpline") '(71 . 3)

    '(11 0.0 100.0 0.0) '(11 100.0 150.0 0.0) '(11 300.0 100.0 0.0))))

    ;---------- ;Ham nay botay.com

    (defun C:CC()

    (entmake (list '(0 . "SPLINE")))

    (setq b (+ 1 1))

    (entmake (list '(11 0.0 100.0 0.0)))

    (entmake (list '(11 100.0 150.0 0.0)))

    (entmake (list '(11 300.0 100.0 0.0)))

    (entmake (list '(100 . "AcDbEntity")))

    (entmake (list '(100 . "AcDbSpline")))

    (entmake (list '(71 . 3))))

    ;----------


  14. Với thu nhập bình quân hàng ngày của bạn, bạn thử đoán xem mình thuộc tầng lớp nào trong xã hội. Cách phân loại giàu nghèo theo 5 bậc như sau:

    1- Thu nhap <= 100000đ/ngày : Bạn cần xóa đói giảm nghèo.

    2- Thu nhập từ 100000 đến 500000 : Bạn chỉ nuôi đủ bản thân.

    3- Thu nhập từ 500000 đến 1000000 : Bạn nuôi đủ cả gia đình.

    4- Thu nhập từ 1000000 đến 10000000 : Bạn tương đối giàu.

    5- Thu nhập > 10000000 : Bạn là một đại gia.

    Bạn hãy tải chương trình về máy, sau đó load rồi dùng lệnh XEM, và nhập vào thu nhập bình quân hằng ngày của bạn. Chương trình sẽ đoán cho bạn.

    Ví dụ: bạn lần lượt nhập 6 số sau đây để kiểm tra: 100 ; 1000 ; 2500 ; 3000 ; 3550 ; 10000.

    Kết quả thật bất ngờ!!! Nếu xem vui vui thì cho ý kiến, đừng làm thinh!

    http://www.cadviet.com/upfiles/3/xem_boi.lsp

    Sorry: Do upload file mãi mà không được nên copy lên đây:

    (defun C:XEM()

    (setq thunhap (getint "\nThu nhap binh quan hang ngay (don vi: 10000 dong) cua ban <1-10000>: "))

    (setq thunhap (/ (* (* 10000 thunhap) 365) 365))

    (cond ((<= thunhap 100000) (alert "Ban la nguoi ngheo kiet xac!"))

    ((and (> thunhap 100000) (<= thunhap 500000)) (alert "Ban chi nuoi du ban than!"))

    ((and (> thunhap 500000) (<= thunhap 1000000)) (alert "Ban nuoi du ca gia dinh!"))

    ((and (> thunhap 1000000) (<= thunhap 10000000)) (alert "Ban tuong doi giau!"))

    ((> thunhap 10000000) (alert "Ban la mot dai gia!"))))


  15. Em muốn lấy ngày giờ hiện tại trong LISP, pác nào giúp em với

    Ban dung thu vai dong nhu sau:

    (setq cdate (menucmd “M=$(edtime,$(getvar,date),DD/MO/YYYY)”)) returns: “28/06/2010”

    (setq cdate (menucmd “M=$(edtime,$(getvar,date),DDDD\”,\” D MONTH YYYY)”)) returns: “Sunday, 16 July 1995”

    • Vote tăng 1

  16. Có thể hai hàm sin và cos có cách tính khác nhau vì tan = sin/cos trường hợp này sẽ ra vô cùng mà máy tính thì không có số vô cùng. Chậc, tính toán trên máy tính là tính gần đúng chứ không như tính theo giải tích

    Không phải chỉ LISP tính sin, cos, tan... gần đúng theo hình thức khai triển chuỗi (có lẽ thế) mà Excel... cũng vậy.

    Vấn đề đưa ra là nhằm mục đích cảnh báo những "sơ ý chết người" khi sử dụng các hàm đó.

    Ví dụ 1: ta viết một đoạn lisp như sau:

    (cond ((< a 100) (setq b 1))

    ((>= a 100) (setq b 2)))

    Khi kết quả trả về là b=1 thì ta cứ ngỡ a<100, nhưng đôi lúc a=nil, thành ra chương trình của ta có thể sai bét.

    Ví dụ 2: khi ta xét 2 đường thẳng có vuông góc với nhau hay không?

    - Nếu xét bằng hàm sin của góc tạo bởi 2 đường thẳng đó thì nó bằng 1, và điều này đúng.

    - Nếu xét bằng hàm cos của góc tạo bởi 2 đường thẳng đó thì nó bằng... 6.12303e-017, và điều này nếu không để ý thì dễ suy ra chúng không vuông góc nhau. Mà thực tế là chúng vuông góc nhau.

    Điều tôi muốn đưa lên diễn đàn chính là để cảnh báo thôi, vì chúng ta có thể "sơ ý" như trên, mà tôi đã là 1 nạn nhân của cả 2 vấn đề trên.

    Mong bạn nào có phát hiện hay thì post lên để mọi người cùng... hưởng lợi.


  17. 1. Bản thân pi là một số xấp xỉ vậy nên (cos (/ pi 2)) là một số xấp xỉ là đương nhiên. Nó không thể ra giá trị chính xác bằng 0

    2. nil luôn nhỏ hơn mọi số. Cái này ta phải bắt lỗi thôi vì phép so sánh chỉ dùng với cùng một kiểu biến

     

    Còn một số điều khó hiểu nữa (chứ không được coi là lỗi) mà bản thân chúng ta chưa hiểu hết về bản chất của lisp mà thôi

    (cos (/ pi 2)) /= 0

    nhưng (sin (/ pi 2) = 1 đấy!


  18. Có thể có bạn đã gặp và đã biết, nhưng cũng có thể có bạn chưa biết. Dưới đây là vài lỗi "oái oăm" trong LISP. Cứ ngỡ nó bình thường nhưng đôi lúc nó khiến bạn mất một đống thời gian vì chúng:

    1) Hãy thử suy nghĩ xem: (cos (/ pi 2))=0 là đúng hay sai?

    2) Cho: (setq a nil). Hãy thử suy nghĩ xem: (< a 100) cho kết quả là gì?

    Ai biết thêm thì post lên cho mọi người.

×