private bool GetInnerBoundary() { //plot 의 boundary 와 roads 를 사용. var segments = boundary.DuplicateSegments(); double offsetDistance = UnderGroundParkingConsts.Clearance; for (int i = 0; i < segments.Length; i++) { Curve temp = segments[i]; var v = temp.TangentAtStart; v.Rotate(-Math.PI / 2, Vector3d.ZAxis); temp.Translate(v * offsetDistance); segments[i] = temp; } List <Point3d> topoly = new List <Point3d>(); for (int k = 0; k < segments.Length; k++) { int j = (k + 1) % segments.Length; Line li = new Line(segments[k].PointAtStart, segments[k].PointAtEnd); Line lj = new Line(segments[j].PointAtStart, segments[j].PointAtEnd); double paramA; double paramB; var intersect = Rhino.Geometry.Intersect.Intersection.LineLine(li, lj, out paramA, out paramB, 0, false); // 교점이 A 선 위에 있음 bool isparamAonA = paramA >= 0 && paramA <= 1 ? true : false; // 교점이 B 선 위에 있음 bool isparamBonB = paramB >= 0 && paramB <= 1 ? true : false; bool isRightSided = paramA > 1 && paramB > 1 ? true : false; bool isLeftSided = paramA < 0 && paramB < 0 ? true : false; // A 나 B 둘중 한 선의 위에. if (isparamAonA && !isparamBonB || !isparamAonA && isparamBonB) { topoly.Add(li.PointAt(paramA)); //topoly.Add(segments[k].PointAtEnd); //topoly.Add(segments[j].PointAtStart); //k의 endpoint 에서 j의 startpoint로 선 긋는다. } // 두 선 위의 교점에. else if (isparamAonA && isparamBonB) { //교점을 더함 topoly.Add(li.PointAt(paramA)); } //외부에 else { //오른쪽 치우침 if (isRightSided) { topoly.Add(segments[k].PointAtEnd); topoly.Add(segments[j].PointAtStart); } //왼쪽 치우침 else if (isLeftSided) { topoly.Add(segments[k].PointAtEnd); topoly.Add(segments[j].PointAtStart); } //일반 else { topoly.Add(li.PointAt(paramA)); } } } topoly.Add(topoly[0]); var tempcurve = new PolylineCurve(topoly); var rotation = tempcurve.ClosedCurveOrientation(Vector3d.ZAxis); var selfintersection = Rhino.Geometry.Intersect.Intersection.CurveSelf(tempcurve, 0); var parameters = selfintersection.Select(n => n.ParameterA).ToList(); parameters.AddRange(selfintersection.Select(n => n.ParameterB)); var spl = tempcurve.Split(parameters); var f = CommonFunc.NewJoin(spl); var merged = f.Where(n => n.ClosedCurveOrientation(Vector3d.ZAxis) == rotation).ToList(); if (merged.Count == 0) { return(false); } merged = merged.OrderByDescending(n => n.GetArea()).ToList(); innerBoundary = merged[0]; return(true); }
//채광방향 public static List <Curve> Lighting(Curve roadCenter, Plot plot, double aptAngle) { double d = 0; if (plot.PlotType != PlotTypes.상업지역) { if (plot.LegalMaxF <= 7) { d = 0.25; } else { d = 0.5; } } else { d = 0.25; } Curve basecurve = null; var cp = AreaMassProperties.Compute(plot.Boundary).Centroid; var basev = Vector3d.XAxis; basev.Rotate(aptAngle, Vector3d.ZAxis); var bounding = plot.Boundary.GetBoundingBox(false); basecurve = new LineCurve(cp - basev * bounding.Diagonal.Length / 2, cp + basev * bounding.Diagonal.Length / 2); List <Curve> result = new List <Curve>(); Curve last = roadCenter.DuplicateCurve(); double pheight = 3.3; double fheight = 2.8; int floor = plot.LegalMaxF; List <Curve> debug = new List <Curve>(); for (int i = 0; i < floor; i++) { var height = pheight + fheight * i; var distance = d * (height - pheight); var segments = roadCenter.DuplicateSegments(); for (int j = 0; j < segments.Length; j++) { var ps = segments[j].PointAtStart; var pe = segments[j].PointAtEnd; double ds = 0; double de = 0; basecurve.ClosestPoint(ps, out ds); basecurve.ClosestPoint(pe, out de); Vector3d vs = basecurve.PointAt(ds) - ps; Vector3d ve = basecurve.PointAt(de) - pe; vs.Unitize(); ve.Unitize(); var mp = segments[j].PointAtNormalizedLength(0.5); var ts = mp + vs; var te = mp + ve; if (roadCenter.Contains(ts) == PointContainment.Inside) { segments[j].Translate(vs * distance); } else if (roadCenter.Contains(te) == PointContainment.Inside) { segments[j].Translate(ve * distance); } segments[j].Translate(Vector3d.ZAxis * height); } List <Point3d> topoly = new List <Point3d>(); for (int k = 0; k < segments.Length; k++) { int j = (k + 1) % segments.Length; Line li = new Line(segments[k].PointAtStart, segments[k].PointAtEnd); Line lj = new Line(segments[j].PointAtStart, segments[j].PointAtEnd); double paramA; double paramB; var intersect = Rhino.Geometry.Intersect.Intersection.LineLine(li, lj, out paramA, out paramB, 0, false); topoly.Add(li.PointAt(paramA)); } topoly.Add(topoly[0]); var tempcurve = new PolylineCurve(topoly); var rotation = tempcurve.ClosedCurveOrientation(Vector3d.ZAxis); var selfintersection = Rhino.Geometry.Intersect.Intersection.CurveSelf(tempcurve, 0); var parameters = selfintersection.Select(n => n.ParameterA).ToList(); parameters.AddRange(selfintersection.Select(n => n.ParameterB)); var spl = tempcurve.Split(parameters); var f = NewJoin(spl); var merged = f.Where(n => n.ClosedCurveOrientation(Vector3d.ZAxis) == rotation).ToList(); debug.AddRange(merged); for (int j = merged.Count - 1; j >= 0; j--) { var tc = merged[j].DuplicateCurve(); tc.Translate(Vector3d.ZAxis * -tc.PointAtStart.Z); if (Curve.CreateBooleanDifference(tc, last).Length == 0) { last = tc; result.Add(merged[j]); } } } return(result); }