Is there a way to return Points in a circle?

Is there a way to return Points in a circle?

rampseeker
Advocate Advocate
925 Views
4 Replies
Message 1 of 5

Is there a way to return Points in a circle?

rampseeker
Advocate
Advocate

I want to select only the points within a certain circle among the points on a certain layer.

What I initially thought was to store all the x,y coordinates of the points and then loop through and inspect all the point data when a circle is selected.
  However, this method seems to become more inefficient as there are more points.
If there is any other way, I would appreciate it if you could let me know.

화면 캡처 2024-12-23 172028.png화면 캡처 2024-12-23 172615.png

0 Likes
926 Views
4 Replies
Replies (4)
Message 2 of 5

Domzinator
Advocate
Advocate

Here is Some code that i use in one of my plugins. In this example i just highlight the points you can change it to suite your needs:

 public static void SelectPointsInCircle()
 {
     Document doc = Application.DocumentManager.MdiActiveDocument;
     Editor ed = doc.Editor;
     Database db = doc.Database;

     try
     {
         // Prompt the user to select a circle
         PromptEntityOptions peo = new PromptEntityOptions("\nSelect a circle: ");
         peo.SetRejectMessage("\nThe selected object is not a circle.");
         peo.AddAllowedClass(typeof(Circle), false);
         PromptEntityResult per = ed.GetEntity(peo);

         if (per.Status != PromptStatus.OK) return;

         // Open the selected circle
         using (Transaction tr = db.TransactionManager.StartTransaction())
         {
             Circle circle = tr.GetObject(per.ObjectId, OpenMode.ForRead) as Circle;
             if (circle == null) return;

             Point3d center = circle.Center;
             double radius = circle.Radius;

             // Create a selection filter for Civil 3D points
             TypedValue[] filterList = new TypedValue[]
             {
                 new TypedValue((int)DxfCode.Start, "AECC_COGO_POINT")
             };
             SelectionFilter filter = new SelectionFilter(filterList);

             // Select all points in the drawing
             PromptSelectionResult psr = ed.SelectAll(filter);
             if (psr.Status != PromptStatus.OK)
             {
                 ed.WriteMessage("\nNo points found in the drawing.");
                 return;
             }

             SelectionSet selSet = psr.Value;
             ObjectIdCollection selectedPoints = new ObjectIdCollection();

             foreach (SelectedObject selObj in selSet)
             {
                 if (selObj != null)
                 {
                     CogoPoint point = tr.GetObject(selObj.ObjectId, OpenMode.ForRead) as CogoPoint;
                     if (point != null)
                     {
                         // Check if the point is within the circle
                         if (center.DistanceTo(point.Location) <= radius)
                         {
                             selectedPoints.Add(point.ObjectId);
                         }
                     }
                 }
             }

             // Highlight the selected points
             if (selectedPoints.Count > 0)
             {
                 foreach (ObjectId id in selectedPoints)
                 {
                     Entity entity = tr.GetObject(id, OpenMode.ForWrite) as Entity;
                     if (entity != null)
                     {
                         entity.Highlight();
                     }
                 }
                 ed.WriteMessage($"\n{selectedPoints.Count} points were selected within the circle.");
             }
             else
             {
                 ed.WriteMessage("\nNo points were found in the circle.");
             }

             tr.Commit();
         }
     }
     catch (System.Exception ex)
     {
         ed.WriteMessage($"\nError: {ex.Message}");
     }
 }
Civil 3D Certified Professional
Message 3 of 5

essam-salah
Advisor
Advisor

hi @rampseeker 

you can basically filter all points that lies inside a rectangle of P1/P2 by checking (or selecting) points with x,y > P1 and < P2 with simple math, then filter by the d <= r, where:
C = circle.CenterPoint
r = circle.Radius
P1.X = C.X - r
P1.Y = C.Y - r
P2.X = C.X + r
P2.Y = C.Y + r

d = distanceBetweeen(C, p)

 

note that the first filtering can be done by fence selection by 4 points of the rectangle of P1/P2

 

essamsalah_0-1735062887143.png

 

0 Likes
Message 4 of 5

rampseeker
Advocate
Advocate

Thank you so much for your reply! I initially thought it would be simple to select entities that touch or are contained within the circle, but after several days of searching, I realized there isn't a function for that. I also came to understand that the method you suggested seems to be the best approach. I really appreciate your help.

0 Likes
Message 5 of 5

rampseeker
Advocate
Advocate

  Initially, I tried to filter the data using the method you suggested, but the issue was that all the points had to be loaded for the function to work. I was hoping there might be a way to simply check if any points existed among the entities within the circle. However, after searching for a few days, I realized that wasn't possible. Thank you so much for your reply.

0 Likes