private Curve DrawLineRamp(Curve road, Vector3d axis, int onStart, RampScale scale, double offset) { Point3d start; Vector3d vx; Vector3d vy; if (axis == Vector3d.Unset) { axis = Vector3d.XAxis; } Vector3d axisPerp = new Vector3d(axis); axisPerp.Rotate(-Math.PI / 2, Vector3d.ZAxis); Vector3d roadv = road.TangentAtStart; double angleRoadAxis = Vector3d.VectorAngle(roadv, axis, Plane.WorldXY); if (angleRoadAxis < Math.PI * 0.25 || angleRoadAxis > Math.PI * 1.75 || (angleRoadAxis < Math.PI * 1.25 && angleRoadAxis > Math.PI * 0.75)) { //selectperpvector vy = axisPerp; } else { //selectoriginvector vy = axis; } Point3d testPoint = road.PointAtNormalizedLength(0.5); Vector3d dirInside = new Vector3d(roadv); dirInside.Rotate(-Math.PI / 2, Vector3d.ZAxis); Point3d testPointInside = testPoint + dirInside; Point3d testPointY = testPoint + vy; Curve testLine = new LineCurve(testPointInside, testPointY); var testI = Rhino.Geometry.Intersect.Intersection.CurveCurve(testLine, road, 0, 0); if (testI.Count != 0) { vy.Reverse(); } //true if (onStart == 0) { vx = new Vector3d(vy); vx.Rotate(Math.PI / 2, Vector3d.ZAxis); //vx = axis; // road.TangentAtStart; //if (vx == Vector3d.Unset) // vx = road.TangentAtStart; //vy = new Vector3d(vx); //vy.Rotate(-Math.PI / 2, Vector3d.ZAxis); start = road.PointAtStart + road.TangentAtStart * (800 + offset); start = start + vy * 1000; } //false else { vx = new Vector3d(vy); vx.Rotate(-Math.PI / 2, Vector3d.ZAxis); //vx = -axis; //-road.TangentAtStart; //if (vx == -Vector3d.Unset) // vx = -road.TangentAtStart; //vy = new Vector3d(vx); //vy.Rotate(Math.PI / 2, Vector3d.ZAxis); start = road.PointAtEnd + -road.TangentAtStart * (800 + offset); start = start + vy * 1000; } Point3d second = start + vx * UnderGroundParkingConsts.LinearRampWidth[(int)scale]; Point3d third = second + vy * (20000 + UnderGroundParkingConsts.WithinRadius[(int)scale]); Point3d forth = third - vx * UnderGroundParkingConsts.LinearRampWidth[(int)scale]; PolylineCurve plc = new PolylineCurve(new Point3d[] { start, second, third, forth, start }); return(plc); }
private Curve DrawCurvedRamp(Curve road, Vector3d axis, int onStart, RampScale scale, double beforeRamp, double offset) { Point3d start; Vector3d vx; Vector3d vy; if (axis == Vector3d.Unset) { axis = Vector3d.XAxis; } double afterRamp = 10000 - beforeRamp; Vector3d axisPerp = new Vector3d(axis); axisPerp.Rotate(-Math.PI / 2, Vector3d.ZAxis); Vector3d roadv = road.TangentAtStart; double angleRoadAxis = Vector3d.VectorAngle(roadv, axis, Plane.WorldXY); if (angleRoadAxis < Math.PI * 0.25 || angleRoadAxis > Math.PI * 1.75 || (angleRoadAxis < Math.PI * 1.25 && angleRoadAxis > Math.PI * 0.75)) { //selectperpvector vy = axisPerp; } else { //selectoriginvector vy = axis; } Point3d testPoint = road.PointAtNormalizedLength(0.5); Vector3d dirInside = new Vector3d(roadv); dirInside.Rotate(-Math.PI / 2, Vector3d.ZAxis); Point3d testPointInside = testPoint + dirInside; Point3d testPointY = testPoint + vy; Curve testLine = new LineCurve(testPointInside, testPointY); var testI = Rhino.Geometry.Intersect.Intersection.CurveCurve(testLine, road, 0, 0); if (testI.Count != 0) { vy.Reverse(); } //true if (onStart == 0) { vx = new Vector3d(vy); vx.Rotate(Math.PI / 2, Vector3d.ZAxis); //vx = axis;//road.TangentAtStart; //if (vx == Vector3d.Unset) // vx = road.TangentAtStart; //vy = new Vector3d(vx); //vy.Rotate(-Math.PI / 2, Vector3d.ZAxis); start = road.PointAtStart + vx * (800 + offset); start = start + vy * 1000; } //false else { vx = new Vector3d(vy); vx.Rotate(-Math.PI / 2, Vector3d.ZAxis); //vx = -axis;// - road.TangentAtStart; //if (vx == -Vector3d.Unset) // vx = -road.TangentAtStart; //vy = new Vector3d(vx); //vy.Rotate(Math.PI / 2, Vector3d.ZAxis); start = road.PointAtEnd + vx * (800 + offset); start = start + vy * 1000; } Point3d second = start + vx * UnderGroundParkingConsts.CurveRampWidth[(int)scale]; Point3d third = second + vy * beforeRamp;//(20000 + UnderGroundParkingConsts.WithinRadius[(int)scale]); double innerArcR = UnderGroundParkingConsts.WithinRadius[(int)scale]; double outerArcR = UnderGroundParkingConsts.WithinRadius[(int)scale] + UnderGroundParkingConsts.CurveRampWidth[(int)scale]; Point3d forth = third + vy * innerArcR + vx * innerArcR; // third - vx * UnderGroundParkingConsts.LinearRampWidth[(int)scale]; Point3d fifth = forth + vx * afterRamp; Point3d sixth = fifth + vy * UnderGroundParkingConsts.CurveRampWidth[(int)scale]; Point3d seventh = sixth - vx * afterRamp; Point3d eighth = seventh - vx * outerArcR - vy * outerArcR; Point3d ninth = start; //polyline1 PolylineCurve plc1 = new PolylineCurve(new Point3d[] { start, second, third }); ArcCurve arc1 = new ArcCurve(new Arc(third, vy, forth)); PolylineCurve plc2 = new PolylineCurve(new Point3d[] { forth, fifth, sixth, seventh }); ArcCurve arc2 = new ArcCurve(new Arc(seventh, -vx, eighth)); PolylineCurve plc3 = new PolylineCurve(new Point3d[] { eighth, ninth }); Curve[] curvesToJoin = new Curve[] { plc1, arc1, plc2, arc2, plc3 }; //Rhino.RhinoDoc.ActiveDoc.Objects.Add(Curve.JoinCurves(curvesToJoin)[0]); var joined = Curve.JoinCurves(curvesToJoin); if (joined.Length > 0) { return(joined[0]); } else { return(null); } //return plc; }
public Curve DrawRamp(Plot plot, Vector3d lineAxis, List <Curve> obstacles) { //규모 판별 - 50 이상? 미만? 너비 3.3 or 6.5 , 내반경 5 or 6 //innerboundary 기준 x (도로판별이힘듦)plot boundary 기준으로, '도로'에 '수직? 이어야 하나?' 인 '27m' 이상 길이 확보 가능? -> 직선 램프 //불가능 -> 곡선램프 -> 시작 선, 도로 선, 장애물 RampScale scale = RampScale.Under50; if (require > 50) { scale = RampScale.Over50; } //도로. Curve[] boundaries = plot.Boundary.DuplicateSegments(); List <Curve> roads = new List <Curve>(); for (int i = 0; i < boundaries.Length; i++) { if (plot.Surroundings[i] != 0) { roads.Add(boundaries[i]); } } for (int i = 0; i < roads.Count; i++) { for (int j = 0; j < 2; j++) { for (int l = 0; l < 100; l++) { double offsetTick = 100;//roads[i].GetLength() / 10; if (l * offsetTick > roads[i].GetLength()) { break; } Curve tempRamp = DrawLineRamp(roads[i], lineAxis, j, scale, l * offsetTick); if (tempRamp == null) { continue; } bool collCheck = CollisionCheck(tempRamp, obstacles); RegionContainment isInside = Curve.PlanarClosedCurveRelationship(tempRamp, innerBoundary, Plane.WorldXY, 0); if (collCheck && isInside == RegionContainment.AInsideB) { return(tempRamp); } } } } //for curvedramp for (int i = 0; i < roads.Count; i++) { for (int j = 0; j < 2; j++) { for (int k = 0; k < 10; k++) { for (int l = 0; l < 100; l++) { double offsetTick = 100;//roads[i].GetLength() / 10; if (l * offsetTick > roads[i].GetLength()) { break; } double beforeRamp = 10000 - k * 1000; Curve tempRamp = DrawCurvedRamp(roads[i], lineAxis, j, scale, beforeRamp, l * offsetTick); if (tempRamp == null) { continue; } bool collCheck = CollisionCheck(tempRamp, obstacles); RegionContainment isInside = Curve.PlanarClosedCurveRelationship(tempRamp, innerBoundary, Plane.WorldXY, 0); if (collCheck && isInside == RegionContainment.AInsideB) { return(tempRamp); } } } } } //cant make ramp return(null); }