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

how to fillet line and arc?

24 REPLIES 24
Reply
Message 1 of 25
mpropst
2686 Views, 24 Replies

how to fillet line and arc?

is there a way to do that programatically? fillet a line and arc

24 REPLIES 24
Message 2 of 25
caddzone
in reply to: mpropst

Yes, but not directly. You have to find the intersection points and then

calculate the new endpoints, and either replace the existing entities with

new ones, or manipulate the existing ones using the methods of the

Curve class (e.g, Extend(), GetSplitCurves(), and so on).

 

 



AcadXTabs for AutoCAD
Supporting AutoCAD 2000-2011


Message 3 of 25
Hallex
in reply to: mpropst

Try CommandLine class from there:

 

http://www.caddzone.com/CommandLine.cs

 

it's likes me more 🙂

 

~'J'~

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 4 of 25
mpropst
in reply to: Hallex

l'll try and figure how to use a c# class in a vbnet app.

the manual calcs are making me feel stupid

🙂

Message 5 of 25
Hallex
in reply to: mpropst

Sorry, I don't knew that you use VB.NET

 

Try handle this class instead:

 

http://www.caddzone.com/CommandLine.vb

 

~'J'~

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 6 of 25
mpropst
in reply to: caddzone

hmmm, i'm not seeing it

i imported .Geometry

 

Dim oCurve As Curve2d
'cast arc to curve

    oCurve = CType(oArc3, Curve2d)

I don't get an .Extend method on the oCurve object

what am i missing?

(other than a brain)

🙂

thanks

mark

 

Message 7 of 25
mpropst
in reply to: Hallex

oh, thanks

Message 8 of 25
mpropst
in reply to: Hallex

Do you have a sample of it's use?

i'll search this group too.

Message 9 of 25
Hallex
in reply to: mpropst

I have already wrote similar one few moons ago

Still searching in my codes but with no luck yet 😞

 

~'J'~

 

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 10 of 25
Hallex
in reply to: mpropst

Huray, have found it in my garbage

Unfortunatelly it's on C# only

I'm pretty sure you could rewrite the code on VB.NET

(change AllowedType to arc and line)

 

        /// <summary>
        ///                     * FILLET LINES *
        /// </summary>
        [CommandMethod("filletlines", CommandFlags.UsePickSet | CommandFlags.Redraw)]
        public static void FL()
        {
            Database db = HostApplicationServices.WorkingDatabase;

            Document doc = acadApp.DocumentManager.MdiActiveDocument;

            Editor ed = doc.Editor;

            Transaction tr = db.TransactionManager.StartTransaction();

            using (tr)
            {
                try
                {
                    // Prompt for the fillet radius

                    PromptDoubleOptions pdo = new PromptDoubleOptions("\nEnter the fillet radius: ");
                    pdo.AllowZero = false;

                    pdo.AllowNegative = false;

                    pdo.AllowNone = false;

                    PromptDoubleResult pdr = ed.GetDouble(pdo);

                    if (pdr.Status != PromptStatus.OK)

                        return;

                    double rad = pdr.Value;

                    // Prompt for the lines to fillet

                    PromptEntityOptions peo = new PromptEntityOptions("\nSelect first line:");
                    peo.SetRejectMessage("\nSelect lines only");

                    peo.AddAllowedClass(typeof(Line), true);

                    PromptEntityResult per = ed.GetEntity(peo);

                    if (per.Status != PromptStatus.OK)

                        return;

                    ObjectId fid = per.ObjectId;

                    peo.Message = "\nSelect second line:";

                    per = ed.GetEntity(peo);

                    if (per.Status != PromptStatus.OK)

                        return;

                    ObjectId sid = per.ObjectId;

                    ObjectId[] ids = new ObjectId[2];

                    ids[0] = fid;

                    ids[1] = sid;

                    DBObject obj1 = tr.GetObject(fid, OpenMode.ForWrite);

                    DBObject obj2 = tr.GetObject(sid, OpenMode.ForWrite);

                    acadApp.SetSystemVariable("FILLETRAD", rad);

                    acadApp.SetSystemVariable("CMDECHO", 0);

                    ResultBuffer buf = new ResultBuffer();

                    buf.Add(new TypedValue(5005, "_FILLET"));

                    buf.Add(new TypedValue(5006, fid));

                    buf.Add(new TypedValue(5006, sid));

                    acedCmd(buf.UnmanagedObject);

                    buf.Dispose();

                    acadApp.SetSystemVariable("CMDECHO", 1);

                    tr.Commit();
                }

                catch (Autodesk.AutoCAD.Runtime.Exception ex)
                {
                    ed.WriteMessage(ex.Message + "\n" + ex.StackTrace);
                }
            }
        }

 

