Example #1
0
        private Point FindBestNeighbour(Point point, int index)
        {
            Point  bestNeighbour = point;
            double area          = BoundaryPolygon.Area();

            for (int x = -1; x < 2; x++)
            {
                for (int y = -1; y < 2; y++)
                {
                    Point   neighbour = new Point(point.X + x, point.Y + y);
                    Polygon copy      = new Polygon(BoundaryPolygon);
                    if (!copy.Vertices.Any(v => v.Equals(neighbour)))
                    {
                        copy.ExchangeVertexAt(index, neighbour);
                        double ar = copy.Area();
                        if (0 < ar && ar < area && copy.IsPolygon() && copy.Encloses(PointsToEnclose))
                        {
                            if (copy.Encloses(PointsToEnclose))
                            {
                                bestNeighbour = neighbour;
                                area          = copy.Area();
                            }
                        }
                    }
                }
            }

            return(bestNeighbour);
        }
Example #2
0
        /*
         * This routine is used to invert the hole points, specifically the 'Y' points.
         * The html canvas has 0,0 at the upper left and 'Y' goes down. For the holegroup canvas
         * we want a 'Y' that goes up, because that's how the holes are overlaid and appear in
         * three dimensions, and how we think of them intuitively. To manage this we'll simply flip the
         * Y points for the duration of the time that they are being edited and reflip them when its time to save
         */
        public void InvertHolePoints()
        {
            for (int i = 0; i < HoleGroupList.Count; i++)
            {
                HoleGroup hg = HoleGroupList.GetFrom(i);

                for (int j = 0; j < hg.HoleList.Length; j++)
                {
                    /*
                     * For all hole types the offset Y is inverted
                     */
                    LayoutHole oHole = hg.HoleList[j];
                    oHole.OffsetY = -oHole.OffsetY;

                    /*
                     * For polygon hole types the individual Y's are inverted
                     */
                    if (oHole.HoleType == "poly")
                    {
                        BoundaryPolygon oPolygon = BoundaryPolygonList.GetFrom(oHole.HoleTypeIndex);
                        for (int k = 0; k < oPolygon.PointList.Length; k++)
                        {
                            Point3D p = oPolygon.PointList[k];
                            p.Y = -p.Y;
                        }
                    }
                }
            }
        }
Example #3
0
        public void FindSmallestBoundaryPolygon(List <Point> points)
        {
            int step = 0;

            PointsToEnclose = points;

            int  vertices  = BoundaryPolygon.Vertices.Count;
            bool developed = true;

            while (developed)
            {
                developed = false;
                for (int v = 0; v < vertices; v++)
                {
                    step++;
                    Point vertex        = BoundaryPolygon.Vertices.ElementAt(v);
                    Point bestNeighbour = FindBestNeighbour(vertex, v);

                    if (!vertex.Equals(bestNeighbour))
                    {
                        BoundaryPolygon.ExchangeVertexAt(v, bestNeighbour);
                        //v--;
                        developed = true;

                        Thread.Sleep(5);
                        UpdateUI?.Invoke(this, new HillClimbingEventArgs(new Polygon(BoundaryPolygon)));
                    }
                }
            }
        }
        //------------------------------------------------------
        private void DrawShapes_Polygon(LayoutHole oHole, bool IsCurrentHole)
        {
            BoundaryPolygon bp = BoundaryPolygonList.GetFrom(oHole.HoleTypeIndex);

            PointF ScreenOffset = this.W2S(oHole.OffsetX, oHole.OffsetY);

            for (int i = 0; i < bp.PointList.Length; i++)
            {
                int FromIndex = i;
                int ToIndex   = i + 1;
                if (ToIndex == bp.PointList.Length)
                {
                    ToIndex = 0;                                 // Wrap at end
                }
                Point3D FromPoint = bp.PointList[FromIndex];

                float fdx = FromPoint.X / CurrentZoom;
                float fdy = FromPoint.Y / CurrentZoom;

                Point3D ToPoint = bp.PointList[ToIndex];

                float tdx = ToPoint.X / CurrentZoom;
                float tdy = ToPoint.Y / CurrentZoom;

                PointF ScreenFrom = new PointF(ScreenOffset.X + fdx, ScreenOffset.Y + fdy);
                PointF ScreenTo   = new PointF(ScreenOffset.X + tdx, ScreenOffset.Y + tdy);

                // Draw handles
                string color = "rgba(255,0,0,.5)";
                if (IsCurrentHole && i == MostRecentlySelectedPolygonVertexIndex)
                {
                    color = "#0000FF";
                }
                this.DrawCircle(color, 10, ScreenFrom.X, ScreenFrom.Y);

                PointF oCenter = EdgeCenter(ScreenFrom, ScreenTo);
                // Draw the handle for the edge
                color = "rgba(0,255,0,.5)";
                if (IsCurrentHole && i == MostRecentlySelectedPolygonEdgeIndex)
                {
                    color = "#0000FF";
                }
                this.DrawRectangle(color, 10, 10, oCenter.X, oCenter.Y);

                // Draw Line
                this.DrawLine(ShapeStrokeColor, (float)0.5, ScreenFrom, ScreenTo);

                // Draw the move handle
                PointF oMove = PolygonCenter(bp);
                float  mdx   = oMove.X / CurrentZoom;
                float  mdy   = oMove.Y / CurrentZoom;

                oMove = new PointF(ScreenOffset.X + mdx, ScreenOffset.Y + mdy);
                color = IsCurrentHole ? "#0000FF" : "rgba(255,0,0,.5)";

                // Draw the move handle
                this.DrawCircle(color, 10, oMove.X, oMove.Y);
            }
        }
Example #5
0
        // If the cur
        public void SplitCurrentPolygonEdge()
        {
            if (MostRecentlySelectedHole == null)
            {
                return;
            }

            if (MostRecentlySelectedHole.HoleType != "poly")
            {
                return;
            }

            if (MostRecentlySelectedPolygonEdgeIndex == -1)
            {
                return;
            }

            BoundaryPolygon oPolygon = BoundaryPolygonList.GetFrom(MostRecentlySelectedHole.HoleTypeIndex);

            /*
             * Locate this edge and create a new point in between the surrounding points
             */
            int FromIndex = MostRecentlySelectedPolygonEdgeIndex;
            int ToIndex   = FromIndex + 1;

            if (ToIndex == oPolygon.PointList.Length)
            {
                ToIndex = 0;
            }

            Point3D FromPoint = oPolygon.PointList[FromIndex];
            Point3D ToPoint   = oPolygon.PointList[ToIndex];

            PointF pF = new PointF(FromPoint.X, FromPoint.Y);
            PointF pT = new PointF(ToPoint.X, ToPoint.Y);

            PointF oCenter = EdgeCenter(pF, pT);

            Point3D pNew = new Point3D();

            pNew.X = oCenter.X;
            pNew.Y = oCenter.Y;
#if DOTNET
            List <Point3D> tmp = new List <Point3D>(oPolygon.PointList);
            tmp.Insert(FromIndex + 1, pNew);
            oPolygon.PointList = tmp.ToArray();
#else
            oPolygon.PointList.splice(FromIndex + 1, 0, pNew);
#endif



            // trigger repaint
            DrawShapes();
        }
Example #6
0
        // Add a polygon. This is managed with a simplelayout object
        public void AddPolygon(int ScreenOffsetX, int ScreenOffsetY, int InitialSides, int Radius)
        {
            if (MostRecentlySelectedHoleGroup == null)
            {
                return;
            }

            BoundaryPolygon oPolygon = new BoundaryPolygon();

            oPolygon.PointList = new Point3D[InitialSides];

            float Angle      = 0;
            float AngleDelta = (float)Math.PI * 2 / InitialSides;

            for (int i = 0; i < InitialSides; i++)
            {
                Point3D p = new Point3D();
#if DOTNET
                float x = (float)Math.Cos(Angle) * Radius;
                float y = (float)Math.Sin(Angle) * Radius;
#else
                float x = (float)Math.cos(Angle) * Radius;
                float y = (float)Math.sin(Angle) * Radius;
#endif
                p.X = x;
                p.Y = y;

                oPolygon.PointList[i] = p;

                Angle += AngleDelta;
            }

            /*
             * Create a hole and boundary polygon object
             */
            PointF     WorldOffset = this.S2W(ScreenOffsetX, ScreenOffsetY);
            LayoutHole oHole       = new LayoutHole();
            oHole.HoleType      = "poly";
            oHole.HoleTypeIndex = BoundaryPolygonList.Count;
            oHole.OffsetX       = WorldOffset.X;
            oHole.OffsetY       = WorldOffset.Y;

            AddHoleToHoleGroup(MostRecentlySelectedHoleGroup, oHole);

            CurrentlySelectedHole    = oHole;
            MostRecentlySelectedHole = oHole;

            BoundaryPolygonList.Add(oPolygon);

            // trigger redraw

            DrawShapes();
        }
Example #7
0
        private PointF PolygonCenter(BoundaryPolygon oPolygon)
        {
            float x = 0;
            float y = 0;

            for (int i = 0; i < oPolygon.PointList.Length; i++)
            {
                Point3D p = oPolygon.PointList[i];
                x += p.X;
                y += p.Y;
            }

            PointF oCenter = new PointF(x / oPolygon.PointList.Length, y / oPolygon.PointList.Length);

            return(oCenter);
        }
        public void DuplicateCurrentHole()
        {
            if (MostRecentlySelectedHole == null)
            {
                return;
            }

            LayoutHole oHole = LayoutHole.CopyFrom(MostRecentlySelectedHole);

            // Add at an offset so it will be easy to see
            oHole.OffsetX += 10;
            oHole.OffsetY += 10;

            // Create a new version of the instance of the hole

            int ndx = MostRecentlySelectedHole.HoleTypeIndex;

            switch (MostRecentlySelectedHole.HoleType)
            {
            case "ell":
                oHole.HoleTypeIndex = BoundaryEllipseList.Count;
                BoundaryEllipse e = BoundaryEllipseList.GetFrom(ndx);
                BoundaryEllipseList.Add(BoundaryEllipse.CopyFrom(e));
                break;

            case "rect":
                oHole.HoleTypeIndex = BoundaryRectangleList.Count;
                BoundaryRectangle r = BoundaryRectangleList.GetFrom(ndx);
                BoundaryRectangleList.Add(BoundaryRectangle.CopyFrom(r));
                break;

            case "poly":
                oHole.HoleTypeIndex = BoundaryPolygonList.Count;
                BoundaryPolygon p = BoundaryPolygonList.GetFrom(ndx);
                BoundaryPolygonList.Add(BoundaryPolygon.CopyFrom(p));
                break;
            }

            // Add the new hole to the hole group
            AddHoleToHoleGroup(MostRecentlySelectedHoleGroup, oHole);

            // trigger a repaint
            DrawShapes();
        }
Example #9
0
        public void RemoveCurrentPolygonVertex()
        {
            if (MostRecentlySelectedHole == null)
            {
                return;
            }

            if (MostRecentlySelectedHole.HoleType != "poly")
            {
                return;
            }

            if (MostRecentlySelectedPolygonVertexIndex == -1)
            {
                return;
            }

            BoundaryPolygon oPolygon = BoundaryPolygonList.GetFrom(MostRecentlySelectedHole.HoleTypeIndex);

            // Don't reduce to less than 3 points
            if (oPolygon.PointList.Length == 3)
            {
                return;
            }

            /*
             * Remove this point and clear the most recently selected edge
             */
#if DOTNET
            List <Point3D> tmp = new List <Point3D>(oPolygon.PointList);
            tmp.RemoveAt(MostRecentlySelectedPolygonVertexIndex);
            oPolygon.PointList = tmp.ToArray();
#else
            oPolygon.PointList.splice(this.MostRecentlySelectedPolygonVertexIndex, 1);
#endif

            MostRecentlySelectedPolygonVertexIndex = -1;

            // trigger a redraw

            DrawShapes();
        }
Example #10
0
 public bool IsInBoundary(GPSPoint Point)
 {
     return(BoundaryPolygon.InPolygon(Point));
 }
Example #11
0
 public Double GetDistanceTo(GPSPoint Point)
 {
     return(BoundaryPolygon.GetDistanceTo(Point));
 }
        //------------------------------------------------------------------------------------------------
        protected void UpdatePolygon(int ScreenMouseX, int ScreenMouseY, int ScreenDeltaX, int ScreenDeltaY)
        {
            BoundaryPolygon oPolygon = BoundaryPolygonList.GetFrom(CurrentlySelectedHole.HoleTypeIndex);
            PointF          pWorld   = this.S2W(ScreenMouseX, ScreenMouseY);
            float           newx     = pWorld.X;
            float           newy     = pWorld.Y;

            // Update the world points to the nearest grid
            if (this.GridSize > 1)
            {
                newx = this.RoundToGrid((int)pWorld.X);
                newy = this.RoundToGrid((int)pWorld.Y);
            }

            switch (CurrentlySelectedHandleType)
            {
            case eHandleType.VertexHandle:
                /*
                 * Retrieve this vertex and update
                 */
                Point3D p = oPolygon.PointList[CurrentlySelectedPolygonVertexIndex];

                p.X += ScreenDeltaX * CurrentZoom;
                p.Y += ScreenDeltaY * CurrentZoom;

                break;

            case eHandleType.EdgeHandle:
                /*
                 * The points associated with the edge are the ones at the value and after
                 */
                int FromIndex = CurrentlySelectedPolygonEdgeIndex;
                int ToIndex   = FromIndex + 1;
                if (ToIndex == oPolygon.PointList.Length)
                {
                    ToIndex = 0;
                }

                Point3D FromPoint = oPolygon.PointList[FromIndex];
                Point3D ToPoint   = oPolygon.PointList[ToIndex];

                FromPoint.X += ScreenDeltaX * CurrentZoom;
                FromPoint.Y += ScreenDeltaY * CurrentZoom;

                ToPoint.X += ScreenDeltaX * CurrentZoom;
                ToPoint.Y += ScreenDeltaY * CurrentZoom;
                break;

            case eHandleType.MoveHandle:
                /*
                 * Update the offset to move the whole shape
                 */
                CurrentlySelectedHole.OffsetX = newx;
                CurrentlySelectedHole.OffsetY = newy;

                /*
                 * Update all points with the delta
                 */
#if false
                for (int i = 0; i < oPolygon.PointList.Length; i++)
                {
                    Point3D pMove = oPolygon.PointList[i];
                    pMove.X += ScreenDeltaX;
                    pMove.Y += ScreenDeltaY;
                }
#endif
                break;
            }
        }
Example #13
0
        //--------------------------------------------------------------------------

        /*
         * A Polygon can be selected in any of these ways:
         * 1. A vertex can be selected, which makes it the active vertex
         * 2. An edge can be selected, which makes it the active edge
         * 3. The move handle can be selected. The move handle is generated as the average of the points of the polygon
         */
        private bool TrySelectPolygon(LayoutHole oHole, int ScreenMouseX, int ScreenMouseY)
        {
            PointF MoveHandle = new PointF(0, 0);
            float  dx;
            float  dy;


            BoundaryPolygon oPolygon = BoundaryPolygonList.GetFrom(oHole.HoleTypeIndex);

            PointF ScreenOffset = this.W2S(oHole.OffsetX, oHole.OffsetY);

            /*
             * See if this is one of the vertices
             */
            for (int i = 0; i < oPolygon.PointList.Length; i++)
            {
                Point3D p = oPolygon.PointList[i];
                dx = p.X / CurrentZoom;
                dy = p.Y / CurrentZoom;

                PointF Target = new PointF(ScreenOffset.X + dx, ScreenOffset.Y + dy);

                if (IsHitOnTarget(ScreenMouseX, ScreenMouseY, Target))
                {
                    CurrentlySelectedHole = oHole;
                    // Most recently selected is used for commands that happen after the mouse is up
                    MostRecentlySelectedHole    = oHole;
                    CurrentlySelectedHandleType = eHandleType.VertexHandle;

                    CurrentlySelectedPolygonVertexIndex = i;
                    // The most recently used is for commands that happen after the mouse is up
                    MostRecentlySelectedPolygonVertexIndex = i;

                    return(true);
                }
            }

            /*
             * See if this is one of the edges
             */
            for (int i = 0; i < oPolygon.PointList.Length; i++)
            {
                int FromIndex = i;
                int ToIndex   = i + 1;
                if (ToIndex == oPolygon.PointList.Length)
                {
                    ToIndex = 0;
                }

                Point3D FromPoint = oPolygon.PointList[FromIndex];

                dx = FromPoint.X / CurrentZoom;
                dy = FromPoint.Y / CurrentZoom;

                PointF pFrom = new PointF(ScreenOffset.X + dx, ScreenOffset.Y + dy);

                Point3D ToPoint = oPolygon.PointList[ToIndex];

                dx = ToPoint.X / CurrentZoom;
                dy = ToPoint.Y / CurrentZoom;

                PointF pTo = new PointF(ScreenOffset.X + dx, ScreenOffset.Y + dy);

                PointF Target = EdgeCenter(pFrom, pTo);

                if (IsHitOnTarget(ScreenMouseX, ScreenMouseY, Target))
                {
                    CurrentlySelectedHole = oHole;
                    // Most recently selected is used for commands that happen after the mouse is up
                    MostRecentlySelectedHole    = oHole;
                    CurrentlySelectedHandleType = eHandleType.EdgeHandle;

                    CurrentlySelectedPolygonEdgeIndex = i;
                    // The most recently used is for commands that happen after the mouse is up
                    MostRecentlySelectedPolygonEdgeIndex = i;

                    return(true);
                }
            }

            /*
             * See if this is the move handle at the center of the polygon
             */
            PointF pCenter = PolygonCenter(oPolygon);

            dx      = pCenter.X / CurrentZoom;
            dy      = pCenter.Y / CurrentZoom;
            pCenter = new PointF(ScreenOffset.X + dx, ScreenOffset.Y + dy);

            if (IsHitOnTarget(ScreenMouseX, ScreenMouseY, pCenter))
            {
                CurrentlySelectedHole = oHole;
                // Most recently selected is used for commands that happen after the mouse is up
                MostRecentlySelectedHole    = oHole;
                CurrentlySelectedHandleType = eHandleType.MoveHandle;
                return(true);
            }


            return(false);
        }