Hi there is there a method to detect if an object is in side of the object. Please look at the picture.
Kind regards,
Irvin
Here's the process I'd use:
Could anyone help me with a code sample?
The things i need to cheak are clear to me. But i have no idea of how to implement it.
Kind regards,
Irvin
// Called Kerry in my other life.
Everything will work just as you expect it to, unless your expectations are incorrect.
class keyThumper<T> : Lazy<T>; another Swamper
Hi Irvin,
The question if any object is within another object is var more difficult then the question if one rectangle is within the other !
.NET does have some build in features but i haven't used these yet.
The general solution goes like this (hope you can read VB style code).
For a rectangle you can use the getboundary information returning object.GetBoundingBox minPoint, maxPoint
and then for any point of the other object you can test if inside the rectangle
Public Function IsInside2DBox(...)
if thePoint(0) <minPoint(0) then exit 'outside
if thePoint(1) <minPoint(1) then exit 'outside
if thePoint(0) >maxPoint(0) then exit 'outside
if thePoint(1) >maxPoint(1) then exit 'outside
IsInside2DBox = True
For a irrecular shaped boundary you have to test for inside (2D) polyline. As said this is a bit more complicated and there are some restrictions such as the 2D boundary may not cross itself like a bowty
Public Function IsInside2DPolyline(xyPoly ...
inside = False
xOld = xyPoly(UBound(xyPoly) - 1)
yOld = xyPoly(UBound(xyPoly))
For i = LBound(xyPoly) To UBound(xyPoly) - 1 Step 2
xNew = xyPoly(i)
yNew = xyPoly(i + 1)
If xNew > xOld Then
x1 = xOld
y1 = yOld
x2 = xNew
y2 = yNew
Else
x1 = xNew
y1 = yNew
x2 = xOld
y2 = yOld
End If
If (xNew < xPnt) = (xPnt <= xOld) And _
((yPnt - y1) * (x2 - x1)) < ((y2 - y1) * (xPnt - x1)) Then
inside = Not inside
End If
xOld = xNew
yOld = yNew
Next
IsInside2DPolyline = inside
Hi Irvin,
Provided code is working with polygons
that has a straight segments only
My bad, have forgot you use vb.net, I wrote
code completely on C#, ugh 🙂
I haven't a time to translate it on VB.Net
Tryit by yourself
Hope that helps,
Oleg
~'J'~
/// <summary> /// Point-In-Polygon Algorithm © 1998,2006,2007 Darel Rex Finley /// working with straight segments ony! /// http://alienryderflex.com/polygon/ /// The function will return YES if the point x,y is inside the polygon, or /// NO if it is not. If the point is exactly on the edge of the polygon, /// then the function may return YES or NO. /// Note that division by zero is avoided because the division is protected /// by the "if" clause which surrounds it. /// </summary> /// <param name="polySides"></param> /// <param name="polyX"></param> /// <param name="polyY"></param> /// <param name="p"></param> /// <returns></returns> public static bool pointInPolygon(int polySides, double[] polyX, double[] polyY, Point2d p) { int i, j = polySides - 1; bool oddNodes = false; double x = p.X; double y = p.Y; for (i = 0; i < polySides; i++) { if ((polyY[i] < y && polyY[j] >= y) || (polyY[j] < y && polyY[i] >= y)) { if (polyX[i] + (y - polyY[i]) / (polyY[j] - polyY[i]) * (polyX[j] - polyX[i]) < x) { oddNodes = !oddNodes; } } j = i; } return oddNodes; } /// <summary> /// by Gilles Chanteau ()2010 /// </summary> /// <param name="idCol"></param> private static void ZoomObjects(ObjectIdCollection idCol) { Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; using (Transaction tr = db.TransactionManager.StartTransaction()) using (ViewTableRecord view = ed.GetCurrentView()) { Matrix3d WCS2DCS = Matrix3d.PlaneToWorld(view.ViewDirection); WCS2DCS = Matrix3d.Displacement(view.Target - Point3d.Origin) * WCS2DCS; WCS2DCS = Matrix3d.Rotation(-view.ViewTwist, view.ViewDirection, view.Target) * WCS2DCS; WCS2DCS = WCS2DCS.Inverse(); Entity ent = (Entity)tr.GetObject(idCol[0], OpenMode.ForRead); Extents3d ext = ent.GeometricExtents; for (int i = 1; i < idCol.Count; i++) { ent = (Entity)tr.GetObject(idCol[i], OpenMode.ForRead); Extents3d tmp = ent.GeometricExtents; ext.AddExtents(tmp); } ext.TransformBy(WCS2DCS); view.Width = ext.MaxPoint.X - ext.MinPoint.X; view.Height = ext.MaxPoint.Y - ext.MinPoint.Y; view.CenterPoint = new Point2d((ext.MaxPoint.X + ext.MinPoint.X) / 2.0, (ext.MaxPoint.Y + ext.MinPoint.Y) / 2.0); ed.SetCurrentView(view); tr.Commit(); } } /// <summary> /// test for multiple shapes inside a straight-segmented polygon (partially borrowed from Kean Walmsley) /// </summary> [CommandMethod("MultiPoly", CommandFlags.UsePickSet | CommandFlags.Redraw | CommandFlags.Modal)] public static void testIfShapeInside() { Database db = HostApplicationServices.WorkingDatabase; Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Editor ed = doc.Editor; DocumentLock docloc = doc.LockDocument(); using(docloc) { Transaction tr = db.TransactionManager.StartTransaction(); using (tr) { try { PromptEntityOptions peo = new PromptEntityOptions("\nSelect a boundary polygon >>"); peo.SetRejectMessage("\nSelect Polyline only >>"); peo.AddAllowedClass(typeof(Polyline), false); PromptEntityResult res; res = ed.GetEntity(peo); if (res.Status != PromptStatus.OK) return; Entity ent = (Entity)tr.GetObject(res.ObjectId, OpenMode.ForRead); if (ent == null) return; ObjectId chkId = ent.ObjectId; ZoomObjects(new ObjectIdCollection() { chkId }); Point3dCollection pts = new Point3dCollection(); Polyline poly = (Polyline)ent as Polyline; if (poly != null) { int num = poly.NumberOfVertices; double[] polyX = new double[num]; double[] polyY = new double[num]; for (int i = 0; i < num; i++) { Point2d p = poly.GetPoint2dAt(i); polyX[i] = p.X; polyY[i] = p.Y; pts.Add(poly.GetPointAtParameter((double)i)); } TypedValue[] filList = new TypedValue[2] {new TypedValue((int)DxfCode.Start, "LWPOLYLINE"),new TypedValue(70, 1) }; SelectionFilter filter = new SelectionFilter(filList); PromptSelectionResult sres = ed.SelectCrossingPolygon(pts, filter); // Do nothing if selection is unsuccessful if (sres.Status != PromptStatus.OK) return; SelectionSet selSet = sres.Value; ObjectId[] ids = selSet.GetObjectIds(); for (int i = 0; i < ids.Length; i++) { if ((ObjectId)ids[i] != chkId)//exclude a boundary from selection { poly = (Polyline)tr.GetObject(ids[i], OpenMode.ForRead); int vnum = poly.NumberOfVertices; bool isInside = true; for (int j = 0; j < vnum; j++) { Point2d p = poly.GetPoint2dAt(j); // isInside = pointInPolygon(num, polyX, polyY, p); if (!isInside) { poly.UpgradeOpen(); poly.ColorIndex = 3; poly.DowngradeOpen(); break; } } } }// } tr.Commit(); } catch (System.Exception ex) { ed.WriteMessage("{0}\n{1}", ex.Message, ex.StackTrace); } }//tr } } /// <summary> /// test is point inside a straight-segmented polygon(partially borrowed from Kean Walmsley) /// </summary> [CommandMethod("SinglePoint", CommandFlags.UsePickSet | CommandFlags.Modal)] public static void testInside() { Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; using (Transaction tr = db.TransactionManager.StartTransaction()) { PromptPointOptions prOpt = new PromptPointOptions("\nSpecify a point: "); PromptPointResult es = ed.GetPoint(prOpt); if (es.Status != PromptStatus.OK) { if (es.Status == PromptStatus.Cancel) { ed.WriteMessage("\nInterrupted by user. Exit.."); return; } else { ed.WriteMessage("\nError on specifying a point.Exit..."); return; } } Point2d pt = new Point2d(es.Value.X, es.Value.Y); PromptEntityOptions peo = new PromptEntityOptions("\nSelect a bounds polygon >>"); peo.SetRejectMessage("\nSelect Polyline only >>"); peo.AddAllowedClass(typeof(Polyline),false); PromptEntityResult res; res = ed.GetEntity(peo); if (res.Status != PromptStatus.OK) return; Entity ent = (Entity)tr.GetObject(res.ObjectId, OpenMode.ForRead); if (ent == null) return; Polyline poly = (Polyline)ent as Polyline; if (poly != null) { int num = poly.NumberOfVertices; double[] polyX = new double[num]; double[] polyY = new double[num]; for (int i = 0; i < num; i++) { Point2d p = poly.GetPoint2dAt(i); polyX[i] = p.X; polyY[i] = p.Y; } bool isInside = pointInPolygon(num, polyX, polyY, pt); ed.WriteMessage("\nIs point inside?\t{0}", isInside); } tr.Commit(); } }
Does anyone happen to have Hallex's code in VB? I am having a heck of a time trying to convert it. None of the converters I use are working. Or maybe point me to a converter that will convert this without errors?
I am trying to do something similar to the OP and I think this will be a great start!
TIA!
What was the error?
http://www.developerfusion.com/tools/convert/csharp-to-vb/
The converters I was using would error out on differing lines of code with the explanation of "Error on line XX"
The one you linked works great! I think I will use that one in the future!
Thanks!