Please see the attachment first
I want to create a command which has a effect,
First, the user is prompted to select the line,
Second, the program execute and determine, find the key points
Finally, fix this line, let the distance from the right end point of line to circleis right just 1.
If there is no solution, then the situation becomes simpler, only the case2: the line connect the circle, perhaps easier
Note: The line and the circle in different layer
I have this idea, but do not know how to make it true, is there anyone has some suggestion?
Sample code is my favorite.
Sincere thanks
Solved! Go to Solution.
Solved by SENL1362. Go to Solution.
Start studying the Selection functions. There are piles of examples.
Search for ed.GetEntity, ed.GetSelection, ed.Select
Yes, I know how to use GetSelection() to get LineObject and the endpoint of LineObject,
But I am thinking of how to let the program know which of endpoints distance more closer to the circle by select the line only, the circle isn’t be selected.
It’s meanI have knew how to access the property of this line, but now my question is there some way will be able to determine which one of the endpoints more distance closer to the circle only by select this line
The program can try or search the near entity of this line, it’s just like a radiolocator..
Uh, I don't want to select anyting except the line, so the question becomes more complicated
If there is some method can only rely on the selected line, then the program automatically sacnning the near entity of the line just like a radiolocator, and then determine which endpoint is more closer to the specific entity, It’s will be a prefect way…
You already knew the selection methodes, so time to show you alternatives:
Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; using (Transaction tr = db.TransactionManager.StartTransaction()) { BlockTable bt = (BlockTable)db.BlockTableId.GetObject(OpenMode.ForRead); BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite); BlockTableRecord ptr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.PaperSpace], OpenMode.ForRead); BlockTableRecord mtr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead); IEnumerable<ObjectId> myEnumerable = mtr.Cast<ObjectId>(); List<ObjectId> modelObjectIds = myEnumerable.ToList(); ed.WriteMessage("\n{0} Number of Modelspace entities", modelObjectIDs.Count); //All Lines or Polylines List<ObjectId> entIDs = modelObjectIds.Where(id => id.ObjectClass.DxfName.ToUpper() == "LINE" || id.ObjectClass.DxfName.ToUpper() == "LWPOLYLINE").ToList<ObjectId>(); foreach (ObjectId entID in entIDs) { Entity theEnt = (Entity)trans.GetObject(entID, OpenMode.ForRead); ed.WriteMessage("\n" + entID.ObjectClass.DxfName + ", " + theEnt.GetType().ToString() + ", " + theEnt.Handle.ToString() + ", " + theEnt.Layer.ToString()); } tr.Commit(); }
Youre circles can be listed using the following:
List<ObjectId> theCircles = modelObjectIds.Where(id => id.ObjectClass.DxfName.ToUpper() == "CIRCLE"
Then distances of the endpoints of the selected line to the circle.Centre - the circle.Radius.
Ah, I think, in fact, I just need to get the intersection of two objects,
First, select the first object only and then use SelectCrossingPolygon () or other methods get the selectsets, then step though the selectsets ,then get the second specified object, and then get their intersection point
But, how to get a intersection point between a line with another object, or the intersection point of the extension cord?
Which class privide a method get the intersection point between object?
Did you know?
Very Thanks.
This may get you on track
using System; using System.Collections.Generic; using System.Text; using System.Text.RegularExpressions; using System.IO; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.Runtime; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.Geometry; namespace line2Circle { public class Class1 { [CommandMethod("l2c")] public void LineTwoCircle() { Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; using (Transaction tr = db.TransactionManager.StartTransaction()) { BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); BlockTableRecord ms = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite); PromptEntityOptions promptForLine = new PromptEntityOptions("\nSelect the Line:"); promptForLine.SetRejectMessage("Lines only"); promptForLine.AddAllowedClass(typeof(Line), true); PromptEntityResult getLineRes = ed.GetEntity(promptForLine); if (getLineRes.Status != PromptStatus.OK) return; Line ln = (Line)tr.GetObject(getLineRes.ObjectId, OpenMode.ForRead); ed.WriteMessage("\nLine: {0}..{1}", ln.StartPoint, ln.EndPoint); PromptEntityOptions promptForCircle = new PromptEntityOptions("\nSelect a Circle:"); promptForLine.SetRejectMessage("Circles only"); promptForLine.AddAllowedClass(typeof(Circle), true); PromptEntityResult getCircleRes = ed.GetEntity(promptForCircle); if (getCircleRes.Status != PromptStatus.OK) return; Circle cir = (Circle)tr.GetObject(getCircleRes.ObjectId, OpenMode.ForRead); ed.WriteMessage("\nCircle: {0},{1}", cir.Center,cir.Radius); Circle tmpCircle = new Circle(cir.Center, new Vector3d(0,0,1),cir.Radius + 1); tmpCircle.SetDatabaseDefaults(db); ms.AppendEntity(tmpCircle); tr.AddNewlyCreatedDBObject(tmpCircle, true); Point3dCollection interSections = new Point3dCollection(); ln.IntersectWith(tmpCircle, Intersect.ExtendThis, interSections, 0, 0); if (interSections.Count < 0) { ed.WriteMessage("\nFault: Line does not intersect with this circle"); } else { for (int i = 0; i < interSections.Count; i++) ed.WriteMessage("\nIntersection[{0}={1}", i, interSections[i]); if (ln.StartPoint.DistanceTo(interSections[0]) < ln.EndPoint.DistanceTo(interSections[0])) ln.ReverseCurve(); Point3d peNew = interSections[0]; if (ln.StartPoint.DistanceTo(peNew) > ln.StartPoint.DistanceTo(interSections[1])) peNew = interSections[1]; //Next lines modify the source line. //ln.UpgradeOpen(); //ln.EndPoint = peNew; //for debug mode w'll create a new (Temporary) line Line tmpLn = new Line(ln.StartPoint, peNew); tmpLn.SetDatabaseDefaults(db); ms.AppendEntity(tmpLn); tr.AddNewlyCreatedDBObject(tmpLn, true); } //double dX = ln.EndPoint.X - ln.StartPoint.X; //double dY = ln.EndPoint.Y - ln.StartPoint.Y; //Point3d ps = cir.Center; //double xPe=cir.Center.X-dY; //double yPe=cir.Center.Y+dX; //Point3d pe = new Point3d(xPe, yPe, cir.Center.Z); //Line lnPp = new Line(ps, pe); //lnPp.SetDatabaseDefaults(db); //ms.AppendEntity(lnPp); //tr.AddNewlyCreatedDBObject(lnPp, true); //Point3dCollection interSections = new Point3dCollection(); //ln.IntersectWith(lnPp, Intersect.ExtendBoth, interSections, 0,0); //ed.WriteMessage("\n Intersection={0}", interSections[0]); //lnPp.EndPoint = interSections[0]; //if (lnPp.Length > cir.Radius) // ed.WriteMessage("\nNo intersection with the Circle"); //else if (lnPp.Length < cir.Radius) // ed.WriteMessage("\nTwo intersection with the Circle"); //else // ed.WriteMessage("\nOne exact intersection with the Circle"); tr.Commit(); } } } }
Yes, I solved it by this Message from this Form as you said:
Measure perpendicular distance between 2 polylines
Very thanks
Can't find what you're looking for? Ask the community or share your knowledge.