void DrawLineOutline(Vector3[] worldPoints, List <Node> nodeList, float width, float additionalWidth, Color color)
        {
            Vector3 cameraPosition = SceneView.currentDrawingSceneView.camera.transform.position;

            for (int i = 0; i <= worldPoints.Length - 2; i++)
            {
                if (!nodeList[i].Active)
                {
                    continue;
                }
                float lineWidth = width + additionalWidth;
                if (nodeList[i].OverrideWidth)
                {
                    lineWidth = nodeList[i].CustomWidth / 2f + additionalWidth;
                }

                float distance = Vector3.Distance(worldPoints[i], cameraPosition);
                if (distance < 200)
                {
                    List <Vector3> pointList = new List <Vector3> {
                        worldPoints[i], worldPoints[i + 1]
                    };
                    List <Vector3> newInflatedList = PolygonUtility.InflatePolygon(pointList, lineWidth, false);
                    PolygonUtility.AlignPointsWithTerrain(newInflatedList, true, VegetationMaskLine.GroundLayerMask);
                    Handles.color = color;
                    Handles.DrawAAPolyLine(3, newInflatedList.ToArray());
                }
            }
        }
示例#2
0
        //this checks a polylist for abnormal polys and returns only those which deem fit
        internal static List <Polygon2d> CheckAndCleanPolygon2dList(List <Polygon2d> polyList)
        {
            if (!CheckPolyList(polyList))
            {
                return(null);
            }
            List <Polygon2d> cleanPolyList = new List <Polygon2d>();

            for (int i = 0; i < polyList.Count; i++)
            {
                bool lineLength = true;
                if (!CheckPoly(polyList[i]))
                {
                    continue;
                }
                if (polyList[i].Lines == null || polyList[i].Lines.Count == 0)
                {
                    continue;
                }
                for (int j = 0; j < polyList[i].Lines.Count; j++)
                {
                    if (polyList[i].Lines[j].Length < 0.01 && PolygonUtility.AreaPolygon(polyList[i]) < 0.2)
                    {
                        lineLength = false;
                    }
                }
                if (CheckPoly(polyList[i]) && lineLength)
                {
                    cleanPolyList.Add(polyList[i]);
                }
            }
            return(cleanPolyList);
        }