~'J'~

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 11 of 25
Hallex
in reply to: mpropst

Use this tools to convert the code:

 

http://converter.telerik.com/

 

I haven't have a time now, so sorry

 

~'J'~

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 12 of 25
Hallex
in reply to: mpropst

Stupid me, I forgot to add AcedCmd function

Here is one on VB.NET

 

Declarations

Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.GraphicsInterface
Imports AcadRT = Autodesk.AutoCAD.Runtime
Imports AcadED = Autodesk.AutoCAD.EditorInput
Imports AcadDB = Autodesk.AutoCAD.DatabaseServices
Imports System.Runtime.InteropServices

 Remove unused above

 

    <DllImport("acad.exe", BestFitMapping:=True, CallingConvention:=CallingConvention.Cdecl, CharSet:=CharSet.Auto)> _
    Private Shared Function acedCmd(ByVal vlist_in As System.IntPtr) As Integer
    End Function

    <CommandMethod("FL")> _
    Public Shared Sub FL()
        Dim db As Database = HostApplicationServices.WorkingDatabase

        Dim doc As Autodesk.AutoCAD.ApplicationServices.Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument

        Dim ed As Editor = doc.Editor

        Dim tr As Transaction = db.TransactionManager.StartTransaction()

        Using tr
            Try
                ' Prompt for the fillet radius

                Dim pdo As New PromptDoubleOptions(vbLf & "Enter the fillet radius: ")
                pdo.AllowZero = False

                pdo.AllowNegative = False

                pdo.AllowNone = False

                Dim pdr As PromptDoubleResult = ed.GetDouble(pdo)

                If pdr.Status <> PromptStatus.OK Then

                    Return
                End If

                Dim rad As Double = pdr.Value

                ' Prompt for the lines to fillet

                Dim peo As New PromptEntityOptions(vbLf & "Select first line:")
                peo.SetRejectMessage(vbLf & "Select line only")

                peo.AddAllowedClass(GetType(Line), True)

                Dim per As PromptEntityResult = ed.GetEntity(peo)

                If per.Status <> PromptStatus.OK Then

                    Return
                End If

                Dim fid As ObjectId = per.ObjectId

                peo.SetRejectMessage(vbLf & "Select arc only")

                peo.AddAllowedClass(GetType(Arc), True)

                peo.Message = vbLf & "Select arc:"

                per = ed.GetEntity(peo)

                If per.Status <> PromptStatus.OK Then

                    Return
                End If

                Dim sid As ObjectId = per.ObjectId

                Dim ids As ObjectId() = New ObjectId(1) {}

                ids(0) = fid

                ids(1) = sid

                Dim obj1 As DBObject = tr.GetObject(fid, OpenMode.ForWrite)

                Dim obj2 As DBObject = tr.GetObject(sid, OpenMode.ForWrite)

                Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("FILLETRAD", rad)

                Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("CMDECHO", 0)

                Dim buf As New ResultBuffer()

                buf.Add(New TypedValue(5005, "_FILLET"))

                buf.Add(New TypedValue(5006, fid))

                buf.Add(New TypedValue(5006, sid))

                acedCmd(buf.UnmanagedObject)

                buf.Dispose()

                Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("CMDECHO", 1)

                tr.Commit()

            Catch ex As Autodesk.AutoCAD.Runtime.Exception
                ed.WriteMessage(ex.Message + vbLf + ex.StackTrace)
            End Try
        End Using
    End Sub

 

~'J'~

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 13 of 25
mpropst
in reply to: Hallex

thanks,

i'll study that and see what i can use

mark

 

Message 14 of 25
mpropst
in reply to: caddzone

am i overthinking this?

i have two arcs (concentric)

they happen to be lying horiz (like a smile)

on either end are two lines connecting the endpoints of the concentric arcs

like a big open smile (so we have 2 arcs and 2 lines)

 

i need to programatically offset the two arcs by distance a and offset the two lines by distance b "away from the center of the smile"

 

then i need to rejoin the new arcs and new lines in a bigger smile (enclosing the original "smile")

this is appearing to take a huge amount of calculating "who is closest to who" and if i need to adjust start or end points

even calculating which direction to offset each arc and each line takes several calcs to decide whether it's a positive distance or negative distance in order to go "away from the center of the smile", not "toward the center of the smile"

 

 

is there an easier way to do this?

the pseudo code at this point seems like

 

is line1 closer to arc1 startpoint or endpoint?

is line2 closer to arc1 startpoint or endpoint?

is line1 closer to arc2 startpoint or endpoint?

is line2 closer to arc2 startpoint or endpoint?

since there are two intersections between each arc and each line...

get the two intersections (times 4)

