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'~
l'll try and figure how to use a c# class in a vbnet app.
the manual calcs are making me feel stupid
🙂
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
oh, thanks
Do you have a sample of it's use?
i'll search this group too.
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'~
thanks,
i'll study that and see what i can use
mark
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
I'm not responding to this because you chose the 'thousand words' rather than the picture.
one of my many defects
🙂
thankyou for such an eloquent chastisment
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
No, I would probably just replace the objects with new ones.
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.