i am creating a custom program to deal with stage storage in civil 3d by using volumes from water surfaces based on extracted contours and all that good stuff.
however i am having some problem with internal islands.
i add the water elevation contour as breakline then add main big surface boundary as hide then contours polyline as show. i added all the contours ones as show which for the island case will not work.
so i need some code to test the relationships between polylines.
first i need to get the largest area polyline this i can do. then for each subsequent polylines i need to see if it is inside of the big one. if it's inside bit one it is an island that needs to be added as a hide boundary in the end after the show is added. and if the polylines is outside of the main big polyline it just is another little pond.
i hate my job. last program i will make.
i am using vb.net with mixture of com and .net. mostly com for civil 3d and some .net for autocad stuff. so this one can be both .net or com or even give me code in c# i'll convert it online works good. something with the intersectwith or something function. something to do with centroid? no idea.
so yeah thanks guys for your help.
Solved! Go to Solution.
Solved by peterfunkautodesk. Go to Solution.
There are ways to do this looking at all the points, but here might be a simple way...
1. Turn the two polylines into AutoCAD regions (but don't add them to the drawing).
2. Union the regions. If the area of the union is the same as the area of the first, then the second is inside it. If the area is bigger, then the area is outside of it.
3. Subtract the regions. If the area is the same, then the second is outside of the first.
4. If the area of the union and the area of the intersect are both different, then the two regions intersect.
Cheers,
Peter Funk
Autodesk, Inc.
thanks Peter. this method works perfectly.
For those who want some code ready to go: here is some.
Here's how it works:
if so the answer is true.
Here is the code to help you:
public static bool IsP1CollectionWithinP2Collection(List<Point3d> p1Collection, List<Point3d> p2Collection) { foreach (Point3d p in p1Collection) { if (BlockUtility.IsPointInPolygon(p2Collection, p)) { } else { return false; } } return true; }
class BlockUtility { public static bool IsPointInPolygon(List<Point3d> polygon, Point3d point) { bool isInside = false; for (int i = 0, j = polygon.Count - 1; i < polygon.Count; j = i++) { if (((polygon[i].Y > point.Y) != (polygon[j].Y > point.Y)) && (point.X < (polygon[j].X - polygon[i].X) * (point.Y - polygon[i].Y) / (polygon[j].Y - polygon[i].Y) + polygon[i].X)) { isInside = !isInside; } } return isInside; } }
private System.Collections.Generic.List<Point3d> GetPanelPoints() { List<Point3d> panel_points = new List<Point3d>(); Document doc = Application.DocumentManager.MdiActiveDocument; Editor ed = doc.Editor; Database db = doc.Database; using (Transaction tr = db.TransactionManager.StartTransaction()) { Polyline pl = tr.GetObject(panelLineID, OpenMode.ForRead) as Polyline; //Polyline pl = panelLineID; int vn = pl.NumberOfVertices; for (int i = 0; i < vn; i++) { // Could also get the 3D point here Point3d pt = pl.GetPoint3dAt(i); panel_points.Add(pt); } } return panel_points; }
you'd have to get access to the two polylines. pl1 and pl2 is what we will call them some thing like this List<Point3d> firstPolyline = GetPanelPoints(pl1) List<Point3d> secondPolyline = GetPanelPoints(pl2) if (PointsUtility.IsP1CollectionWithinP2Collection(pointsOfRandomPolyline, _panelPoints)) { // you get your answer }
First get all the points associated with the two polylines.
then ask the question: are all the points associated with the first polyline contained within the second?
if so the answer is true.
That's assuming the polylines don't contain curves, which they can.