.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Draw a polyline with an arrow

19 REPLIES 19
SOLVED
Reply
Message 1 of 20
quyenpv
1422 Views, 19 Replies

Draw a polyline with an arrow

Do you use vb.net or c# draw a polyline with arrow using EntityJig which allows you to change the direction of the arrow as shown below

DynArrow.gif.b28a0b45685cb8ca595de2a370c285dd.gif

Due to the fact that work often has to use arrows, if you can draw and drag the desired arrow direction as above, it will be very effective for the job.

Screenshot 2023-08-15 214044.png

 

19 REPLIES 19
Message 2 of 20
Ed.Jobe
in reply to: quyenpv

Are you offering to share your code?? If so, post it in a code window using the </> button.

Ed


Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
How to post your code.

EESignature

Message 3 of 20
hippe013
in reply to: quyenpv

Either language will get the job done. If you are just starting out and haven't learned either language then it is recommended to use C#. The majority of examples posted are written in C#. 

Message 4 of 20
quyenpv
in reply to: Ed.Jobe

Yes, I just found a lisp with the same function as above, but I hope you can only help with the vb.net or c# code to draw the arrow as above.
Message 5 of 20
_gile
in reply to: quyenpv

Hi,

Before embarking on such a task, you should first learn how to simply acquire a user start and end point and draw an arrow-shaped polyline in the current space.

Using classes derived from EntityJig to dynamically display entity modifications based on cursor position requires a mastery of the basic concepts of AutoCAD's .NET API.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 6 of 20
quyenpv
in reply to: _gile

@_gile Please help fix it

 

Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Geometry

Public Class ArrowJig
    Inherits EntityJig

    Private _startPoint As Point3d
    Private _arrowEnd As Point3d

    Public Sub New(entity As Entity, startPt As Point3d)
        MyBase.New(entity)
        _startPoint = startPt
        _arrowEnd = startPt
    End Sub

    Protected Overrides Function Sampler(prompts As JigPrompts) As SamplerStatus
        Dim jppo As New JigPromptPointOptions("Chọn điểm kết thúc mũi tên:")
        jppo.BasePoint = _startPoint
        jppo.UseBasePoint = True

        Dim res = prompts.AcquirePoint(jppo)
        If res.Value.Equals(_arrowEnd) Then
            Return SamplerStatus.NoChange
        Else
            _arrowEnd = res.Value
            Return SamplerStatus.OK
        End If
    End Function

    Protected Overrides Function Update() As Boolean
        Dim polyline As Polyline = TryCast(Me.Entity, Polyline)
        If polyline IsNot Nothing Then
            Dim dir = _arrowEnd - _startPoint
            Dim arrowLen = dir.Length / 3
            Dim perp = dir.GetPerpendicularVector().GetNormal() * arrowLen / 2
            dir = dir.GetNormal()

            polyline.SetPointAt(0, New Point2d(_startPoint.X, _startPoint.Y))
            polyline.SetPointAt(1, New Point2d(_arrowEnd.X, _arrowEnd.Y))
            polyline.SetPointAt(2, New Point2d((_arrowEnd - (dir * arrowLen)).X, (_arrowEnd - (dir * arrowLen)).Y))
            polyline.SetPointAt(3, New Point2d((_arrowEnd - (dir * arrowLen) + perp).X, (_arrowEnd - (dir * arrowLen) + perp).Y))
        End If
        Return True
    End Function

    Public Shared Sub CreateArrow()
        Dim doc = Application.DocumentManager.MdiActiveDocument
        Dim db = doc.Database
        Dim ed = doc.Editor

        Dim ppr = ed.GetPoint("Chọn điểm bắt đầu mũi tên:")
        If ppr.Status <> PromptStatus.OK Then
            Return
        End If

        Dim polyline As New Polyline()
        polyline.AddVertexAt(0, New Point2d(ppr.Value.X, ppr.Value.Y), 0, 0, 0)
        polyline.AddVertexAt(1, New Point2d(ppr.Value.X, ppr.Value.Y), 0, 0, 0)
        polyline.AddVertexAt(2, New Point2d(ppr.Value.X, ppr.Value.Y), 0, 0, 0)

        Dim jig As New ArrowJig(polyline, ppr.Value)
        Dim res = ed.Drag(jig)
        If res.Status = PromptStatus.OK Then
            Using tr = db.TransactionManager.StartTransaction()
                Dim btr As BlockTableRecord = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite)
                btr.AppendEntity(polyline)
                tr.AddNewlyCreatedDBObject(polyline, True)
                tr.Commit()
            End Using
        End If
    End Sub

