Exemplo n.º 1
0
        //Create Parkinglots along edge
        private void CreateOuterParkingLot(Curve boundaryCurve, LocalRules localRules, Plane plane)
        {
            //Change Curve offset
            BoundingBox bx = boundaryCurve.GetBoundingBox(Plane.WorldXY);

            Point3d[] bxPT          = bx.GetCorners();
            Vector3d  outsideVector = bxPT[0] - bxPT[2];

            outsideVector.Unitize();
            Point3d outsidePT = bxPT[0] + outsideVector;

            Curve[] offsetBoundary = boundaryCurve.Offset(outsidePT, Vector3d.ZAxis, -localRules.BoothDepth, 0.01, CurveOffsetCornerStyle.Sharp);

            //Sometimes offset fails. This checks for that and uses alternative method, less precise method
            if (offsetBoundary[0].GetLength() < (localRules.BoothDepth * 2) + Math.Sqrt((Math.Pow(localRules.BoothDepth, 2) * 2)) + 1)
            {
                offsetBoundary = boundaryCurve.Offset(Plane.WorldXY, localRules.BoothDepth, 0.01, CurveOffsetCornerStyle.Sharp);
                //Check direction
                if (offsetBoundary[0].Contains(boundaryCurve.PointAtStart, Plane.WorldXY, 0.01) == PointContainment.Inside)
                {
                    offsetBoundary = boundaryCurve.Offset(Plane.WorldXY, -localRules.BoothDepth, 0.01, CurveOffsetCornerStyle.Sharp);
                }
            }

            List <Curve> explodeOffsetBoundary = new List <Curve>();

            foreach (var curve in offsetBoundary)
            {
                if (curve is PolylineCurve)
                {
                    explodeOffsetBoundary.AddRange(curve.DuplicateSegments());
                }
                else
                {
                    explodeOffsetBoundary.Add(curve);
                }
            }

            Curve[] offsetBoundaryjoined;
            if (offsetBoundary.Length > 2)
            {
                offsetBoundaryjoined = Curve.JoinCurves(offsetBoundary, 0.5);
            }
            else
            {
                offsetBoundaryjoined = offsetBoundary;
            }



            //Make Outer parkingplots

            foreach (var curve in explodeOffsetBoundary)
            {
                List <Parkingspace> tempSpaces = new List <Parkingspace>();
                double[]            divpar     = curve.DivideByLength(localRules.BoothWidth, true, false, out Point3d[] points);

                //Create Booths
                for (int i = 0; i < points.Length; i++)
                {
                    Vector3d Dir = curve.TangentAt(divpar[i]);
                    Dir.Rotate(Math.PI / 2, Vector3d.ZAxis);
                    Dir.Unitize();
                    if (boundaryCurve.ClosedCurveOrientation() == CurveOrientation.CounterClockwise)
                    {
                        Dir.Reverse();
                    }
                    Dir = Vector3d.Multiply(localRules.BoothDepth, Dir);

                    // Create new parking
                    Plane        boothPlane   = new Plane(points[i], curve.TangentAt(divpar[i]), Dir);
                    Parkingspace parkingspace = new Parkingspace(boothPlane, localRules, false);


                    tempSpaces.Add(parkingspace);
                }

                List <int> spacesToCull = new List <int>();

                // Check if Parkinglot fullfill criterias
                if (boundaryCurve.IsPeriodic != true)
                {
                    for (int j = 0; j < tempSpaces.Count; j++)
                    {
                        Curve boxCurves = tempSpaces[j].ManeuveringBox.ToNurbsCurve();

                        //Check for maneuveringarea
                        if (Intersection.CurveCurve(offsetBoundaryjoined[0], boxCurves, 0.0, 0.001).Count > 1)
                        {
                            spacesToCull.Add(j);
                            continue;
                        }
                        //Check if booths exceed the ends
                        if (offsetBoundaryjoined[0].Contains(tempSpaces[j].Curves.PointAtStart, plane, 0.001) != PointContainment.Coincident)
                        {
                            spacesToCull.Add(j);
                            continue;
                        }
                        if (offsetBoundaryjoined[0].Contains(tempSpaces[j].Curves.PointAtEnd, plane, 0.001) != PointContainment.Coincident)
                        {
                            spacesToCull.Add(j);
                            continue;
                        }
                    }
                    //Check if end booths overlap >180 degress corners
                    for (int i = 5; i < (tempSpaces.Count); i++)
                    {
                        if (spacesToCull.Contains(i))
                        {
                            continue;
                        }
                        if (boundaryCurve.Contains(tempSpaces[i].Curves.PointAtLength(localRules.BoothDepth), Plane.WorldXY, 0.001) != PointContainment.Coincident)
                        {
                            spacesToCull.Add(i);
                            continue;
                        }
                        if (boundaryCurve.Contains(tempSpaces[i].Curves.PointAtLength(tempSpaces[i].Curves.GetLength() - localRules.BoothDepth), Plane.WorldXY, 0.001) != PointContainment.Coincident)
                        {
                            spacesToCull.Add(i);
                            continue;
                        }
                    }
                }

                //Remove Parkinglots that doesn't fullfill criterias
                spacesToCull.Sort();
                spacesToCull.Reverse();
                foreach (int index in spacesToCull)
                {
                    tempSpaces.RemoveAt(index);
                }
                Spaces.AddRange(tempSpaces);
            }
        }
Exemplo n.º 2
0
        //Create inner Parkinglots
        private void CreateInnerParkinglots(Curve boundaryCurve, LocalRules localRules, Plane plane)
        {
            //Create offset curve with outer booth and driveway distance
            BoundingBox bx = boundaryCurve.GetBoundingBox(Plane.WorldXY);

            Point3d[] bxPT          = bx.GetCorners();
            Vector3d  outsideVector = bxPT[0] - bxPT[2];

            outsideVector.Unitize();
            Point3d outsidePT = bxPT[0] + outsideVector;

            Curve[] innerBounderyCrv = boundaryCurve.Offset(outsidePT, Vector3d.ZAxis, -(localRules.BoothDepth + localRules.ManeuveringArea), 0.5, CurveOffsetCornerStyle.Sharp);

            //Sometimes offset fails. This checks for that and uses alternative method, less precise method
            if (innerBounderyCrv[0].GetLength() < ((localRules.BoothDepth + localRules.ManeuveringArea) * 2) + Math.Sqrt((Math.Pow(localRules.BoothDepth + localRules.ManeuveringArea, 2) * 2)) + 1)
            {
                innerBounderyCrv = boundaryCurve.Offset(Plane.WorldXY, localRules.BoothDepth + localRules.ManeuveringArea, 0.01, CurveOffsetCornerStyle.Sharp);
                //Check direction
                if (innerBounderyCrv[0].Contains(boundaryCurve.PointAtStart, Plane.WorldXY, 0.01) == PointContainment.Inside)
                {
                    innerBounderyCrv = boundaryCurve.Offset(Plane.WorldXY, -(localRules.BoothDepth + localRules.ManeuveringArea), 0.01, CurveOffsetCornerStyle.Sharp);
                }
            }
            debug.AddRange(innerBounderyCrv);
            //Create BB and centerlines
            innerBounderyCrv[0].GetBoundingBox(plane, out Box boundarybox);
            Point3d[] boxCorners = boundarybox.GetCorners();
            Line      startLine  = new Line(boxCorners[0], boxCorners[1]);
            Line      endLine    = new Line(boxCorners[3], boxCorners[2]);

            // Direction of inner booths
            Vector3d boothDir = startLine.UnitTangent;

            boothDir.Unitize();
            boothDir = Vector3d.Multiply(localRules.BoothDepth, boothDir);

            //Copy center lines according to distancerules
            List <Curve> copyLines = new List <Curve>();

            for (double i = localRules.BoothDepth; i < startLine.Length;)
            {
                Point3d startPT = startLine.PointAtLength(i);
                Point3d endPT   = endLine.PointAtLength(i);
                copyLines.Add(new Line(startPT, endPT).ToNurbsCurve());
                i = i + (localRules.BoothDepth * 2) + localRules.ManeuveringArea;
            }


            //Find inner curves
            foreach (Curve crvline in copyLines)
            {
                var curveEvent = Intersection.CurveCurve(innerBounderyCrv[0], crvline, 0, 0);
                if (curveEvent != null)
                {
                    List <double> curveT = new List <double>();
                    for (int i = 0; i < curveEvent.Count; i++)
                    {
                        var crvLine = curveEvent[i];
                        curveT.Add(crvLine.ParameterB);
                    }

                    Curve[] curveSplit = crvline.Split(curveT);

                    foreach (Curve curve in curveSplit)
                    {
                        double midT = (curve.Domain.T0 + curve.Domain.T1) / 2;

                        if (innerBounderyCrv[0].Contains(curve.PointAt(midT), Plane.WorldXY, 0).Equals(PointContainment.Inside))
                        {
                            CenterLines.Add(curve);
                        }
                    }
                }
            }

            //Parking Booths
            foreach (Curve curve in CenterLines)
            {
                curve.DivideByLength(localRules.BoothWidth, true, false, out Point3d[] points);
                if (points == null)
                {
                    continue;
                }
                foreach (Point3d point in points)
                {
                    //One way
                    Plane        boothPlane   = new Plane(point, curve.TangentAt(0.1), boothDir);
                    Parkingspace parkingspace = new Parkingspace(boothPlane, localRules, true);
                    parkingLinesLeft.Add(parkingspace);
                    //Opposite way
                    boothDir.Reverse();
                    boothPlane   = new Plane(point, curve.TangentAt(0.1), boothDir);
                    parkingspace = new Parkingspace(boothPlane, localRules, true);
                    parkingLinesLeft.Add(parkingspace);
                    //Return Vector
                    boothDir.Reverse();
                }

                PointCloud startPTsLeft  = new PointCloud();
                PointCloud startPTsRight = new PointCloud();
                PointCloud allStartPT    = new PointCloud();

                //Check for collision with driving path

                List <Parkingspace> finalParkingLinesLeft  = new List <Parkingspace>();
                List <Parkingspace> finalParkingLinesRight = new List <Parkingspace>();
                for (int i = 0; i < parkingLinesLeft.Count; i++)
                {
                    CurveIntersections crvEvent = Intersection.CurveCurve(innerBounderyCrv[0], parkingLinesLeft[i].Curves, 0.0001, 0.0000);
                    if (crvEvent.Count > 0)
                    {
                        parkingEnds.Add(parkingLinesLeft[i].Curves);
                    }
                    else
                    {
                        finalParkingLinesLeft.Add(parkingLinesLeft[i]);
                        startPTsLeft.Add(parkingLinesLeft[i].Curves.PointAtStart);
                        allStartPT.Add(parkingLinesLeft[i].Curves.PointAtStart);
                    }
                }

                for (int i = 0; i < parkingLinesRight.Count; i++)
                {
                    CurveIntersections crvEvent = Intersection.CurveCurve(innerBounderyCrv[0], parkingLinesRight[i].Curves, 0.0001, 0.0000);
                    if (crvEvent.Count > 0)
                    {
                        parkingEnds.Add(parkingLinesRight[i].Curves);
                    }
                    else
                    {
                        finalParkingLinesRight.Add(parkingLinesRight[i]);
                        startPTsRight.Add(parkingLinesRight[i].Curves.PointAtStart);
                        allStartPT.Add(parkingLinesRight[i].Curves.PointAtStart);
                    }
                }



                //try
                //{
                //    //Fix one end
                //    Point3d crvEnd = curve.PointAtEnd;
                //    Curve endCurve = createEnds(innerBounderyCrv, startPTsLeft, startPTsRight, finalParkingLinesLeft, finalParkingLinesRight, crvEnd);
                //    notParkingSpaces.Add(endCurve);
                //    Curve splitCurveOne = splitend(curve, allStartPT, crvEnd);

                //    //Fix the other end
                //    Point3d crvStart = curve.PointAtStart;
                //    endCurve = createEnds(innerBounderyCrv, startPTsLeft, startPTsRight, finalParkingLinesLeft, finalParkingLinesRight, crvStart);
                //    notParkingSpaces.Add(endCurve);
                //    notParkingSpaces.Add(splitend(splitCurveOne, allStartPT, crvStart));

                //}
                //catch
                //{

                //}


                Spaces.AddRange(finalParkingLinesLeft);
                Spaces.AddRange(finalParkingLinesRight);

                parkingLinesLeft.Clear();
                parkingLinesRight.Clear();
            }
            parkingspaceNO = Spaces.Count;
        }