for each pair of intersections

   is point 1 closer to arc startpoint or endpoint or is point2 closer

  whichever is closeest to existing arc is the intersection we want

  either arc startangle or arc endangle is adjusted depending on if startpoint or endpoint of arc is closes to new intersection

ditto for each line, which line is closest to which arc

is it startpoint of the line or endpoint of line that is closest to new intersection

 etc etc etc

 

has anyone attacked this kind of thing before?

what simple easy method am i not thinking of?

 

thanks

mark

 

 

 

Message 15 of 25
caddzone
in reply to: mpropst

I'm not responding to this because you chose the 'thousand words' rather than the picture.

 

 



AcadXTabs for AutoCAD
Supporting AutoCAD 2000-2011


Message 16 of 25
mpropst
in reply to: caddzone

one of my many defects

🙂

thankyou for such an eloquent chastisment

 

Message 17 of 25
mpropst
in reply to: caddzone

based on the drawings attached to the other reply...i'm trying to divide and conquer

so since each arc and each line have two intersections i'm trying to find the "close" one

given a pointlist (in this case of two points, but i think this allows any number of points) which point is closest to the arc (either to the startpoint or the end point)

i'm working on trying to test this and see if it works. but does the concept even look close?
 

 Private Function GetClosestIntersectionToOrigArc(ByVal ListOfPoints As Object, ByVal oarc As AcadArc) As Double()
    Dim arcstart As Point3d
    Dim arcEnd As Point3d
    Dim Testpoint As Point3d
    Dim NewPointList() As Double
    Dim NewStartPoint(0 To 2) As Double

    arcstart = DirectCast(oarc.StartPoint, Point3d)
    arcEnd = DirectCast(oarc.EndPoint, Point3d)


    NewPointList = CType(ListOfPoints, Double())


    'because IntersectWith can return multiple intersections we have to find which is closest to original arc
    'it's either closest to arcstart or arcend
    Dim i As Short
    Dim colPoints As New Collection

    'if the array isn't multiple of 3 we're hosed
    'collect individual points from the list
    For i = 0 To UBound(NewPointList) Step 3
      NewStartPoint(0) = NewPointList(i)
      NewStartPoint(1) = NewPointList(i + 1)
      NewStartPoint(2) = NewPointList(i + 2)
      colPoints.Add(NewStartPoint)

    Next
    Dim dTestDist As Double
    Dim currentClosePoint As Object = Nothing
    Dim dCurrentLeastDist As Double


    For i = 1 To colPoints.Count
      NewStartPoint = colPoints.Item(i)
      'convert to point3d so i can use .Distance
      Testpoint = DirectCast(DirectCast(NewStartPoint, Object), Point3d)

      If arcstart.DistanceTo(Testpoint) < arcEnd.DistanceTo(Testpoint) Then 'test point is close to start
        dTestDist = arcstart.DistanceTo(Testpoint)
        If dTestDist < dCurrentLeastDist Then
          dCurrentLeastDist = dTestDist
          currentClosePoint = DirectCast(Testpoint, Object)

        End If
      Else 'end is closer to testpoint
        dTestDist = arcEnd.DistanceTo(Testpoint)
        If dTestDist < dCurrentLeastDist Then
          dCurrentLeastDist = dTestDist
          currentClosePoint = DirectCast(Testpoint, Object)

        End If

      End If
    Next

    'cast object to double array
    Return DirectCast(currentClosePoint, Double())
  End Function

Message 18 of 25
caddzone
in reply to: mpropst

No, I would probably just replace the objects with new ones.



AcadXTabs for AutoCAD
Supporting AutoCAD 2000-2011


Message 19 of 25
mpropst
in reply to: caddzone

right but to replace or adjust existing i still need the same information (i think???),

i still have to figure out which intersection of the two is the right one for every combination. arc1 line1, arc1 line2, arc2 line1, arc 2 line2, each of which pair have two intersections.(8 points)

i dont' think i  can depend on it always being the first one in the returned list of points from IntersectWith.

 and i have to find out if the interseciton is start point or end point for the new arc or line (which i think means 8^2 combinations?)

 

perhaps you're saying, if i create new arc/line i can disregard direction of origninal arc(which is start and which is endpoint) - which would eliminate on level of testing...

 

in my present case that probably wouldn't matter but in some application it might?

Message 20 of 25
caddzone
in reply to: mpropst

Your problem doesn't entirely make sense, because you are starting with

a very specific set of objects (two concentric arcs and two lines that

pass through the center of the arcs).

 

If that is the constraint, you don't really need to figure out very much

at all.

 

Your problem is being complicated by the fact that you're using the

API to try to 'edit' existing objects when it is far easier to just replace

them with new objects using the parameters derived from the ones

being replaced.

 



AcadXTabs for AutoCAD
Supporting AutoCAD 2000-2011


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

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost