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

gia_bach

CADViet Team
  • Số lượng nội dung

    1.624
  • Đã tham gia

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

  • Ngày trúng

    122

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


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

    Hỏi về thuật toán.

    Tôi có 1 pline 2D lớn (màu đỏ), closed, không chứa arc và nhiều pline 2D nhỏ (màu trắng), closed và không chứa arc.

    Cần 1  thuật toán để biến các pline nhỏ thỏa mãn:

    - Nếu nằm trong đỏ (kể cả trùng cạnh) thì giữ nguyên.

    - Nếu nằm ngoài đỏ (kể cả trùng cạnh) thì xóa.

    - Nếu giao nhau thì cắt bỏ phần ngoài đỏ và tạo thành pline mới closed (bao gồm cả phần đỏ nằm trong pline trắng như hình).

    Đ/k: Không dùng đến region (vì  thứ này đã dùng chạy chậm và dễ lỗi). Và chạy càng nhanh càng tốt (vì có hàng ngàn hình nhỏ).

    Ai có thuật toán hay xin mách giùm. Thanks!

     

    Tôi dùng cách này, (bỏ qua t/h pline khác cao độ.)


    Xét giao điểm của 2 pline (có thể dùng hàm IntersectWith ):
    -    nếu không có giao điểm (pline màu đỏ và màu vàng) :
          xét 1 đỉnh bất kì của pline (vàng+đỏ), 
             +    nếu đỉnh đó nằm trong pline trắng -> pline đó nằm trong (chọn)
             +    nếu đỉnh đó nằm ngoài -> pline đó nằm ngoài (bỏ)
    -    có giao điểm,  duyệt qua toàn bộ các đỉnh của pline
             +    TH1 pline green: nếu tất cả các đỉnh đều nằm ngoài HOẶC nằm trên cạnh của pline trắng -> pline đó nằm ngoài (bỏ)
             +    TH2 pline cyan: nếu tất cả các đỉnh đều nằm trong HOẶC nằm trên cạnh của pline trắng -> pline đó nằm trong (chọn)
             +    TH3 pline magenta: có đỉnh nằm trong và đỉnh nằm ngoài     

     

    image.thumb.png.2998f0eb81e8111de32a0fd36b9b1f1d.png

     

    T/hợp 3 (minh họa t/h đơn giản chỉ có 2 giao điểm):

    1. BREAK tại các giao điểm , sau đó duyệt qua các đỉnh của pline bị break (có t/hợp phải duyệt qua các trung điểm của các cạnh):
      -    chỉ cần 1 đỉnh nằm ngoài pline trắng -> bỏ qua pline này 
      -    chỉ cần 1 đỉnh nằm trong pline trắng -> chon pline này.

     

    2. Làm ngược lại, BREAK pline trắng tại các giao điểm và chọn pline bên trong pline magenta

    3. Nối 2 pline với nhau.
    image.png.9d340da73a7581935fff8a9e42e00dd5.png

     

    + Một t/hợp phức tạp

    image.png.acc917cfaaa942de8afbd3297347d721.png

     

     

    • Like 1

  2. Bác Hạ tham khảo code này:

        ' draw a spline from points
        <CommandMethod("AddSpline_HA")>
        Public Sub AddSpline_HA()
            Dim doc As Document = Application.DocumentManager.MdiActiveDocument
            Dim db As Database = doc.Database
            Dim ed As Editor = doc.Editor
    
            Dim tvArr(0) As TypedValue
            tvArr.SetValue(New TypedValue(DxfCode.Start, "point"), 0)
    
            Dim filter As SelectionFilter = New SelectionFilter(tvArr)
            Dim pso As PromptSelectionOptions = New PromptSelectionOptions()
            pso.MessageForAdding = "Select points to add a spline"
    
            'Get a selection
            Dim result As PromptSelectionResult = ed.GetSelection(pso, filter)
            If result.Status <> PromptStatus.OK Then
                Return
            End If
    
            '' Start a transaction
            Using tr As Transaction = db.TransactionManager.StartTransaction()
                Dim ptColl As Point3dCollection = New Point3dCollection()
    
                Dim ss As SelectionSet = result.Value
                For Each sob As SelectedObject In ss
                    Dim pointObj As DBPoint = DirectCast(tr.GetObject(sob.ObjectId, OpenMode.ForRead), DBPoint)
                    Dim pos As Point3d = pointObj.Position
                    If Not ptColl.Contains(pos) Then
                        ptColl.Add(pos)
                    End If
                Next
    
                '' Open the Block table for write
                Dim currentSpace As BlockTableRecord = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite)
    
                '' Get a 3D vector from the point (0.5,0.5,0)
                Dim vecTan As Vector3d = New Point3d(0.5, 0.5, 0).GetAsVector
    
                '' Create a spline with a start and end tangency of (0.5, 0.5, 0.0)
                Dim spline As Spline = New Spline(ptColl, vecTan, vecTan, 4, 0.0)
                spline.ColorIndex = 1
                '' Add the new object to the block table record and the transaction
                currentSpace.AppendEntity(spline)
                tr.AddNewlyCreatedDBObject(spline, True)
    
    
                ' other constructor
                spline = New Spline(ptColl, 4, 0.0)
                spline.ColorIndex = 4
                currentSpace.AppendEntity(spline)
                tr.AddNewlyCreatedDBObject(spline, True)
    
                tr.Commit()
            End Using
        End Sub

     

    • Like 1

  3. Hỏi về giải thuật chắc sẽ có nhiều người người trả lời hơn!

     

     

    Về cơ bản v/đề của bạn là tìm giao của 2 line: sử dụng hàm Intersectwith

                     Line l1 = tr.GetObject(per.ObjectId, OpenMode.ForRead) as Line;
                     per = ed.GetEntity("Line2");
                     Line l2 = tr.GetObject(per.ObjectId, OpenMode.ForRead) as Line;
                     Point3dCollection ptcol = new Point3dCollection();
                     l1.IntersectWith(l2, Intersect.ExtendBoth,ptcol, IntPtr.Zero, IntPtr.Zero);

     

    sau đó thay đổi điểm đầu mút gần giao điểm :

    line.Startpoint = giao điểm
    or  line.Endpoint = giao diểm

     

    • Like 1

  4. 1 giờ} trướ}c, Nguyên Khải đã nói:

    Chào cả nhà, em mới tìm hiểu về C# với autocad. Làm thử cái Addin cho Autocad 2020, nhưng khi debug sử dụng netload để load file .dll thì gõ lệnh lại không ra. Nhờ các anh chỉ điểm giúp em với ạ. (Visual studio 2017, đã add các file thư viện AcCoreMgd.dll, AcDbMgd.dll, AcMgd.dll và sử dụng template flugin của autocad 2020)

    
    using System;
    using Autodesk.AutoCAD.Runtime;
    using Autodesk.AutoCAD.ApplicationServices;
    using Autodesk.AutoCAD.DatabaseServices;
    using Autodesk.AutoCAD.Geometry;
    using Autodesk.AutoCAD.EditorInput;
    
    
    using AcAp = Autodesk.AutoCAD.ApplicationServices.Application;
    
    
    [assembly: ExtensionApplication(typeof(Autocad_2020_plugin_001.MyPlugin))]
    
    namespace Autocad_2020_plugin_001
    {
        public class MyPlugin
        {
            [CommandMethod("cmdhello")]
            public void cmdFirstCommand()
            {
                var doc = AcAp.DocumentManager.MdiActiveDocument;
                //var db = doc.Database;
                var ed = doc.Editor;
    
                ed.WriteMessage("\n Hello World");
            }        
        }
    }

     

    Code không thấy sai chỗ nào!

    bạn có thể upload project ?


  5. 28 phút trước, Doan Van Ha đã nói:

    Mọi người cho hỏi: có ai gặp lỗi này chưa? Lý do lỗi? Cách giải quyết?

    Là: khi lấy Intersection của 2 regions thì kết quả trả về không đúng. VD trong hình và file đính kèm thì khi lấy region to (màu xanh) trừ đi region nhỏ (màu đỏ) cad lại trả về như kết quả Union của 2 regions xanh và đỏ. Đính kèm hình + file cad + file lsp để test.

     

     

    Error.lsp

    Intersection.dwg

    Cad 2015 khi dùng (vla-boolean rg_to acIntersection rg_nho) trả về region có area =0


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

    Chào mọi người mình tìm được 1 lisp dim polyline nhưng muốn chỉnh lại theo nhu cầu của mình, khi dùng các phân đoạn arc trong polyline sẽ được dim theo 2 điểm đầu và cuối, nhờ mọi người sữa giúp mình để các phân đoạn arc đó dùng dimarc để dim. Cám ơn mọi người.

    image.thumb.png.50f4ae7b53ff60cfb1fcde6416c251a8.png

    dpl.dwg

    DPL_Automatic Dimension Pline.lsp

    Bạn thử Lisp này.

    chú ý chọn Dim_style trước khi chạy lệnh nhé.

    (defun c:dimpl(/ doc ep i mp obj oldosn pllst plset sp spc)
      (defun LM:BulgeCenter ( p1 p2 b )
        (polar p1
    	   (+ (angle p1 p2) (- (/ pi 2) (* 2 (atan b))))
    	   (/ (* (distance p1 p2) (1+ (* b b))) 4 b)    ))
      
      (princ "\n<<< Select LwPolyline for dimensioning >>> ")
      (setq doc (vla-get-activedocument (vlax-get-acad-object))
            spc (vlax-get doc (if (eq (getvar 'CVPORT) 1)
    			    'Paperspace
    			    'Modelspace	    )	    )  )
      
      (if(setq plSet(ssget '((0 . "LWPOLYLINE"))))
        (progn
          (setq pLlst(vl-remove-if 'listp(mapcar 'cadr(ssnamex plSet)))
    	    oldOsn (getvar "OSMODE"))
          (setvar "OSMODE" 0)
          (foreach pl pLlst
    	(setq obj (vlax-ename->vla-object pl)
    	      i 0)
    	(Repeat (fix (vlax-curve-getEndParam obj))
    	  (setq sp (vlax-curve-getpointatparam obj i)
    		ep (vlax-curve-getpointatparam obj (1+ i))
    		mp (vlax-curve-getpointatparam obj (+ i 0.5)))
    	  (if (= 0 (vla-GetBulge obj i))
    	    (vla-AddDimAligned spc
    	      (vlax-3d-point sp) (vlax-3d-point ep) (vlax-3d-point mp))
    	    (vla-AddDimArc spc
    	      (vlax-3d-point (LM:BulgeCenter sp ep (vla-GetBulge obj i)))
    	      (vlax-3d-point sp) (vlax-3d-point ep) (vlax-3d-point mp))
    	    );if
    	  (setq i (1+ i))
    	  ); Repeat
    	); end foreach
          (setvar "OSMODE" oldOsn)
          ); end progn
        ); end if
      (princ)
      ); end of defun

     

    • Like 1

  7. 5 giờ trước, alisp đã nói:

    Đó là mã unicode, muốn biết chữ nào mã bao nhiêu thì dùng hàm unicode() trong excel. Tuy nhiên cách này thủ công quá, vài chữ thì được chứ nhiều thì khá phiền. Tôi thấy nếu trong file lsp đã hiện chữ nhật và trong cad cũng dùng font nhật thì sẽ hiện đúng thôi.

    Chắc bạn "cưỡi ngựa xem hoa" rồi.

    image.thumb.png.dd9dec36623189fd4b818eda7def293a.png


  8. 25 phút trước, phat1998 đã nói:

    chào anh, đây là lisp chia đường thành n điểm để lấy về tọa độ điểm và góc tạo bởi đường pháp tuyến tại mỗi điểm với trục 0x. xuất ra file text với cú pháp mỗi dòng là ( G01 X_ Y_ A_)

    anh có thể convert từ lisp  sang c# được ko ạ

    phat.LSP

    Ở bên topic Lisp, bác Huy đã làm tốt công việc này, cớ gì bạn phải convert qua C#?

     

    có vẻ như cái bạn cần là C++ (ARX), để lập trình cho máy CNC.


  9. 5 giờ trước, Bùi Mạnh Hùng đã nói:

    Mình có đoạn code này, mình quét chọn đối tượng trên bản vẽ sau đó lọc ra các đối tượng là dimension. Mình muốn lấy tọa độ ExtLinePoint của Dimension để xử lý, mà không hiểu sao mình không lấy được. Có bạn nào giúp mình sửa lại đoạn code với. Cái đoạn trong dấu ngoặc í. Mình cám ơn nhiều.

     

    Sub checkkichthuoclo()

    Dim obs1 As AcadSelectionSet
    Dim object1 As Variant
    Dim dimaligned1 As AcadDimAligned
    Dim point As Variant

     

    On Error Resume Next
    Set obs1 = ThisDrawing.SelectionSets("Myss")
    If Err Then
    Err.Clear
    Set obs1 = ThisDrawing.SelectionSets.Add("Myss")
    Else
    obs1.Clear
    End If
    obs1.SelectOnScreen

     

    (

        For Each object1 In obs1
        If object1.ObjectName = "AcDbRotatedDimension" Then
        Set dimaligned1 = object1
        point = dimaligned1.ExtLine1Point
        MsgBox point(0)
        Else: End If
        Next

    )


    End Sub

     

     

    Thay thế dòng:

    If object1.ObjectName = "AcDbRotatedDimension" Then

    bằng :

    If object1.ObjectName = "AcDbAlignedDimension" Then

    • Like 1
×