Hello!
I want to get the entities (text) that are contained by a polyline. Any ideas?
Thanks!
The easiest way, if the drawing is open in AutoCAD editor, is to use Editor.SelectCrossingPolygon()/SelectWindowPolygon() with selection filter set to DBText and/or MText. Make sure before you call Editor.SelectCrossing/WindowPolygon you need to the polyline is entirely visible in the view.
You can also loop through all text entities in the Model/PaperSpace to see whether it is entirely or partially inside the polygon by using one of the known algorithms of testing if a point is inside polygon, which you can find by searching the web. For each text entity, you can get its bounding box, thus 4 corner points; then test each point, then you would know if the text entity is entirely or partially or not at all in the polygon.
Norman Yuan
try this.
public static bool IsPartialInside(Polyline poly, Entity ent) { try { //Quick scan based on Bounding Box if (ent.GeometricExtents.MinPoint.X > poly.GeometricExtents.MaxPoint.X) return false; if (ent.GeometricExtents.MinPoint.Y > poly.GeometricExtents.MaxPoint.Y) return false; if (ent.GeometricExtents.MinPoint.Z > poly.GeometricExtents.MaxPoint.Z) return false; if (ent.GeometricExtents.MaxPoint.X < poly.GeometricExtents.MinPoint.X) return false; if (ent.GeometricExtents.MaxPoint.Y < poly.GeometricExtents.MinPoint.Y) return false; if (ent.GeometricExtents.MaxPoint.Z < poly.GeometricExtents.MinPoint.Z) return false; Point3dCollection plPoints = AcadPolyTools.PolyToPoints(poly); Point3dCollection entPoints = GetBoundingPoints(ent); //add center of entity entPoints.Add(new Point3d( 0.5 * (ent.GeometricExtents.MinPoint.X + ent.GeometricExtents.MaxPoint.X), 0.5 * (ent.GeometricExtents.MinPoint.Y + ent.GeometricExtents.MaxPoint.Y), 0.5 * (ent.GeometricExtents.MinPoint.Z + ent.GeometricExtents.MaxPoint.Z))); foreach (Point3d point in entPoints) if (IsInside(plPoints, point)) return true; } catch ...
public static Point3dCollection GetBoundingPoints(Entity ent) { Point3dCollection contourPoints = new Point3dCollection(); //Note: argument may be virtual, i.e. not added to te database switch (ent.ObjectId.ObjectClass.DxfName) { case "LINE": Line line = (Line)ent; contourPoints.Add(line.StartPoint); contourPoints.Add(line.EndPoint); break; case "LWPOLYLINE": Polyline poly = (Polyline)ent; for (int i = 0; i < poly.NumberOfVertices - 1; i++) contourPoints.Add(poly.GetPoint3dAt(i)); break; case "TEXT": DBText text = (DBText)ent; if (text.Rotation == 0) { contourPoints.Add(ent.GeometricExtents.MinPoint); contourPoints.Add(new Point3d(ent.GeometricExtents.MaxPoint.X, ent.GeometricExtents.MinPoint.Y, 0)); contourPoints.Add(ent.GeometricExtents.MaxPoint); contourPoints.Add(new Point3d(ent.GeometricExtents.MinPoint.X, ent.GeometricExtents.MaxPoint.Y, 0)); } else { using (DBText tmpText = (DBText)text.Clone()) { tmpText.AdjustAlignment(text.Database); double textRot = tmpText.Rotation; tmpText.TransformBy(Matrix3d.Rotation(-textRot, Vector3d.ZAxis, tmpText.Position)); var tmpPoly = ExtentsToPoly(tmpText); tmpPoly.TransformBy(Matrix3d.Rotation(textRot, Vector3d.ZAxis, text.Position)); ////Debug //using (Transaction tr = text.Database.TransactionManager.TopTransaction) //{ // BlockTable bt = (BlockTable)tr.GetObject(text.Database.BlockTableId, OpenMode.ForRead); // BlockTableRecord ms = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite); // ms.AppendEntity(tmpPoly); // tr.AddNewlyCreatedDBObject(tmpPoly, true); //} foreach (Point3d tmpPnt in AcadPolyTools.PolyToPoints(tmpPoly)) contourPoints.Add(tmpPnt); } } break; case "MTEXT": MText mtext = (MText)ent; //GetBoundingPoints are not in the correct order var mtBB = mtext.GetBoundingPoints(); contourPoints.Add(mtBB[2]); contourPoints.Add(mtBB[3]); contourPoints.Add(mtBB[1]); contourPoints.Add(mtBB[0]); break; case "INSERT": BlockReference blkRef = (BlockReference)ent; if (blkRef.Rotation == 0) { contourPoints.Add(ent.GeometricExtents.MinPoint); contourPoints.Add(new Point3d(ent.GeometricExtents.MaxPoint.X, ent.GeometricExtents.MinPoint.Y, 0)); contourPoints.Add(ent.GeometricExtents.MaxPoint); contourPoints.Add(new Point3d(ent.GeometricExtents.MinPoint.X, ent.GeometricExtents.MaxPoint.Y, 0)); } else { using (BlockReference tmpBlkRef = (BlockReference)blkRef.Clone()) { tmpBlkRef.Rotation = 0; tmpBlkRef.ScaleFactors = new Scale3d(1); tmpBlkRef.Position = Point3d.Origin; Matrix3d blkTrf = Matrix3d.Scaling(blkRef.ScaleFactors[0], blkRef.Position).PostMultiplyBy(Matrix3d.Rotation(blkRef.Rotation, Vector3d.ZAxis, blkRef.Position)).PostMultiplyBy(Matrix3d.Displacement(Point3d.Origin.GetVectorTo(blkRef.Position))); Point3d tmpBlkRefMinPoint = tmpBlkRef.GeometricExtents.MinPoint.TransformBy(blkTrf); Point3d tmpBlkRefMaxPoint = tmpBlkRef.GeometricExtents.MaxPoint.TransformBy(blkTrf); contourPoints.Add(tmpBlkRefMinPoint); contourPoints.Add(new Point3d(tmpBlkRefMaxPoint.X, tmpBlkRefMinPoint.Y, 0)); contourPoints.Add(tmpBlkRefMaxPoint); contourPoints.Add(new Point3d(tmpBlkRefMinPoint.X, tmpBlkRefMaxPoint.Y, 0)); } } break; default: contourPoints.Add(ent.GeometricExtents.MinPoint); contourPoints.Add(new Point3d(ent.GeometricExtents.MaxPoint.X, ent.GeometricExtents.MinPoint.Y, 0)); contourPoints.Add(ent.GeometricExtents.MaxPoint); contourPoints.Add(new Point3d(ent.GeometricExtents.MinPoint.X, ent.GeometricExtents.MaxPoint.Y, 0)); break; } return contourPoints; }
public static bool IsInside(Point3dCollection polyPoint, Point3d pnt) { int i, j = polyPoint.Count - 1; bool oddNodes = false; for (i = 0; i < polyPoint.Count; i++) { Point3d pi = polyPoint[i]; Point3d pj = polyPoint[j]; //quicker for large number of points to test, but need Init procedure for Multiple[] and Constant[] //if ((pi.Y < pnt.Y && pj.Y >= pnt.Y || pj.Y < pnt.Y && pi.Y >= pnt.Y)) // oddNodes ^= (pnt.Y * Multiple[i] + Constant[i] < pnt.X); if ((pi.Y < pnt.Y && pj.Y >= pnt.Y || pj.Y < pnt.Y && pi.Y >= pnt.Y) && (pi.X <= pnt.X || pj.X <= pnt.X)) oddNodes ^= (pi.X + (pnt.Y - pi.Y) / (pj.Y - pi.Y) * (pj.X - pi.X) < pnt.X); j = i; } return oddNodes; }