示例#3
0
        internal static bool CheckPolyAdjacencyToPolyList(Polygon2d poly, List <Polygon2d> polyList)
        {
            if (!CheckPoly(poly))
            {
                return(false);
            }
            if (!CheckPolyList(polyList))
            {
                return(false);
            }
            bool check = false;

            for (int i = 0; i < polyList.Count; i++)
            {
                Dictionary <string, object> adjObject = PolygonUtility.FindPolyAdjacentEdge(poly, polyList[i]);
                check = (bool)adjObject["Neighbour"];
            }
            if (check)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
示例#4
0
        //sorts a list of points form a polyline
        public static List <Point2d> SortPoints(List <Point2d> pointList)
        {
            if (!ValidateObject.CheckPointList(pointList))
            {
                return(null);
            }
            Point2d       cen     = PolygonUtility.CentroidOfPoly(Polygon2d.ByPoints(pointList));
            Vector2d      vecX    = new Vector2d(0, 100);
            List <double> angList = new List <double>();

            int[] indList = new int[pointList.Count];
            for (int i = 0; i < pointList.Count; i++)
            {
                Vector2d CenterToPt = new Vector2d(cen, pointList[i]);
                double   dotValue   = vecX.Dot(CenterToPt);
                double   angValue   = Math.Atan2(CenterToPt.Y - vecX.Y, CenterToPt.X - vecX.X);
                angList.Add(angValue);
                indList[i] = i;
            }
            List <int> newIndexList = new List <int>();

            newIndexList = BasicUtility.SortIndex(angList);
            List <Point2d> sortedPointList = new List <Point2d>();

            for (int i = 0; i < pointList.Count; i++)
            {
                sortedPointList.Add(pointList[newIndexList[i]]);
            }
            return(sortedPointList);
        }
示例#5
0
        //gets list of polygon2ds and find the most closest polygon2d to the center , to place the central stn
        internal static Dictionary <string, object> MakeCentralStation(List <Polygon2d> polygonsList, Point2d centerPt)
        {
            if (polygonsList == null || polygonsList.Count == 0)
            {
                return(null);
            }
            if (polygonsList.Count < 2)
            {
                return(new Dictionary <string, object>
                {
                    { "PolyCentral", (polygonsList) },
                    { "IndexInPatientPoly", (0) }
                });
            }
            List <Polygon2d> newPolyLists = new List <Polygon2d>();
            List <double>    distanceList = new List <double>();
            double           minArea = 100, ratio = 0.5, dis = 0;; int dir = 0;
            List <int>       indices     = PolygonUtility.SortPolygonsFromAPoint(polygonsList, centerPt);
            Polygon2d        polyToPlace = polygonsList[indices[0]];
            double           area        = PolygonUtility.AreaPolygon(polyToPlace);

            if (area > minArea)
            {
                List <double> spans = PolygonUtility.GetSpansXYFromPolygon2d(polyToPlace.Points);
                if (spans[0] > spans[1])
                {
                    dir = 1;
                    dis = spans[0] / 2;
                }
                else
                {
                    dir = 0;
                    dis = spans[1] / 2;
                }
                Random ran = new Random();
                //Dictionary<string, object> splittedPoly = BasicSplitPolyIntoTwo(polyToPlace, ratio, dir);
                //Dictionary<string, object> splittedPoly = SplitByDistanceFromPoint(polyToPlace, dis, dir);
                Dictionary <string, object> splittedPoly     = SplitObject.SplitByDistance(polyToPlace, ran, dis, dir);
                List <Polygon2d>            polyReturnedList = (List <Polygon2d>)splittedPoly["PolyAfterSplit"];
                if (!ValidateObject.CheckPolyList(polyReturnedList))
                {
                    return(null);
                }
                List <int> ind = PolygonUtility.SortPolygonsFromAPoint(polyReturnedList, centerPt);
                newPolyLists.Add(polyReturnedList[ind[0]]);
                newPolyLists.Add(polyReturnedList[ind[1]]);
            }
            else
            {
                newPolyLists.Add(polyToPlace);
            }
            return(new Dictionary <string, object>
            {
                { "PolyCentral", (newPolyLists) },
                { "IndexInPatientPoly", (indices[0]) }
            });
        }
示例#6
0
        internal static Dictionary <string, object> ComputePolyCentersAlign(Polygon2d polyA, Polygon2d polyB)
        {
            //compute orig centers
            Point2d centerPolyA = PointUtility.CentroidInPointLists(polyA.Points);
            Point2d centerPolyB = PointUtility.CentroidInPointLists(polyB.Points);

            Point2d   staticPoint, movingPoint;
            Polygon2d staticPoly, movingPoly;

            double areaPolyA = PolygonUtility.AreaPolygon(polyA);
            double areaPolyB = PolygonUtility.AreaPolygon(polyB);

            if (areaPolyA > areaPolyB)
            {
                staticPoint = centerPolyB;
                staticPoly  = polyB;
                movingPoint = centerPolyA;
                movingPoly  = polyA;
            }
            else
            {
                staticPoint = centerPolyA;
                staticPoly  = polyA;
                movingPoint = centerPolyB;
                movingPoly  = polyB;
            }

            //shift the other points
            Point2d movingPoint1   = new Point2d(staticPoint.X, movingPoint.Y);
            Point2d movingPoint2   = new Point2d(movingPoint.X, staticPoint.Y);
            bool    IsMovingPoint1 = GraphicsUtility.PointInsidePolygonTest(movingPoly, movingPoint1);
            bool    IsMovingPoint2 = GraphicsUtility.PointInsidePolygonTest(movingPoly, movingPoint2);

            if (IsMovingPoint1)
            {
                movingPoint = movingPoint1;
            }
            else if (IsMovingPoint2)
            {
                movingPoint = movingPoint2;
            }
            else
            {
                staticPoint = centerPolyA;
                staticPoly  = polyA;
                movingPoint = movingPoint1;
                movingPoly  = polyB;
            }

            return(new Dictionary <string, object>
            {
                { "CenterPolyA", (staticPoint) },
                { "CenterPolyB", (movingPoint) },
                { "PolyA", (staticPoly) },
                { "PolyB", (movingPoly) }
            });
        }
示例#7
0
        //check if a given polygon2d has any of its longer edges aligned with any edge of the containerpolygon2d
        internal static bool CheckPolyGetsExternalWall(Polygon2d poly, Polygon2d containerPoly, double shortEdgeDist = 16, bool tag = true)
        {
            bool check = false;

            if (!ValidateObject.CheckPoly(poly))
            {
                return(check);
            }
            Polygon2d polyReg = new Polygon2d(null);

            //make given polys reduce number of points
            if (tag)
            {
                polyReg = new Polygon2d(poly.Points);
            }
            else
            {
                polyReg = poly;
            }
            Polygon2d containerPolyReg = new Polygon2d(containerPoly.Points);

            for (int i = 0; i < polyReg.Points.Count; i++)
            {
                int    a = i, b = i + 1;
                double eps = 0;
                if (i == polyReg.Points.Count - 1)
                {
                    b = 0;
                }
                double        distance    = PointUtility.DistanceBetweenPoints(polyReg.Points[a], polyReg.Points[b]);
                List <double> spansSorted = PolygonUtility.GetPolySpan(containerPolyReg);
                if (distance <= spansSorted[0] * 0.75)
                {
                    continue;
                }
                Line2d lineA = Line2d.ByStartPointEndPoint(polyReg.Points[a], polyReg.Points[b]);
                for (int j = 0; j < containerPolyReg.Points.Count; j++)
                {
                    int c = j, d = j + 1;
                    if (j == containerPolyReg.Points.Count - 1)
                    {
                        d = 0;
                    }
                    Line2d lineB = Line2d.ByStartPointEndPoint(containerPolyReg.Points[c], containerPolyReg.Points[d]);
                    check = GraphicsUtility.LineAdjacencyCheck(lineA, lineB, eps);
                    if (check)
                    {
                        break;
                    }
                }
                if (check)
                {
                    break;
                }
            }
            return(check);
        }
        public static Dictionary <string, object> SplitByDistance(Polygon2d polyOutline, Random ran, double distance = 10, int dir = 0, double spacing = 0)
        {
            if (!ValidateObject.CheckPoly(polyOutline))
            {
                return(null);
            }
            double         extents = 5000, spacingProvided;
            List <Point2d> polyOrig = polyOutline.Points;

            if (spacing == 0)
            {
                spacingProvided = BuildLayout.SPACING;
            }
            else
            {
                spacingProvided = spacing;
            }

            List <Point2d> poly = PolygonUtility.SmoothPolygon(polyOrig, spacingProvided);

            if (!ValidateObject.CheckPointList(poly))
            {
                return(null);
            }
            Dictionary <int, object> obj = PointUtility.PointSelector(ran, poly);
            Point2d pt        = (Point2d)obj[0];
            int     orient    = (int)obj[1];
            Line2d  splitLine = new Line2d(pt, extents, dir);

            // push this line right or left or up or down based on ratio
            if (dir == 0)
            {
                splitLine = LineUtility.Move(splitLine, 0, orient * distance);
            }
            else
            {
                splitLine = LineUtility.Move(splitLine, orient * distance, 0);
            }

            Dictionary <string, object> intersectionReturn = MakeIntersections(poly, splitLine, spacingProvided);
            List <Point2d>   intersectedPoints             = (List <Point2d>)intersectionReturn["IntersectedPoints"];
            List <Polygon2d> splittedPoly = (List <Polygon2d>)intersectionReturn["PolyAfterSplit"];
            List <Point2d>   ptA = (List <Point2d>)intersectionReturn["PointASide"];
            List <Point2d>   ptB = (List <Point2d>)intersectionReturn["PointBSide"];
            Polygon2d        polyA = new Polygon2d(ptA, 0), polyB = new Polygon2d(ptB, 0);

            //List<Polygon2d> splittedPoly = new List<Polygon2d>();
            //splittedPoly.Add(polyA); splittedPoly.Add(polyB);
            return(new Dictionary <string, object>
            {
                { "PolyAfterSplit", (splittedPoly) },
                { "SplitLine", (splitLine) },
                { "IntersectedPoints", (intersectedPoints) },
                { "PointASide", (ptA) },
                { "PointBSide", (ptB) }
            });
        }
        public static Dictionary <string, object> SplitByDistanceFromPoint(Polygon2d polyOutline, double distance = 10, int dir = 0, double space = 0)
        {
            if (polyOutline == null || polyOutline.Points == null || polyOutline.Points.Count == 0)
            {
                return(null);
            }
            if (space == 0)
            {
                space = BuildLayout.SPACING2;
            }
            double         extents     = 5000;
            int            threshValue = 50;
            List <Point2d> polyOrig    = polyOutline.Points;
            List <Point2d> poly        = new List <Point2d>();

            if (polyOrig.Count > threshValue)
            {
                poly = polyOrig;
            }
            else
            {
                poly = PolygonUtility.SmoothPolygon(polyOrig, space);
            }

            if (poly == null || poly.Count == 0)
            {
                return(null);
            }
            int     lowInd    = PointUtility.LowestPointFromList(poly);
            Point2d lowPt     = poly[lowInd];
            Line2d  splitLine = new Line2d(lowPt, extents, dir);

            if (dir == 0)
            {
                splitLine = LineUtility.Move(splitLine, 0, 1 * distance);
            }
            else
            {
                splitLine = LineUtility.Move(splitLine, 1 * distance, 0);
            }

            Dictionary <string, object> intersectionReturn = MakeIntersections(poly, splitLine, space);
            List <Point2d>   intersectedPoints             = (List <Point2d>)intersectionReturn["IntersectedPoints"];
            List <Polygon2d> splittedPoly = (List <Polygon2d>)intersectionReturn["PolyAfterSplit"];
            List <Point2d>   ptA          = (List <Point2d>)intersectionReturn["PointASide"];
            List <Point2d>   ptB          = (List <Point2d>)intersectionReturn["PointBSide"];

            return(new Dictionary <string, object>
            {
                { "PolyAfterSplit", (splittedPoly) },
                { "SplitLine", (splitLine) },
                { "IntersectedPoints", (intersectedPoints) },
                { "PointASide", (ptA) },
                { "PointBSide", (ptB) }
            });
        }
        // find the closest point to a point from a group of cells
        internal static int FindClosestPointIndex(List <Cell> cellList, Point2d pt)
        {
            List <Point2d> ptList = new List <Point2d>();

            for (int i = 0; i < cellList.Count; i++)
            {
                if (cellList[i].CellAvailable)
                {
                    ptList.Add(cellList[i].CenterPoint);
                }
            }
            return(PolygonUtility.FindClosestPointIndex(ptList, pt));
        }
示例#11
0
        /// <summary>
        /// Distributes random points within bounds and creates a convex hull around it.
        /// </summary>
        /// <param name="mask"></param>
        /// <param name="bounds"></param>
        /// <param name="count"></param>
        public static List <Vector3> CreateRandomShapeUsingConvexHull(Bounds bounds, int count)
        {
            List <Vector2> points = new List <Vector2>();

            for (int i = 0; i < count; i++)
            {
                points.Add(PolygonUtils.GetRandomPointXZ(bounds));
            }

            List <Vector2> convexHull = PolygonUtility.GetConvexHull(points);

            List <Vector3> nodes = convexHull.ConvertAll <Vector3>(item => new Vector3(item.x, 0, item.y));

            return(nodes);
        }
示例#12
0
        //returns the highest and lowest point along with indices from a pointlist
        internal static Dictionary <string, object> ReturnHighestAndLowestPointofBBox(Polygon2d poly)
        {
            Range2d range = PolygonUtility.GetRang2DFromBBox(ReadData.FromPointsGetBoundingPoly(poly.Points));
            double  minX = range.Xrange.Min;
            double  maxX = range.Xrange.Max;
            double  minY = range.Yrange.Min;
            double  maxY = range.Yrange.Max;
            Point2d lowPt = new Point2d(minX, minY), hipt = new Point2d(maxX, maxY);


            return(new Dictionary <string, object>
            {
                { "LowerPoint", (lowPt) },
                { "HigherPoint", (hipt) },
            });
        }
        /// <summary>
        /// Transform the mask and convert it into its convex hull.
        /// </summary>
        /// <param name="mask"></param>
        public static void ConvexHull(VegetationMaskArea mask)
        {
            Vector3 maskPosition = mask.transform.position;

            List <Vector2> positionsXY = mask.Nodes.ConvertAll <Vector2>(item => new Vector2(item.Position.x, item.Position.z));

            List <Vector2> convexHull = PolygonUtility.GetConvexHull(positionsXY);

            mask.Nodes.Clear();
            foreach (Vector2 nodePosition in convexHull)
            {
                mask.AddNodeToEnd(new Vector3(maskPosition.x + nodePosition.x, 0, maskPosition.z + nodePosition.y));
            }

            // center main handle, implicitly updates the mask
            CenterMainHandle(mask);
        }
        public static Dictionary <string, object> SplitByLine(Polygon2d polyOutline, Line2d inputLine, double distance = 5)
        {
            if (!ValidateObject.CheckPoly(polyOutline))
            {
                return(null);
            }
            List <Point2d> polyOrig   = polyOutline.Points;
            List <Point2d> poly       = PolygonUtility.SmoothPolygon(polyOrig, BuildLayout.SPACING);
            Line2d         splitLine  = new Line2d(inputLine);
            Point2d        centerPoly = PointUtility.CentroidInPointLists(poly);
            bool           checkSide  = ValidateObject.CheckPointSide(splitLine, centerPoly);
            int            orient     = ValidateObject.CheckLineOrient(splitLine);

            if (orient == 0)
            {
                if (!checkSide)
                {
                    splitLine = LineUtility.Move(splitLine, 0, -1 * distance);
                }
                else
                {
                    splitLine = LineUtility.Move(splitLine, 0, 1 * distance);
                }
            }
            else
            {
                if (checkSide)
                {
                    splitLine = LineUtility.Move(splitLine, -1 * distance, 0);
                }
                else
                {
                    splitLine = LineUtility.Move(splitLine, 1 * distance, 0);
                }
            }

            Dictionary <string, object> intersectionReturn = MakeIntersections(poly, splitLine, BuildLayout.SPACING);
            List <Polygon2d>            splittedPoly       = (List <Polygon2d>)intersectionReturn["PolyAfterSplit"];

            return(new Dictionary <string, object>
            {
                { "PolyAfterSplit", (splittedPoly) },
                { "SplitLine", (splitLine) }
            });
        }
示例#15
0
        //sort points clockwise direction
        internal static List <Point2d> DoSortClockwise(List <Point2d> poly, List <Point2d> intersectedPoints, List <int> pIndex)
        {
            if (intersectedPoints == null || intersectedPoints.Count == 0)
            {
                return(null);
            }
            List <Point2d> cleanedPtList = new List <Point2d>();

            if (intersectedPoints.Count > 2)
            {
                cleanedPtList = CleanDuplicatePoint2d(intersectedPoints);
            }
            else
            {
                cleanedPtList = intersectedPoints;
            }
            return(PolygonUtility.OrderPolygon2dPoints(poly, cleanedPtList, pIndex)); //intersectedPoints
        }
示例#16
0
        // from a list of given polys  it assigns each program a list of polys till its area is satisfied
        internal static List <List <Polygon2d> > AssignPolysToProgramData(List <ProgramData> newProgDataList, List <Polygon2d> polygonLists)
        {
            //reset the area provided to the input progdata
            for (int i = 0; i < newProgDataList.Count; i++)
            {
                newProgDataList[i].ProgAreaProvided = 0;
            }
            List <List <Polygon2d> > polyEachProgramList = new List <List <Polygon2d> >();
            Stack <Polygon2d>        polyStack           = new Stack <Polygon2d>();

            for (int i = 0; i < polygonLists.Count; i++)
            {
                polyStack.Push(polygonLists[i]);
            }

            for (int i = 0; i < newProgDataList.Count; i++)
            {
                ProgramData progItem = newProgDataList[i];
                //Trace.WriteLine("Starting Porg Data : " + i + "///////////");
                bool added = false;
                //double areaProgram = progData[i].CurrentAreaNeeds;
                List <Polygon2d> polysForProg = new List <Polygon2d>();
                while (progItem.CurrentAreaNeeds > 0 && polyStack.Count > 0)
                {
                    //Trace.WriteLine("  = = now in while = = ");
                    Polygon2d currentPoly = polyStack.Pop();
                    double    currentArea = PolygonUtility.AreaPolygon(currentPoly);
                    progItem.AddAreaToProg(currentArea);
                    polysForProg.Add(currentPoly);
                    //Trace.WriteLine("Area Given Now is : " + progItem.AreaAllocatedValue);
                    //Trace.WriteLine("Area Left over to Add :" + progItem.CurrentAreaNeeds);
                    added = true;
                }
                //dummy is just to make sure the function re reuns when slider is hit
                if (added)
                {
                    polyEachProgramList.Add(polysForProg);
                }
                //if (!added) Trace.WriteLine("Did not add.  PolyStack Left : " + polyStack.Count + " | Current area needs were : " + progItem.CurrentAreaNeeds);
                //Trace.WriteLine("++++++++++++++++++++++++++++++");
            }
            return(polyEachProgramList);
        }
示例#17
0
        public static Dictionary <string, object> CheckPolyNotches(Polygon2d poly, double distance = 10)
        {
            if (!CheckPoly(poly))
            {
                return(null);
            }
            bool      hasNotches = true;
            int       count = 0, maxTry = 2 * poly.Points.Count;
            Polygon2d currentPoly = new Polygon2d(poly.Points);

            while (hasNotches && count < maxTry)
            {
                Dictionary <string, object> notchObject = PolygonUtility.RemoveAnyNotches(currentPoly, distance);
                if (notchObject == null)
                {
                    continue;
                }
                currentPoly = (Polygon2d)notchObject["PolyNotchRemoved"];
                for (int i = 0; i < poly.Lines.Count; i++)
                {
                    int a = i, b = i + 1;
                    if (i == poly.Points.Count - 1)
                    {
                        b = 0;
                    }
                    if (poly.Lines[a].Length < distance && poly.Lines[b].Length < distance)
                    {
                        hasNotches = true; break;
                    }
                    else
                    {
                        hasNotches = false;
                    }
                }
                count += 1;
            }
            return(new Dictionary <string, object>
            {
                { "PolyReduced", (poly) },
                { "HasNotches", (hasNotches) },
                { "Trials", (count) }
            });
        }
        /// <summary>
        /// Apply the Douglas Peucker reduction algorithm
        /// </summary>
        /// <param name="positions"></param>
        /// <returns></returns>
        public static List <Vector3> ApplyDoublesPeucker(List <Vector3> positions, float douglasPeuckerReductionTolerance)
        {
            if (douglasPeuckerReductionTolerance == 0)
            {
                return(positions);
            }

            // convert to vector2
            List <Vector2> vector2List = positions.ConvertAll <Vector2>(item => new Vector2(item.x, item.z));

            // use vspro's DouglasPeuckerReduction algorithm
            vector2List = PolygonUtility.DouglasPeuckerReduction(vector2List, douglasPeuckerReductionTolerance);

            // convert back to vector3
            if (vector2List.Count >= 3)
            {
                positions = vector2List.ConvertAll <Vector3>(item => new Vector3(item.x, 0, item.y));
            }

            return(positions);
        }
示例#19
0
        public void GenerateHullNodes(float tolerance)
        {
            List <Vector2> worldSpacePointList = new List <Vector2>();

            MeshFilter[] mersFilters = GetComponentsInChildren <MeshFilter>();
            for (int i = 0; i <= mersFilters.Length - 1; i++)
            {
                Mesh mesh = mersFilters[i].sharedMesh;
                if (mesh)
                {
                    List <Vector3> verticeList = new List <Vector3>();
                    mesh.GetVertices(verticeList);
                    for (int j = 0; j <= verticeList.Count - 1; j++)
                    {
                        Vector3 worldSpacePosition = mersFilters[i].transform.TransformPoint(verticeList[j]);
                        Vector2 worldSpacePoint    = new Vector2
                        {
                            x = worldSpacePosition.x,
                            y = worldSpacePosition.z
                        };
                        worldSpacePointList.Add(worldSpacePoint);
                    }
                }
            }

            List <Vector2> hullPointList    = PolygonUtility.GetConvexHull(worldSpacePointList);
            List <Vector2> reducedPointList = PolygonUtility.DouglasPeuckerReduction(hullPointList, tolerance);


            if (reducedPointList.Count >= 3)
            {
                ClearNodes();
                for (int i = 0; i <= reducedPointList.Count - 1; i++)
                {
                    Vector3 worldSpacePosition = new Vector3(reducedPointList[i].x, 0, reducedPointList[i].y);
                    AddNode(worldSpacePosition);
                }
                PositionNodes();
            }
        }
示例#20
0
        //checks a polygon2d to have min Area and min dimensions
        internal static bool CheckPolyDimension(Polygon2d poly, double minArea = 6, double side = 2)
        {
            if (!CheckPoly(poly))
            {
                return(false);
            }
            if (PolygonUtility.AreaPolygon(poly) < minArea)
            {
                return(false);
            }
            List <double> spans = PolygonUtility.GetSpansXYFromPolygon2d(poly.Points);

            if (spans[0] < side)
            {
                return(false);
            }
            if (spans[1] < side)
            {
                return(false);
            }
            return(true);
        }
        //uses makepolysofproportion function to split one big poly into sub components
        internal static Dictionary <string, object> SplitBigPolys(List <Polygon2d> polyInputList, double acceptableWidth, double factor = 4)
        {
            List <Polygon2d> polyOrganizedList = new List <Polygon2d>(), polyCoverList = new List <Polygon2d>();
            int count = 0;

            for (int i = 0; i < polyInputList.Count; i++)
            {
                Polygon2d poly = polyInputList[i];
                if (poly == null || poly.Points == null || poly.Points.Count == 0)
                {
                    count += 1;
                    continue;
                }
                double targetArea = PolygonUtility.AreaPolygon(poly) / factor;
                MakePolysOfProportion(poly, polyOrganizedList, polyCoverList, acceptableWidth, targetArea);
            }
            BuildLayout.RECURSE = 0;
            return(new Dictionary <string, object>
            {
                { "PolySpaces", (polyOrganizedList) },
                { "PolyForCirculation", (polyCoverList) }
            });
        }
示例#22
0
        //checsk the aspect ratio of polygons
        internal static bool CheckPolyAspectRatio(Polygon2d poly, double minDimensionAllowed = 5)
        {
            if (!CheckPoly(poly))
            {
                return(false);
            }

            List <double> spans = PolygonUtility.GetSpansXYFromPolygon2d(poly.Points);

            if (spans.Count > 1)
            {
                if (spans[0] < minDimensionAllowed || spans[1] < minDimensionAllowed)
                {
                    return(false);
                }
                double aspectRatio = spans[0] / spans[1];
                if (aspectRatio < 1)
                {
                    aspectRatio = 1 / aspectRatio;
                }
                if (aspectRatio > 5)
                {
                    return(false);
                }
                if (aspectRatio > 1.5)
                {
                    double areaShouldBe = spans[0] * spans[1];
                    double areaPoly     = PolygonUtility.AreaPolygon(poly);
                    if (areaPoly / areaShouldBe < 0.9)
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
        public static Dictionary <string, object> MakeProgCirculationPolys(List <Line2d> circulationNetwork, List <Polygon2d> polyProgList, double circulationWidth = 8, double circulationFrequency = 0.5, int designSeed = 10)
        {
            if (!ValidateObject.CheckPolyList(polyProgList))
            {
                return(null);
            }
            if (circulationNetwork == null || circulationNetwork.Count == 0)
            {
                return(null);
            }
            List <Line2d> flatLineList    = new List <Line2d>();
            List <bool>   IsDuplicateList = new List <bool>();

            polyProgList = PolygonUtility.SmoothPolygonList(polyProgList, 5);

            //flatten all the polys in each depts to make it one list
            List <Polygon2d> circulationPolyList = new List <Polygon2d>();
            List <Polygon2d> updatedProgPolyList = new List <Polygon2d>();
            List <int>       deptIdList          = new List <int>();
            double           allowedCircRatio    = 4;
            List <double>    areaProgPolyList    = new List <double>();

            for (int i = 0; i < polyProgList.Count; i++)
            {
                areaProgPolyList.Add(PolygonUtility.AreaPolygon(polyProgList[i]));
            }

            double maxArea = areaProgPolyList.Max();

            areaProgPolyList.Sort();
            int    value      = (int)(areaProgPolyList.Count / 3);
            double areaThresh = areaProgPolyList[value];
            Random ran        = new Random(designSeed);

            for (int i = 0; i < circulationNetwork.Count; i++)
            {
                Line2d splitter   = circulationNetwork[i];
                double someNumber = BasicUtility.RandomBetweenNumbers(ran, 1, 0);
                if (someNumber > circulationFrequency)
                {
                    continue;
                }
                for (int j = 0; j < polyProgList.Count; j++)
                {
                    Polygon2d progPoly = polyProgList[j];
                    double    areaPoly = PolygonUtility.AreaPolygon(progPoly);

                    Point2d midPt       = LineUtility.LineMidPoint(splitter);
                    Point2d nudgedMidPt = LineUtility.NudgeLineMidPt(splitter, progPoly, 0.5);
                    bool    checkInside = GraphicsUtility.PointInsidePolygonTest(progPoly, nudgedMidPt);

                    if (checkInside)
                    {
                        Dictionary <string, object> splitResult    = SplitObject.SplitByLine(progPoly, splitter, circulationWidth);
                        List <Polygon2d>            polyAfterSplit = (List <Polygon2d>)(splitResult["PolyAfterSplit"]);
                        if (ValidateObject.CheckPolyList(polyAfterSplit))
                        {
                            double areaA = PolygonUtility.AreaPolygon(polyAfterSplit[0]), areaB = PolygonUtility.AreaPolygon(polyAfterSplit[1]);
                            if (areaA < areaB)
                            {
                                if (polyAfterSplit[0].Points != null)
                                {
                                    if (ValidateObject.CheckPolyBBox(polyAfterSplit[0], allowedCircRatio))
                                    {
                                        circulationPolyList.Add(polyAfterSplit[0]);
                                    }
                                }
                                updatedProgPolyList.Add(polyAfterSplit[1]);
                            }
                            else
                            {
                                if (polyAfterSplit[1].Points != null)
                                {
                                    if (ValidateObject.CheckPolyBBox(polyAfterSplit[1], allowedCircRatio))
                                    {
                                        circulationPolyList.Add(polyAfterSplit[1]);
                                    }
                                }
                                updatedProgPolyList.Add(polyAfterSplit[0]);
                            }
                        } // end of if loop checking polylist
                    }     // end of check inside
                }         // end of for loop j
            }             // end of for loop i

            return(new Dictionary <string, object>
            {
                { "ProgCirculationPoly", (circulationPolyList) }
            });
        }
        public static Dictionary <string, object> FindDeptCirculationNetwork(List <DeptData> deptData, Polygon2d leftOverPoly = null, bool noExternalWall = false, double circulationFrequency = 0.75)
        {
            if (deptData == null || deptData.Count == 0)
            {
                return(null);
            }
            double                limit = 0;
            List <Polygon2d>      polygonsAllDeptList = new List <Polygon2d>();
            List <DeptData>       deptDataAllDeptList = new List <DeptData>();
            List <List <string> > deptNamesNeighbors  = new List <List <string> >();
            List <List <Line2d> > lineCollection      = new List <List <Line2d> >();

            //make flattened list of all dept data and dept polys
            for (int i = 0; i < deptData.Count; i++)
            {
                List <Polygon2d> polyList = deptData[i].PolyAssignedToDept;
                if (!ValidateObject.CheckPolyList(polyList))
                {
                    continue;
                }
                for (int j = 0; j < polyList.Count; j++)
                {
                    polygonsAllDeptList.Add(polyList[j]);
                    deptDataAllDeptList.Add(deptData[i]);
                }
            }
            if (leftOverPoly != null)
            {
                polygonsAllDeptList.Add(leftOverPoly);
            }
            //else Trace.WriteLine("leftover poly found null, so not added");
            List <Line2d> networkLine = new List <Line2d>();

            for (int i = 0; i < polygonsAllDeptList.Count; i++)
            {
                Polygon2d polyA = polygonsAllDeptList[i];
                for (int j = i + 1; j < polygonsAllDeptList.Count; j++)
                {
                    Polygon2d polyB = polygonsAllDeptList[j];
                    Dictionary <string, object> checkNeighbor = PolygonUtility.FindPolyAdjacentEdge(polyA, polyB, limit);
                    if (checkNeighbor != null)
                    {
                        if ((bool)checkNeighbor["Neighbour"] == true)
                        {
                            networkLine.Add((Line2d)checkNeighbor["SharedEdge"]);
                        }
                    }
                }
            }

            // if externalWalls not necessary
            List <Line2d>    extraLines  = new List <Line2d>();
            List <Polygon2d> polyKeyList = new List <Polygon2d>();

            if (noExternalWall)
            {
                polyKeyList = deptData[0].PolyAssignedToDept;
                for (int i = 0; i < polyKeyList.Count; i++)
                {
                    Polygon2d polyA = polyKeyList[i];
                    for (int j = i + 1; j < polyKeyList.Count; j++)
                    {
                        Polygon2d polyB = polyKeyList[j];
                        Dictionary <string, object> checkNeighbor = PolygonUtility.FindPolyAdjacentEdgeEdit(polyA, polyB, 0.05);
                        if (checkNeighbor != null)
                        {
                            if ((bool)checkNeighbor["Neighbour"] == true)
                            {
                                networkLine.Add((Line2d)checkNeighbor["SharedEdge"]);
                                extraLines.Add((Line2d)checkNeighbor["SharedEdge"]);
                            }
                        }
                    }
                }
            }
            List <Line2d> cleanNetworkLines = LineUtility.RemoveDuplicateLines(networkLine);

            // extend the lines found
            for (int i = 0; i < cleanNetworkLines.Count; i++)
            {
                cleanNetworkLines[i] = LineUtility.ExtendLine(cleanNetworkLines[i], 2000);
            }

            cleanNetworkLines = RemoveNetworkRedundancy(cleanNetworkLines, circulationFrequency);

            //return cleanNetworkLines;
            return(new Dictionary <string, object>
            {
                { "CirculationNetworkLines", (cleanNetworkLines) }
            });
        }
        public static Dictionary <string, object> SplitByRatio(Polygon2d polyOutline, double ratio = 0.5, int dir = 0)
        {
            if (polyOutline == null)
            {
                return(null);
            }
            if (polyOutline != null && polyOutline.Points == null)
            {
                return(null);
            }

            double         extents = 5000;
            double         minimumLength = 2, minWidth = 10, aspectRatio = 0, eps = 0.1;
            List <Point2d> polyOrig = polyOutline.Points;
            List <Point2d> poly = PolygonUtility.SmoothPolygon(polyOrig, BuildLayout.SPACING);
            List <double>  spans = PolygonUtility.GetSpansXYFromPolygon2d(poly);
            double         horizontalSpan = spans[0], verticalSpan = spans[1];
            Point2d        polyCenter = PolygonUtility.CentroidOfPoly(Polygon2d.ByPoints(poly));

            if (horizontalSpan < minimumLength || verticalSpan < minimumLength)
            {
                return(null);
            }

            if (horizontalSpan > verticalSpan)
            {
                dir = 1; aspectRatio = horizontalSpan / verticalSpan;
            }
            else
            {
                dir = 0; aspectRatio = verticalSpan / horizontalSpan;
            }

            // adjust ratio
            if (ratio < 0.15)
            {
                ratio = ratio + eps;
            }
            if (ratio > 0.85)
            {
                ratio = ratio - eps;
            }

            if (horizontalSpan < minWidth || verticalSpan < minWidth)
            {
                ratio = 0.5;
            }
            Line2d splitLine = new Line2d(polyCenter, extents, dir);
            double shift     = ratio - 0.5;

            if (dir == 0)
            {
                splitLine = LineUtility.Move(splitLine, 0, shift * verticalSpan);
            }
            else
            {
                splitLine = LineUtility.Move(splitLine, shift * horizontalSpan, 0);
            }

            Dictionary <string, object> intersectionReturn = MakeIntersections(poly, splitLine, BuildLayout.SPACING);
            List <Point2d>   intersectedPoints             = (List <Point2d>)intersectionReturn["IntersectedPoints"];
            List <Polygon2d> splittedPoly = (List <Polygon2d>)intersectionReturn["PolyAfterSplit"];

            return(new Dictionary <string, object>
            {
                { "PolyAfterSplit", (splittedPoly) },
                { "SplitLine", (splitLine) },
                { "IntersectedPoints", (intersectedPoints) }
            });
        }
示例#26
0
        /// <summary>
        /// Modifies a polygon and creates a random shape.
        ///
        /// Algorithm:
        ///
        /// * create a new polygon, subdivided this way:
        ///   + get center of polygon
        ///   + create a list of angles for iteration
        ///   + iterate through the angles, create a line using the angle and find the intersection with a line of the polygon
        /// * iterate through the subdivided polygon
        ///   + move the vertex towards the center
        ///   + consider previous vertex in order to not move in too large steps
        /// </summary>
        public static List <Vector3> CreateRandomShape(List <Vector3> polygon, float ellipseRelaxationFactor, int angleStepCount, bool randomAngleMovement, bool keepOriginalShape, float douglasPeuckerReductionTolerance)
        {
            Vector3 meanVector = PolygonUtils.GetMeanVector(polygon);
            float   length     = meanVector.magnitude * 2;


            #region create angles

            // get the list of angles to step through
            List <float> angleRadList = CreateAngleList(angleStepCount, randomAngleMovement);

            #endregion create angles

            #region create new polygon using angles

            List <Vector3> subdividedPolygon = new List <Vector3>();

            // add existing points in order to keep the general voronoi shape
            if (keepOriginalShape)
            {
                subdividedPolygon.AddRange(polygon);
            }

            for (int i = 0; i < angleRadList.Count; i++)
            {
                // convert angle from deg to rad
                float angle = angleRadList[i];

                float x = meanVector.x + length * Mathf.Cos(angle);
                float z = meanVector.z + length * Mathf.Sin(angle);

                // position on the ellipse
                Vector3 line1PositionA = meanVector;
                Vector3 line1PositionB = new Vector3(x, 0, z);

                for (var j = 0; j < polygon.Count; j++)
                {
                    int currIndex = j;
                    int nextIndex = j + 1;
                    if (nextIndex == polygon.Count)
                    {
                        nextIndex = 0;
                    }

                    Vector3 line2PositionA = new Vector3(polygon[currIndex].x, 0, polygon[currIndex].z);
                    Vector3 line2PositionB = new Vector3(polygon[nextIndex].x, 0, polygon[nextIndex].z);


                    Vector3 intersection = Vector3.zero;

                    // try and find an intersection. if one is found, add the point to the list
                    if (PolygonUtils.LineSegmentsIntersection(line1PositionA, line1PositionB, line2PositionA, line2PositionB, out intersection))
                    {
                        subdividedPolygon.Add(intersection);
                        break;
                    }
                }
            }

            // sort again
            PolygonUtils.SortClockWise(subdividedPolygon);

            #endregion create new polygon using angles


            #region create new polygon using the intersections
            List <Vector3> newPolygon = new List <Vector3>();

            float prevDistance = 0;

            for (int i = 0; i < subdividedPolygon.Count; i++)
            {
                Vector3 curr = subdividedPolygon[i];

                // position on the ellipse
                Vector3 position = curr;

                // from center to position
                float   distance  = (position - meanVector).magnitude;
                Vector3 direction = (position - meanVector).normalized;

                // move from center towards new position. but not too much, let it depend on the previous distance
                {
                    // move initially from 0 to max distance. otherwise use the previous value
                    float min = i == 0 ? distance * ellipseRelaxationFactor : prevDistance * ellipseRelaxationFactor;
                    float max = distance;

                    // the radius must be smaller during the next iteration, we are navigating around an ellipse => clamp the values
                    if (min > max)
                    {
                        min = max;
                    }

                    float moveDistance = UnityEngine.Random.Range(min, max);

                    distance = moveDistance;
                }

                position = meanVector + distance * direction;

                newPolygon.Add(position);

                prevDistance = distance;
            }
            #endregion create new polygon using the intersections

            if (douglasPeuckerReductionTolerance > 0)
            {
                // convert to vector2
                List <Vector2> vector2List = newPolygon.ConvertAll <Vector2>(item => new Vector2(item.x, item.z));

                // use vspro's DouglasPeuckerReduction algorithm
                vector2List = PolygonUtility.DouglasPeuckerReduction(vector2List, douglasPeuckerReductionTolerance);

                // convert back to vector3
                if (vector2List.Count >= 3)
                {
                    newPolygon = vector2List.ConvertAll <Vector3>(item => new Vector3(item.x, 0, item.y));
                }
            }

            return(newPolygon);
        }
        //subdivide a given poly into smaller parts till acceptable width is met, returns list of polydept grids and list of polys to compute circulation
        public static List <List <Polygon2d> > SplitRecursivelyToSubdividePoly(List <Polygon2d> polyList, double acceptableWidth = 10, double circulationFreq = 10, double ratio = 0.5, bool tag = false)
        {
            if (!ValidateObject.CheckPolyList(polyList))
            {
                return(null);
            }

            int count = 0;
            Queue <Polygon2d>        polyQueue = new Queue <Polygon2d>();
            List <List <Polygon2d> > polyAllReturn = new List <List <Polygon2d> >();
            List <Polygon2d>         polyBrokenList = new List <Polygon2d>(), polyCirculationList = new List <Polygon2d>();
            double totalArea = 0; // cirFac = Math.Ceiling(acceptableWidth/ circulationFreq);
            double cirFac = circulationFreq;

            for (int i = 0; i < polyList.Count; i++)
            {
                totalArea += PolygonUtility.AreaPolygon(polyList[i]);
                polyQueue.Enqueue(polyList[i]);
            }
            Random rand = new Random();
            double targetArea = totalArea / cirFac;

            while (polyQueue.Count > 0)
            {
                Polygon2d currentPoly = polyQueue.Dequeue();
                Dictionary <string, object> splitObj = SplitByRatio(currentPoly, ratio, 0);
                if (tag)
                {
                    ratio = BasicUtility.RandomBetweenNumbers(rand, 0.7, 0.35);
                }
                if (splitObj == null)
                {
                    continue;
                }
                List <Polygon2d> polySplitList = (List <Polygon2d>)splitObj["PolyAfterSplit"];
                if (ValidateObject.CheckPolyList(polySplitList) && polySplitList.Count > 1)
                {
                    polySplitList = PolygonUtility.SmoothPolygonList(polySplitList, 2);
                    Polygon2d bbox1 = Polygon2d.ByPoints(ReadData.FromPointsGetBoundingPoly(polySplitList[0].Points));
                    Polygon2d bbox2 = Polygon2d.ByPoints(ReadData.FromPointsGetBoundingPoly(polySplitList[1].Points));
                    if (!ValidateObject.CheckPoly(bbox1) || !ValidateObject.CheckPoly(bbox2))
                    {
                        continue;
                    }

                    if (PolygonUtility.AreaPolygon(polySplitList[0]) > targetArea)
                    {
                        polyCirculationList.Add(polySplitList[0]);
                    }
                    if (PolygonUtility.AreaPolygon(polySplitList[1]) > targetArea)
                    {
                        polyCirculationList.Add(polySplitList[1]);
                    }

                    if (bbox1.Lines[0].Length < acceptableWidth || bbox1.Lines[1].Length < acceptableWidth)
                    {
                        polyBrokenList.Add(polySplitList[0]);
                    }
                    else
                    {
                        polyQueue.Enqueue(polySplitList[0]);
                    }
                    if (bbox2.Lines[0].Length < acceptableWidth || bbox2.Lines[1].Length < acceptableWidth)
                    {
                        polyBrokenList.Add(polySplitList[1]);
                    }
                    else
                    {
                        polyQueue.Enqueue(polySplitList[1]);
                    }
                }
                if (ValidateObject.CheckPolyList(polySplitList) && polySplitList.Count < 2)
                {
                    Polygon2d bbox1 = Polygon2d.ByPoints(ReadData.FromPointsGetBoundingPoly(polySplitList[0].Points));
                    if (!ValidateObject.CheckPoly(bbox1))
                    {
                        continue;
                    }
                    if (bbox1.Lines[0].Length < acceptableWidth || bbox1.Lines[1].Length < acceptableWidth)
                    {
                        polyBrokenList.Add(polySplitList[0]);
                    }
                    if (PolygonUtility.AreaPolygon(polySplitList[0]) > targetArea)
                    {
                        polyCirculationList.Add(polySplitList[0]);
                    }
                    else
                    {
                        polyQueue.Enqueue(polySplitList[0]);
                    }
                }
                count += 1;
            }

            for (int i = 0; i < polyQueue.Count; i++)
            {
                polyBrokenList.Add(polyQueue.Dequeue());
            }
            polyAllReturn.Add(polyBrokenList);
            polyAllReturn.Add(polyCirculationList);
            return(polyAllReturn);
        }
        //gets a poly and recursively splits it till acceptabledimension is met and makes a polyorganized list
        internal static void MakePolysOfProportion(Polygon2d poly, List <Polygon2d> polyOrganizedList,
                                                   List <Polygon2d> polycoverList, double acceptableWidth, double targetArea)
        {
            BuildLayout.RECURSE += 1;
            List <double> spanListXY = PolygonUtility.GetSpansXYFromPolygon2d(poly.Points);
            double        spanX = spanListXY[0], spanY = spanListXY[1];
            double        aspRatio = spanX / spanY;
            double        lowRange = 0.3, highRange = 2;
            double        maxValue = 0.70, minValue = 0.35;
            double        threshDistanceX = acceptableWidth;
            double        threshDistanceY = acceptableWidth;
            Random        ran             = new Random();
            bool          square          = true;
            double        div;

            div = BasicUtility.RandomBetweenNumbers(BuildLayout.RANGENERATE, maxValue, minValue);
            if (spanX > threshDistanceX && spanY > threshDistanceY)
            {
                square = false;
            }
            else
            {
                if (aspRatio > lowRange && aspRatio < highRange)
                {
                    square = false;
                }
                else
                {
                    square = true;
                }
            }
            if (square)
            {
                polyOrganizedList.Add(poly);
            }
            else
            {
                Dictionary <string, object> splitResult;
                //poly is rectangle so split it into two and add
                if (spanX > spanY)
                {
                    double dis = spanY * div;
                    int    dir = 1;
                    //splitResult = BasicSplitPolyIntoTwo(poly, 0.5, dir);
                    splitResult = SplitObject.SplitByDistance(poly, ran, dis, dir, BuildLayout.SPACING2);
                    //splitResult = SplitByDistanceFromPoint(poly, dis, dir);
                }
                else
                {
                    double dis = spanX * div;
                    int    dir = 0;
                    //splitResult = BasicSplitPolyIntoTwo(poly, 0.5, dir);
                    splitResult = SplitObject.SplitByDistance(poly, ran, dis, dir, BuildLayout.SPACING2);
                    //splitResult = SplitByDistanceFromPoint(poly, dis, dir);
                }

                List <Polygon2d> polyAfterSplit = (List <Polygon2d>)splitResult["PolyAfterSplit"];
                if (ValidateObject.CheckPolyList(polyAfterSplit))
                {
                    double areaPolA = PolygonUtility.AreaPolygon(polyAfterSplit[0]);
                    double areaPolB = PolygonUtility.AreaPolygon(polyAfterSplit[1]);
                    if (areaPolA > targetArea)
                    {
                        polycoverList.Add(polyAfterSplit[0]);
                    }
                    if (areaPolB > targetArea)
                    {
                        polycoverList.Add(polyAfterSplit[1]);
                    }

                    List <double> spanA = PolygonUtility.GetSpansXYFromPolygon2d(polyAfterSplit[0].Points);
                    List <double> spanB = PolygonUtility.GetSpansXYFromPolygon2d(polyAfterSplit[1].Points);
                    //Trace.WriteLine("RECURSE is : " + RECURSE);
                    if (BuildLayout.RECURSE < 1500)
                    {
                        if ((spanA[0] > 0 && spanA[1] > 0) || (spanB[0] > 0 && spanB[1] > 0))
                        {
                            if (spanA[0] > acceptableWidth && spanA[1] > acceptableWidth)
                            {
                                MakePolysOfProportion(polyAfterSplit[0], polyOrganizedList, polycoverList, acceptableWidth, targetArea);
                            }
                            else
                            {
                                polyOrganizedList.Add(polyAfterSplit[0]);
                                double areaPoly = PolygonUtility.AreaPolygon(polyAfterSplit[0]);
                            }
                            //end of 1st if
                            if (spanB[0] > acceptableWidth && spanB[1] > acceptableWidth)
                            {
                                MakePolysOfProportion(polyAfterSplit[1], polyOrganizedList, polycoverList, acceptableWidth, targetArea);
                            }
                            else
                            {
                                polyOrganizedList.Add(polyAfterSplit[1]);
                            }
                            //end of 2nd if
                        }
                        else
                        {
                            polyOrganizedList.Add(polyAfterSplit[0]);
                            polyOrganizedList.Add(polyAfterSplit[1]);
                        }
                    }
                } // end of if loop , checkingpolylists
            }
        }         // end of function
        public static Dictionary <string, object> FindProgCirculationNetwork(List <DeptData> deptData, Polygon2d buildingOutline, List <Polygon2d> leftOverPoly = null)
        {
            if (!ValidateObject.CheckPoly(buildingOutline))
            {
                return(null);
            }
            if (deptData == null)
            {
                return(null);
            }
            List <Polygon2d>      polygonsAllProgList = new List <Polygon2d>();
            List <DeptData>       deptDataAllDeptList = new List <DeptData>();
            List <List <Line2d> > lineCollection      = new List <List <Line2d> >();

            for (int i = 0; i < deptData.Count; i++)
            {
                if ((deptData[i].DepartmentType.IndexOf(BuildLayout.KPU.ToLower()) != -1 ||
                     deptData[i].DepartmentType.IndexOf(BuildLayout.KPU.ToUpper()) != -1))
                {
                    continue;                                                                      // dont add for KPU
                }
                if (deptData[i].PolyAssignedToDept == null)
                {
                    continue;
                }
                polygonsAllProgList.AddRange(deptData[i].PolyAssignedToDept);
            }
            if (leftOverPoly != null)
            {
                polygonsAllProgList.AddRange(leftOverPoly);
            }
            for (int i = 0; i < polygonsAllProgList.Count; i++)
            {
                polygonsAllProgList[i] = new Polygon2d(polygonsAllProgList[i].Points);
            }

            List <Line2d> networkLine = new List <Line2d>();

            for (int i = 0; i < polygonsAllProgList.Count; i++)
            {
                Polygon2d poly1 = polygonsAllProgList[i];
                for (int j = i + 1; j < polygonsAllProgList.Count; j++)
                {
                    Polygon2d poly2 = polygonsAllProgList[j];
                    Dictionary <string, object> checkNeighbor = PolygonUtility.FindPolyAdjacentEdge(poly1, poly2);
                    if (checkNeighbor != null)
                    {
                        if ((bool)checkNeighbor["Neighbour"] == true)
                        {
                            networkLine.Add((Line2d)checkNeighbor["SharedEdge"]);
                        }
                    }
                }
            }
            List <Line2d> cleanNetworkLines = LineUtility.RemoveDuplicateLines(networkLine);

            cleanNetworkLines = GraphicsUtility.RemoveDuplicateslinesWithPoly(buildingOutline, cleanNetworkLines);
            List <List <string> > deptNeighborNames = new List <List <string> >();

            List <Line2d> onlyOrthoLineList = new List <Line2d>();

            for (int i = 0; i < cleanNetworkLines.Count; i++)
            {
                bool checkOrtho = ValidateObject.CheckLineOrthogonal(cleanNetworkLines[i]);
                if (checkOrtho == true)
                {
                    onlyOrthoLineList.Add(cleanNetworkLines[i]);
                }
            }
            return(new Dictionary <string, object>
            {
                { "CirculationNetwork", (onlyOrthoLineList) },
                { "PolygonsForAllPrograms", (polygonsAllProgList) }
            });
        }
示例#30
0
        //make the given poly all points orthonogonal to each other
        internal static Polygon2d MakePolyPointsOrtho(Polygon2d poly)
        {
            Polygon2d      polyReg        = new Polygon2d(poly.Points);
            List <Point2d> ptForOrthoPoly = new List <Point2d>();

            for (int i = 0; i < polyReg.Points.Count; i++)
            {
                Point2d pt = Point2d.ByCoordinates(polyReg.Points[i].X, polyReg.Points[i].Y);
                ptForOrthoPoly.Add(pt);
            }

            for (int i = 0; i < polyReg.Points.Count; i++)
            {
                int    a = i, b = i + 1;
                double eps = 50;
                if (i == polyReg.Points.Count - 1)
                {
                    b = 0;
                }
                Line2d line = new Line2d(polyReg.Points[a], polyReg.Points[b]);
                if (ValidateObject.CheckLineOrient(line) == -1)
                {
                    //double diffX = Math.Abs(line.StartPoint.X - line.EndPoint.X);
                    //double diffY = Math.Abs(line.StartPoint.Y - line.EndPoint.Y);
                    Point2d cenPoly  = PolygonUtility.CentroidOfPoly(polyReg);
                    Point2d ptEndA   = Point2d.ByCoordinates(polyReg.Points[a].X + eps, polyReg.Points[a].Y);
                    Line2d  refLineA = Line2d.ByStartPointEndPoint(polyReg.Points[a], ptEndA);

                    Point2d ptEndB   = Point2d.ByCoordinates(polyReg.Points[b].X + eps, polyReg.Points[b].Y);
                    Line2d  refLineB = Line2d.ByStartPointEndPoint(polyReg.Points[b], ptEndB);

                    Point2d projectedPtA = GraphicsUtility.ProjectedPointOnLine(refLineB, polyReg.Points[a]);
                    Point2d projectedPtB = GraphicsUtility.ProjectedPointOnLine(refLineA, polyReg.Points[b]);

                    Vector2d vecA       = new Vector2d(projectedPtA, cenPoly);
                    Vector2d vecB       = new Vector2d(projectedPtB, cenPoly);
                    double   vecALength = vecA.Length;
                    double   vecBLength = vecB.Length;
                    if (vecALength > vecBLength)
                    {
                        //ptForOrthoPoly[i] = projectedPtA;
                        ptForOrthoPoly.Insert(b, projectedPtB);
                    }
                    else
                    {
                        //ptForOrthoPoly[i] = projectedPtB;
                        ptForOrthoPoly.Insert(b, projectedPtA);
                    }

                    /*
                     * if (diffX > diffY)
                     * {
                     *  Point2d ptEndA = Point2d.ByCoordinates(polyReg.Points[a].X, polyReg.Points[a].Y + eps);
                     *  Line2d refLineA = Line2d.ByStartPointEndPoint(polyReg.Points[a], ptEndA);
                     *  refLineA = LineUtility.extend(refLineA);
                     *
                     *  Point2d ptEndB = Point2d.ByCoordinates(polyReg.Points[b].X, polyReg.Points[b].Y + eps);
                     *  Line2d refLineB = Line2d.ByStartPointEndPoint(polyReg.Points[b], ptEndB);
                     *  refLineB = LineUtility.extend(refLineB);
                     *
                     *  Point2d projectedPtA = GraphicsUtility.ProjectedPointOnLine(refLineB, polyReg.Points[a]);
                     *  Point2d projectedPtB = GraphicsUtility.ProjectedPointOnLine(refLineA, polyReg.Points[b]);
                     *
                     *  Vector2d vecA = new Vector2d(projectedPtA, cenPoly);
                     *  Vector2d vecB = new Vector2d(projectedPtB, cenPoly);
                     *  double vecALength = vecA.Length;
                     *  double vecBLength = vecB.Length;
                     *  if(vecALength < vecBLength)
                     *  {
                     *      //ptForOrthoPoly[i] = projectedPtA;
                     *      ptForOrthoPoly.Insert(b, projectedPtB);
                     *  }
                     *  else
                     *  {
                     *      //ptForOrthoPoly[i] = projectedPtB;
                     *      ptForOrthoPoly.Insert(b, projectedPtA);
                     *  }
                     * }
                     * else
                     * {
                     *
                     *  Point2d ptEndA = Point2d.ByCoordinates(polyReg.Points[a].X + eps, polyReg.Points[a].Y);
                     *  Line2d refLineA = Line2d.ByStartPointEndPoint(polyReg.Points[a], ptEndA);
                     *  refLineA = LineUtility.extend(refLineA);
                     *
                     *  Point2d ptEndB = Point2d.ByCoordinates(polyReg.Points[b].X + eps, polyReg.Points[b].Y);
                     *  Line2d refLineB = Line2d.ByStartPointEndPoint(polyReg.Points[b], ptEndB);
                     *  refLineB = LineUtility.extend(refLineB);
                     *
                     *  Point2d projectedPtA = GraphicsUtility.ProjectedPointOnLine(refLineB, polyReg.Points[a]);
                     *  Point2d projectedPtB = GraphicsUtility.ProjectedPointOnLine(refLineA, polyReg.Points[b]);
                     *
                     *  Vector2d vecA = new Vector2d(projectedPtA, cenPoly);
                     *  Vector2d vecB = new Vector2d(projectedPtB, cenPoly);
                     *  double vecALength = vecA.Length;
                     *  double vecBLength = vecB.Length;
                     *  if (vecALength < vecBLength)
                     *  {
                     *      //ptForOrthoPoly[i] = projectedPtA;
                     *      ptForOrthoPoly.Insert(b, projectedPtB);
                     *  }
                     *  else
                     *  {
                     *      //ptForOrthoPoly[i] = projectedPtB;
                     *      ptForOrthoPoly.Insert(b, projectedPtB);
                     *  }
                     * }
                     */
                }
            }
            return(new Polygon2d(ptForOrthoPoly));
        }