.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to detect wether an retangle or closed pline is inside another.

12 REPLIES 12
Reply
Message 1 of 13
Irvin
1417 Views, 12 Replies

How to detect wether an retangle or closed pline is inside another.

Hi there is there a method to detect if an object is in side of the object. Please look at the picture.

 

ForumImage.png

 

 

Kind regards,

 

Irvin

12 REPLIES 12
Message 2 of 13
Anonymous
in reply to: Irvin

Here's the process I'd use:

 

  1. Test if the bounding boxes intersect. (If not, then red can't be inside green.)
  2. Test if the two end points of the red line are within the green shape.  (If not, then red is not entirely within green.)
  3. Test if the red line intersects any of the lines that make up the green shape.  (If so, then red is not entirely within green.)

 

Message 3 of 13
Irvin
in reply to: Irvin

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

Message 4 of 13
kdub_nz
in reply to: Irvin

Actually, the solution is simpler than krugerm indicated. For both red and Yellow, Test for intersection with Green .. if true , return failure If Sucess, Test if one vertex is inside green, If so possible sucess. An anomolie could be if green is inside red or yellow, but you could handle that in a similar manner

// 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

Message 5 of 13
Irvin
in reply to: Irvin

Please tell me how to check if one and other intersects.

 

Anybody got a sample?

Message 6 of 13
kdub_nz
in reply to: Irvin

Sorry, no I don't have a sample. Have you tried to code a solution ?

// 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

Message 7 of 13
Anonymous
in reply to: Irvin

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
   

 

 

 

 

Message 8 of 13
Hallex
in reply to: Irvin

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();
            }
    
}

 

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 9 of 13
Irvin
in reply to: Irvin

Thanks Hallex,

 

Im a c# programmer (Learning is a work in progress)

 

Kind regards,

 

Irvin

Message 10 of 13
Hallex
in reply to: Irvin

Anyway,

 

See you

 

~'J'~

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 11 of 13
Rob.O
in reply to: Hallex

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!

Message 12 of 13
arcticad
in reply to: Rob.O

What was the error?

http://www.developerfusion.com/tools/convert/csharp-to-vb/

---------------------------



(defun botsbuildbots() (botsbuildbots))
Message 13 of 13
Rob.O
in reply to: arcticad

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!

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost