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