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).
Try CommandLine class from there:
http://www.caddzone.com/CommandLine.cs
it's likes me more 🙂
~'J'~
Sorry, I don't knew that you use VB.NET
Try handle this class instead:
http://www.caddzone.com/CommandLine.vb
~'J'~
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
I have already wrote similar one few moons ago
Still searching in my codes but with no luck yet 😞
~'J'~
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'~
Use this tools to convert the code:
I haven't have a time now, so sorry
~'J'~
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'~
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
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
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?
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.
Can't find what you're looking for? Ask the community or share your knowledge.