End Class

#Region "Test Commands"
Public Module TestArrow
    <CommandMethod("TestArrow")>
    Public Sub CreateArrowCmd()
        ArrowJig.CreateArrow()
    End Sub
End Module
#End Region

 

Message 7 of 20
GiaBach
in reply to: quyenpv

Hi Quyen,

Here's the update, but as Mr.Gile said "Don't try to run before you're able to stand up".

    Protected Overrides Function Update() As Boolean
        Dim polyline As Polyline = TryCast(Me.Entity, Polyline)
        If polyline IsNot Nothing Then
            Dim dir = _arrowEnd - _startPoint
            Dim arrowLen = dir.Length / 3
            Dim perp = dir.GetPerpendicularVector().GetNormal() * arrowLen / 2
            dir = dir.GetNormal()

            polyline.SetPointAt(0, New Point2d(_startPoint.X, _startPoint.Y))
            polyline.SetPointAt(1, New Point2d((_arrowEnd - (dir * arrowLen)).X, (_arrowEnd - (dir * arrowLen)).Y))
            polyline.SetStartWidthAt(1, arrowLen / 2)
            polyline.SetPointAt(2, New Point2d(_arrowEnd.X, _arrowEnd.Y))
            'polyline.SetPointAt(3, New Point2d((_arrowEnd - (dir * arrowLen) + perp).X, (_arrowEnd - (dir * arrowLen) + perp).Y))
        End If
        Return True
    End Function
Message 8 of 20
quyenpv
in reply to: GiaBach

Thank you @GiaBach , @_gile 
The above code after updating still can't drag the arrow direction after drawing like the picture

DynArrow.gif.b28a0b45685cb8ca595de2a370c285dd.gif

 

Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Geometry

Public Class ArrowJig
    Inherits EntityJig

    Private _startPoint As Point3d
    Private _arrowEnd As Point3d

    Public Sub New(entity As Entity, startPt As Point3d)
        MyBase.New(entity)
        _startPoint = startPt
        _arrowEnd = startPt
    End Sub

    Protected Overrides Function Sampler(prompts As JigPrompts) As SamplerStatus
        Dim jppo As New JigPromptPointOptions("Chọn điểm kết thúc mũi tên:")
        jppo.BasePoint = _startPoint
        jppo.UseBasePoint = True

        Dim res = prompts.AcquirePoint(jppo)
        If res.Value.Equals(_arrowEnd) Then
            Return SamplerStatus.NoChange
        Else
            _arrowEnd = res.Value
            Return SamplerStatus.OK
        End If
    End Function

    Protected Overrides Function Update() As Boolean
        Dim polyline As Polyline = TryCast(Me.Entity, Polyline)
        If polyline IsNot Nothing Then
            Dim dir = _arrowEnd - _startPoint
            Dim arrowLen = dir.Length / 3
            Dim perp = dir.GetPerpendicularVector().GetNormal() * arrowLen / 2
            dir = dir.GetNormal()

            polyline.SetPointAt(0, New Point2d(_startPoint.X, _startPoint.Y))
            polyline.SetPointAt(1, New Point2d((_arrowEnd - (dir * arrowLen)).X, (_arrowEnd - (dir * arrowLen)).Y))
            polyline.SetStartWidthAt(1, arrowLen / 2)
            polyline.SetPointAt(2, New Point2d(_arrowEnd.X, _arrowEnd.Y))
            'polyline.SetPointAt(3, New Point2d((_arrowEnd - (dir * arrowLen) + perp).X, (_arrowEnd - (dir * arrowLen) + perp).Y))
        End If
        Return True
    End Function

    Public Shared Sub CreateArrow()
        Dim doc = Application.DocumentManager.MdiActiveDocument
        Dim db = doc.Database
        Dim ed = doc.Editor

        Dim ppr = ed.GetPoint("Chọn điểm bắt đầu mũi tên:")
        If ppr.Status <> PromptStatus.OK Then
            Return
        End If

        Dim polyline As New Polyline()
        polyline.AddVertexAt(0, New Point2d(ppr.Value.X, ppr.Value.Y), 0, 0, 0)
        polyline.AddVertexAt(1, New Point2d(ppr.Value.X, ppr.Value.Y), 0, 0, 0)
        polyline.AddVertexAt(2, New Point2d(ppr.Value.X, ppr.Value.Y), 0, 0, 0)

        Dim jig As New ArrowJig(polyline, ppr.Value)
        Dim res = ed.Drag(jig)
        If res.Status = PromptStatus.OK Then
            Using tr = db.TransactionManager.StartTransaction()
                Dim btr As BlockTableRecord = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite)
                btr.AppendEntity(polyline)
                tr.AddNewlyCreatedDBObject(polyline, True)
                tr.Commit()
            End Using
        End If
    End Sub

End Class

#Region "Test Commands"
Public Module TestArrow
    <CommandMethod("TestArrow")>
    Public Sub CreateArrowCmd()
        ArrowJig.CreateArrow()
    End Sub
End Module
#End Region

 

Message 9 of 20
kdub_nz
in reply to: quyenpv

@quyenpv 

 

That's your homework  🙂


// Called Kerry in my other life.

Everything will work just as you expect it to, unless your expectations are incorrect.

class keyThumper<T> : Lazy<T>;      another  Swamper

Message 10 of 20
_gile
in reply to: quyenpv

@quyenpv

Did you write this code yourself? Because it seems to have been written by a ChatGPT (i.e., an assembly of code snippets that it doesn't understand but that seems to answer the request).

 

It seems that you don't want to follow the recommendations you've been given to learn how to program AutoCAD.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 11 of 20
quyenpv
in reply to: _gile

This code I wrote myself and concatenated many reference codes on the forums

Message 12 of 20
quyenpv
in reply to: kdub_nz

No you. Draw this arrow just for quick in the wiring diagram to show the direction of soldering
Message 13 of 20
_gile
in reply to: quyenpv


@quyenpv  a écrit :

This code I wrote myself and concatenated many reference codes on the forums


This is the same way ChatGPT tries to predict what a code responding to a request might be, and most of the time the code doesn't work.

 

If you really want to learn programming, write code step by step.

First write simple command to draw an arrow from the start point to the end point (note you can use the polyline width for the arrow head).

Second write another simple command for the reversed arrow (arrow head on the start point).

Finally you could try to write a code using a Jig to switch the side of the arrow head according to the cursor position.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 14 of 20
quyenpv
in reply to: quyenpv

So sad! Still can't write

Message 15 of 20
cuongtk2
in reply to: quyenpv

You can't eat a big piece and you'll get fat right away

Message 16 of 20
quyenpv
in reply to: quyenpv

Learning is an extension of the whole process. Crossing martial arts is too difficult
Học là một sự trải dài của cả quá trình. Vượt vũ môn khó quá

Message 17 of 20
_gile
in reply to: quyenpv

Here's a code that shows you how to draw a simple arrow.

Instead of copying and pasting the code, which teaches nothing, rewrite it, trying to understand everything you write.

_gile_0-1692268190038.png

 

 

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 18 of 20
_gile
in reply to: _gile

Step 2: draw the reversed arrow.

The code is the same, excepted the arrow head and the width position.

_gile_1-1692268310315.png

 

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 19 of 20
_gile
in reply to: _gile

Now that we know how to draw the arrow in both directions, we can separate the part of the code that draws the base polyline and the part that draws the arrowhead, and execute the latter part with a Jig to let the user choose the direction.

 

The command method:

_gile_0-1692346356069.png

 

The ArrowJig class

_gile_1-1692346493438.png

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 20 of 20
quyenpv
in reply to: quyenpv

Thank you very much @_gile 

Through your code, I really understand its essence

Code full C# of @_gile 

 

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;

[assembly: CommandClass(typeof(ArrowCommands))]

public class ArrowCommands
{
    [CommandMethod("Arrow3")]
    public static void DrawArrow()
    {
        Document doc = Application.DocumentManager.MdiActiveDocument;
        Database db = doc.Database;
        Editor ed = doc.Editor;

        PromptPointOptions ppo = new PromptPointOptions("\nStart point:");
        PromptPointResult ppr = ed.GetPoint(ppo);
        if (ppr.Status != PromptStatus.OK) return;
        Point3d point1 = ppr.Value;

        ppo.Message = "\nEnd point:";
        ppo.UseBasePoint = true;
        ppo.BasePoint = ppr.Value;
        ppr = ed.GetPoint(ppo);
        if (ppr.Status != PromptStatus.OK) return;
        Point3d point2 = ppr.Value;

        using (Transaction tr = doc.TransactionManager.StartTransaction())
        {
            using (Polyline pline = new Polyline())
            {
                Point2d startPoint = new Point2d(point1.X, point1.Y);
                Point2d endPoint = new Point2d(point2.X, point2.Y);
                pline.AddVertexAt(0, startPoint, 0.0, 0.0, 0.0);
                pline.AddVertexAt(1, endPoint, 0.0, 0.0, 0.0);
                pline.TransformBy(ed.CurrentUserCoordinateSystem);

                // Using a jig to set the arrow head
                ArrowJig jig = new ArrowJig(pline);
                PromptResult jigResult = ed.Drag(jig);
                if (jigResult.Status == PromptStatus.OK)
                {
                    BlockTableRecord curSpace = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
                    curSpace.AppendEntity(pline);
                    tr.AddNewlyCreatedDBObject(pline, true);
                }
            }
            tr.Commit();
        }
    }
}

class ArrowJig : EntityJig
{
    private Polyline pline;
    private Point3d dragPoint;
    private Point2d startPoint, endPoint;
    private Vector2d vector;
    private double width;

    public ArrowJig(Polyline pline) : base(pline)
    {
        this.pline = pline;
        startPoint = pline.GetPoint2dAt(0);
        endPoint = pline.GetPoint2dAt(1);
        vector = startPoint.GetVectorTo(endPoint) / 3.0;
        width = pline.Length / 6.0;

        pline.AddVertexAt(1, endPoint - vector, 0.0, width, 0.0);
    }

    protected override SamplerStatus Sampler(JigPrompts prompts)
    {
        PromptPointResult promptPointResult = prompts.AcquirePoint("\nPick a point on the arrowhead side:");
        if (promptPointResult.Value.IsEqualTo(dragPoint))
            return SamplerStatus.NoChange;
        
        dragPoint = promptPointResult.Value;
        return SamplerStatus.OK;
    }

    protected override bool Update()
    {
        if (dragPoint.DistanceTo(startPoint) < dragPoint.DistanceTo(endPoint))
        {
            pline.SetPointAt(1, startPoint + vector);
            pline.SetEndWidthAt(0, width);
            pline.SetStartWidthAt(1, 0.0);
        }
        else
        {
            pline.SetPointAt(1, endPoint - vector);
            pline.SetEndWidthAt(0, 0.0);
            pline.SetStartWidthAt(1, width);
        }
        return true;
    }
}

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Forma Design Contest


Autodesk Design & Make Report