private Rectangle3d outerRectFinder(Polyline convexHull) { double solAngle = 0; double solArea = double.MaxValue; Line[] edges = convexHull.GetSegments(); for (int i = 0; i < edges.Length; i++) { double tempAngle = Vector3d.VectorAngle(edges[i].UnitTangent, Vector3d.XAxis) * Math.Sign(Vector3d.CrossProduct(edges[i].UnitTangent, Vector3d.XAxis).Z); Polyline polylineClone = new Polyline(convexHull); polylineClone.Transform(Transform.Rotation(tempAngle, Point3d.Origin)); BoundingBox tempBox = polylineClone.BoundingBox; double tempArea = tempBox.Diagonal.X * tempBox.Diagonal.Y; if (tempArea < solArea) { solArea = tempArea; solAngle = tempAngle; } } Polyline polyClone = new Polyline(convexHull); polyClone.Transform(Transform.Rotation(solAngle, Point3d.Origin)); BoundingBox solBox = polyClone.BoundingBox; Rectangle3d solRect = new Rectangle3d(new Plane(solBox.Min, Vector3d.ZAxis), solBox.Max.X - solBox.Min.X, solBox.Max.Y - solBox.Min.Y); solRect.Transform(Transform.Rotation(-solAngle, Point3d.Origin)); return(solRect); }
public static Rectangle3d CreateOutline(Point3d centroid, double width, double height, int rotation) { Point3d pointA = centroid - new Vector3d(width / 2, -height / 2, 0); Point3d pointB = centroid + new Vector3d(width / 2, -height / 2, 0); Rectangle3d rect = new Rectangle3d(Plane.WorldXY, pointA, pointB); double rotRadians = (double)rotation / 360 * 2 * Math.PI; Transform trans = Transform.Rotation(rotRadians, Vector3d.ZAxis, centroid); rect.Transform(trans); return(rect); }
private Rectangle3d TranslateRect(Point3d pt, Rectangle3d r0) { Vector3d c0 = new Vector3d(AreaMassProperties.Compute(r0.ToNurbsCurve()).Centroid); Vector3d tg = new Vector3d(pt); Vector3d t0 = Vector3d.Subtract(tg, c0); Rectangle3d rNew0 = new Rectangle3d(r0.Plane, r0.Width, r0.Height); rNew0.Transform(Transform.Translation(t0)); return(rNew0); }
public static BoxElement BoxFromString(string data, Curve bounds) { var dims = bounds.GetBoundingBox(Plane.WorldXY); var maxCorner = dims.Max; var minCorner = dims.Min; var range = maxCorner.X - minCorner.X; var rangeInc = range / 6; var mid = (maxCorner + minCorner) / 2; var reflectionPlane = Plane.WorldZX; reflectionPlane.Origin = mid; var xform = Transform.Mirror(reflectionPlane); var splitData = data.Split(':'); var lang = splitData[0].Split('_')[1].Split('/'); var adverb = lang[0]; var verb = lang[1]; var coords = splitData[1].Replace("(", "").Replace(")", "").Split(','); var startPt = new Point3d(Convert.ToDouble(coords[0]) * rangeInc, Convert.ToDouble(coords[1]) * rangeInc, 0); var endPt = new Point3d(Convert.ToDouble(coords[2]) * rangeInc, Convert.ToDouble(coords[3]) * rangeInc, 0); startPt = startPt + minCorner; endPt = endPt + minCorner; var boxGeo = new Rectangle3d(Plane.WorldXY, startPt, endPt).ToNurbsCurve(); boxGeo.Transform(xform); return(new BoxElement(boxGeo, verb, adverb)); }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { bool Oratation = false; double Scale = 1; Transform Trans = new Transform(); if (!DA.GetData(0, ref Scale)) { return; } if (!DA.GetData(1, ref Oratation)) { return; } if (Scale == 0) { this.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Scale 不能为0"); } Scale = Math.Abs(Scale); PaperSize Paper = this.GetPaperSize(this.DrawingFrameType); Rectangle3d Rect = new Rectangle3d(Plane.WorldXY, Paper.Width, Paper.Height); Trans = Transform.Scale(Rect.Center, Scale); Matrix Matrix = new Matrix(Trans); if (Oratation) { //矩阵的变换顺序 Trans = Transform.Multiply(Trans, Transform.Rotation(Math.PI / 2, Rect.Center)); } Rect.Transform(Trans); DA.SetData(0, Rect); }
protected override void SolveInstance(IGH_DataAccess DA) { List <Curve> boundary = new List <Curve>(); DA.GetDataList <Curve>("Boundary", boundary); int Res = -1; DA.GetData <int>("Resolution", ref Res); string folderPath = string.Empty; DA.GetData <string>("Target Folder", ref folderPath); if (!folderPath.EndsWith(@"\")) { folderPath = folderPath + @"\"; } string prefix = string.Empty; DA.GetData <string>("Prefix", ref prefix); string URL = string.Empty; DA.GetData <string>("REST URL", ref URL); if (URL.EndsWith(@"/")) { URL = URL + "export?"; } bool run = false; DA.GetData <bool>("run", ref run); string userSRStext = string.Empty; DA.GetData <string>("User Spatial Reference System", ref userSRStext); string imageType = string.Empty; DA.GetData <string>("Image Type", ref imageType); ///GDAL setup RESTful.GdalConfiguration.ConfigureOgr(); ///TODO: implement SetCRS here. ///Option to set CRS here to user-defined. Needs a SetCRS global variable. //string userSRStext = "EPSG:4326"; OSGeo.OSR.SpatialReference userSRS = new OSGeo.OSR.SpatialReference(""); userSRS.SetFromUserInput(userSRStext); int userSRSInt = Int16.Parse(userSRS.GetAuthorityCode(null)); ///Set transform from input spatial reference to Rhino spatial reference OSGeo.OSR.SpatialReference rhinoSRS = new OSGeo.OSR.SpatialReference(""); rhinoSRS.SetWellKnownGeogCS("WGS84"); ///This transform moves and scales the points required in going from userSRS to XYZ and vice versa Transform userSRSToModelTransform = Heron.Convert.GetUserSRSToModelTransform(userSRS); Transform modelToUserSRSTransform = Heron.Convert.GetModelToUserSRSTransform(userSRS); GH_Structure <GH_String> mapList = new GH_Structure <GH_String>(); GH_Structure <GH_String> mapquery = new GH_Structure <GH_String>(); GH_Structure <GH_Rectangle> imgFrame = new GH_Structure <GH_Rectangle>(); FileInfo file = new FileInfo(folderPath); file.Directory.Create(); string size = string.Empty; if (Res != 0) { size = "&size=" + Res + "%2C" + Res; } for (int i = 0; i < boundary.Count; i++) { GH_Path path = new GH_Path(i); ///Get image frame for given boundary BoundingBox imageBox = boundary[i].GetBoundingBox(false); imageBox.Transform(modelToUserSRSTransform); ///Make sure to have a rect for output Rectangle3d rect = BBoxToRect(imageBox); ///Query the REST service string restquery = URL + ///legacy method for creating bounding box string "bbox=" + imageBox.Min.X + "%2C" + imageBox.Min.Y + "%2C" + imageBox.Max.X + "%2C" + imageBox.Max.Y + "&bboxSR=" + userSRSInt + size + //"&layers=&layerdefs=" + "&imageSR=" + userSRSInt + //"&transparent=false&dpi=&time=&layerTimeOptions=" + "&format=" + imageType; // + //"&f=json"; string restqueryJSON = restquery + "&f=json"; string restqueryImage = restquery + "&f=image"; mapquery.Append(new GH_String(restqueryImage), path); string result = string.Empty; ///Get extent of image from arcgis rest service as JSON result = Heron.Convert.HttpToJson(restqueryJSON); JObject jObj = JsonConvert.DeserializeObject <JObject>(result); if (!jObj.ContainsKey("href")) { restqueryJSON = restqueryJSON.Replace("export?", "exportImage?"); restqueryImage = restqueryImage.Replace("export?", "exportImage?"); mapquery.RemovePath(path); mapquery.Append(new GH_String(restqueryImage), path); result = Heron.Convert.HttpToJson(restqueryJSON); jObj = JsonConvert.DeserializeObject <JObject>(result); } if (run) { Point3d extMin = new Point3d((double)jObj["extent"]["xmin"], (double)jObj["extent"]["ymin"], 0); Point3d extMax = new Point3d((double)jObj["extent"]["xmax"], (double)jObj["extent"]["ymax"], 0); rect = new Rectangle3d(Plane.WorldXY, extMin, extMax); rect.Transform(userSRSToModelTransform); ///Download image from source ///Catch if JSON query throws an error string imageQueryJSON = jObj["href"].ToString(); using (WebClient webC = new WebClient()) { try { if (!String.IsNullOrEmpty(imageQueryJSON)) { webC.DownloadFile(imageQueryJSON, folderPath + prefix + "_" + i + "." + imageType); webC.Dispose(); } else { webC.DownloadFile(restqueryImage, folderPath + prefix + "_" + i + "." + imageType); webC.Dispose(); } } catch (WebException e) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, e.Message); webC.DownloadFile(restqueryImage, folderPath + prefix + "_" + i + "." + imageType); webC.Dispose(); } } } var bitmapPath = folderPath + prefix + "_" + i + "." + imageType; mapList.Append(new GH_String(bitmapPath), path); imgFrame.Append(new GH_Rectangle(rect), path); AddPreviewItem(bitmapPath, rect); } DA.SetDataTree(0, mapList); DA.SetDataTree(1, imgFrame); DA.SetDataTree(2, mapquery); }
private IList <Rectangle3d> CheckFit(BoundingBox bx, Rectangle3d rect, Curve boundary, double offset, bool withRotation, List <Point3d> outPts, double searchSpacing, bool axisAligned, List <Vector3d> vs) { bool IsRotated = false; bool searching = true; double angle = 1.5708; List <double> spacing = FindSpacing(rect, offset); IList <Rectangle3d> tRects = new List <Rectangle3d>(); double dX = searchSpacing; double dY = searchSpacing; double xMin = bx.Min.X; double yMin = bx.Min.Y; Point3d p = new Point3d(xMin, yMin, 0.0); Vector3d translationVector = new Vector3d(rect.Plane.XAxis.X, rect.Plane.YAxis.Y, 1); translationVector.Unitize(); for (double y = yMin; y < bx.Max.Y; y += dY) { for (double x = xMin; x < bx.Max.X; x += dX) { Vector3d v = new Vector3d(x, y, 0.0); Vector3d pv = new Vector3d(p); if (axisAligned) { pv = new Vector3d(translationVector.X * dX, translationVector.Y * dY, 1); } Vector3d toVector = Vector3d.Add(v, pv); Point3d pNew = new Point3d(toVector); p = pNew; PointContainment pc = boundary.Contains(p, Plane.WorldXY, 0.1); if (pc == PointContainment.Inside) { // Translate rect to new position Rectangle3d tRect = TranslateRect(p, rect); // Check containment of rect bool IsContained = BoundaryContainsCurve(tRect.ToNurbsCurve(), boundary); if (!IsContained && withRotation && !searching) { tRect.Transform(Transform.Rotation(angle, p)); IsContained = BoundaryContainsCurve(tRect.ToNurbsCurve(), boundary); IsRotated = true; } if (IsContained) { if (searching) { searching = false; dX = spacing[0]; dY = spacing[1]; xMin = (1 - bx.Min.X % p.X) * p.X; } outPts.Add(p); vs.Add(pv); tRects.Add(tRect); } if (IsRotated && withRotation) { // Update spacing double t = dX; dX = dY; dY = t; IsRotated = false; } } } } return(tRects); }
/// <summary> /// Given an input manifest of named values between zero and one, generate a drawing. /// </summary> /// <param name="input"></param> public DrawingManifest(InputManifest input) { // Parse adjacent // Generate anchor points from input.Adjacent var position = 0.4 * input.Adjacent; var BottomLeft = new Point3d(0.5 - position, 0, 0); var TopLeft = new Point3d(0.5 - position, 1, 0); var BottomRight = new Point3d(0.5 + position, 0, 0); var TopRight = new Point3d(0.5 + position, 1, 0); // Generate interior points from input.Openings var pointCount = Convert.ToInt32(Math.Round(input.Openings * 9)) + 3; double step = 1.0 / pointCount; var leftPoints = new List <Point3d>(); var rightPoints = new List <Point3d>(); var r = new Random(Convert.ToInt32(input.Tutorial * 100)); var rotateL = Transform.Rotation((input.Parallel * 20) * (Math.PI / 180), Vector3d.ZAxis, new Point3d(input.Adjacent, input.Adjacent, 0)); var rotateR = Transform.Rotation((input.Parallel * -20) * (Math.PI / 180), Vector3d.ZAxis, new Point3d(1 - input.Adjacent, 1 - input.Adjacent, 0)); for (var i = 1; i < pointCount; i++) { var y = i * step; var x = r.NextDouble() * (input.Openings * 0.25); var ptLeft = new Point3d((0.5 - position - x), y, 0); var ptRight = new Point3d((0.5 + position + x), y, 0); ptLeft.Transform(rotateL); ptRight.Transform(rotateR); leftPoints.Add(ptLeft); rightPoints.Add(ptRight); } var leftEdgePoints = new List <Point3d>() { BottomLeft }; leftEdgePoints.AddRange(leftPoints); leftEdgePoints.Add(TopLeft); var rightEdgePoints = new List <Point3d>() { BottomRight }; rightEdgePoints.AddRange(rightPoints); rightEdgePoints.Add(TopRight); // Generate polylines var leftEdge = new Polyline(leftEdgePoints); var rightEdge = new Polyline(rightEdgePoints); // Push lines to output Debug.Add(RhinoPolylineToSvgar(leftEdge)); Debug.Add(RhinoPolylineToSvgar(rightEdge)); // Thicken polylines var thickenL = Transform.Translation(new Vector3d(-0.001, 0, 0)); var thickenR = Transform.Translation(new Vector3d(0.001, 0, 0)); var leftThicken = new Polyline(leftEdgePoints); leftThicken.Transform(thickenL); var rightThicken = new Polyline(rightEdgePoints); rightThicken.Transform(thickenR); Debug.Add(RhinoPolylineToSvgar(leftThicken)); Debug.Add(RhinoPolylineToSvgar(rightThicken)); var leftThicken2 = new Polyline(leftEdgePoints); leftThicken2.Transform(thickenL); leftThicken2.Transform(thickenL); var rightThicken2 = new Polyline(rightEdgePoints); rightThicken2.Transform(thickenR); rightThicken2.Transform(thickenR); Debug.Add(RhinoPolylineToSvgar(leftThicken2)); Debug.Add(RhinoPolylineToSvgar(rightThicken2)); // Offset polylines var offsetL = Transform.Translation(new Vector3d(-0.01, 0, 0)); var offsetR = Transform.Translation(new Vector3d(0.01, 0, 0)); var leftOffset = new Polyline(leftEdgePoints); leftOffset.Transform(offsetL); var rightOffset = new Polyline(rightEdgePoints); rightOffset.Transform(offsetR); Debug.Add(RhinoPolylineToSvgar(leftOffset)); Debug.Add(RhinoPolylineToSvgar(rightOffset)); var leftOffsetThicken = new Polyline(leftEdgePoints); leftOffsetThicken.Transform(offsetL); leftOffsetThicken.Transform(thickenL); var rightOffsetThicken = new Polyline(rightEdgePoints); rightOffsetThicken.Transform(offsetR); rightOffsetThicken.Transform(thickenR); Debug.Add(RhinoPolylineToSvgar(leftOffsetThicken)); Debug.Add(RhinoPolylineToSvgar(rightOffsetThicken)); //Edges.Add(RhinoPolylineToSvgar(leftEdge)); //Edges.Add(RhinoPolylineToSvgar(rightEdge)); // Extend line segments var lex = new List <Line>(); var rex = new List <Line>(); for (var i = 0; i < leftEdge.SegmentCount; i++) { var l = input.Disjoint * 0.15; var cL = leftEdge.SegmentAt(i); var cR = rightEdge.SegmentAt(i); var cLextended = new Line(cL.From, cL.To); cLextended.Extend(l, l); var cRextended = new Line(cR.From, cR.To); cRextended.Extend(l, l); var cLexA = new Line(cL.From, cLextended.From); var cLexB = new Line(cL.To, cLextended.To); var cRexA = new Line(cR.From, cRextended.From); var cRexB = new Line(cR.To, cRextended.To); lex.AddRange(new List <Line>() { cLexA, cLexB }); rex.AddRange(new List <Line>() { cRexA, cRexB }); } var movedLex = new List <Line>(); var movedRex = new List <Line>(); lex.ForEach(x => { var tx = Transform.Translation(new Vector3d(x.To - x.From) * 0.25); x.Transform(tx); movedLex.Add(x); }); rex.ForEach(x => { var tx = Transform.Translation(new Vector3d(x.To - x.From) * 0.25); x.Transform(tx); movedRex.Add(x); }); for (var i = 0; i < movedLex.Count; i++) { Debug.Add(RhinoPolylineToSvgar(new Polyline(new List <Point3d>() { movedLex[i].From, movedLex[i].To }))); Debug.Add(RhinoPolylineToSvgar(new Polyline(new List <Point3d>() { movedRex[i].From, movedRex[i].To }))); //var lexSegs = PolylineToDashedLine(new Polyline(new List<Point3d>() { movedLex[i].From, movedLex[i].To }), 0.15); //var rexSegs = PolylineToDashedLine(new Polyline(new List<Point3d>() { movedRex[i].From, movedRex[i].To }), 0.15); //var segs = new List<Polyline>(); //segs.AddRange(lexSegs); //segs.AddRange(rexSegs); //segs.ForEach(x => //{ // Debug.Add(RhinoPolylineToSvgar(x)); //}); //Extensions.Add(RhinoPolylineToSvgar(new Polyline(new List<Point3d>() { movedLex[i].From, movedLex[i].To }))); //Extensions.Add(RhinoPolylineToSvgar(new Polyline(new List<Point3d>() { movedRex[i].From, movedRex[i].To }))); } for (var i = 0; i < movedLex.Count; i += 2) { var crvA = movedLex[i]; var targetA = crvA.To.X > crvA.From.X ? new Point3d(rightEdge.SegmentAt(i / 2).To.X, crvA.To.Y, 0) : new Point3d(0, crvA.To.Y, 0); var crvB = movedLex[i + 1]; var targetB = crvB.To.X > crvB.From.X ? new Point3d(rightEdge.SegmentAt(i / 2).From.X, crvB.To.Y, 0) : new Point3d(0, crvB.To.Y, 0); var crvC = movedRex[i]; var targetC = crvC.To.X < crvC.From.X ? new Point3d(leftEdge.SegmentAt(i / 2).To.X, crvC.To.Y, 0) : new Point3d(1, crvC.To.Y, 0); var crvD = movedRex[i + 1]; var targetD = crvD.To.X < crvD.From.X ? new Point3d(leftEdge.SegmentAt(i / 2).From.X, crvD.To.Y, 0) : new Point3d(1, crvD.To.Y, 0); var ext = new List <Line>() { new Line(crvA.To, targetA), new Line(crvB.To, targetB), new Line(crvC.To, targetC), new Line(crvD.To, targetD) }; var allExtensions = new List <Polyline>(); ext.ForEach(x => { var scale = Transform.Scale(x.From, input.Disjoint); if (x.To.X > 0 && x.To.X < 1) { x.Transform(scale); } allExtensions.Add(new Polyline(new List <Point3d>() { x.From, x.To })); }); allExtensions.ForEach(x => { Debug.Add(RhinoPolylineToSvgar(x)); //PolylineToDashedLine(x, 0.15).ForEach(y => //{ // Debug.Add(RhinoPolylineToSvgar(y)); //}); //Extensions.Add(RhinoPolylineToSvgar(x)); }); } var largeLines = new List <Polyline>(); for (var i = 0; i < leftEdge.SegmentCount; i++) { var lc = leftEdge.SegmentAt(i); var rc = rightEdge.SegmentAt(i); var threshold = input.Largethreshold; if (lc.ToNurbsCurve().GetLength() > threshold / 2) { var largeC = new Line(lc.From, lc.To); largeC.ExtendThroughBox(new BoundingBox(new Point3d(0, 0, 0), new Point3d(1, 1, 1))); var largeCL = new Line(largeC.From, largeC.To); var largeCR = new Line(largeC.From, largeC.To); var moveR = Transform.Translation(new Vector3d(0.04, 0, 0)); var moveL = Transform.Translation(new Vector3d(-0.04, 0, 0)); largeCL.Transform(moveL); largeCR.Transform(moveR); largeLines.Add(new Polyline(new List <Point3d>() { new Point3d(largeCL.From.X - (0.04 * input.Parallel), largeCL.From.Y, 0), largeCL.To })); //largeLines.Add(new Polyline(new List<Point3d>() { largeC.From, largeC.To })); //largeLines.Add(new Polyline(new List<Point3d>() { new Point3d(largeCR.From.X + (0.04 * input.Parallel), largeCR.From.Y, 0), largeCR.To })); } if (rc.ToNurbsCurve().GetLength() > threshold / 2) { var largeC = new Line(rc.From, rc.To); largeC.ExtendThroughBox(new BoundingBox(new Point3d(0, 0, 0), new Point3d(1, 1, 1))); var largeCL = new Line(largeC.From, largeC.To); var largeCR = new Line(largeC.From, largeC.To); var moveR = Transform.Translation(new Vector3d(0.02, 0, 0)); var moveL = Transform.Translation(new Vector3d(-0.02, 0, 0)); largeCL.Transform(moveL); largeCR.Transform(moveR); //largeLines.Add(new Polyline(new List<Point3d>() { largeCL.From, new Point3d(largeCL.To.X - (0.04 * input.Parallel), largeCL.To.Y, 0) })); //largeLines.Add(new Polyline(new List<Point3d>() { largeC.From, largeC.To })); largeLines.Add(new Polyline(new List <Point3d>() { largeCR.From, new Point3d(largeCR.To.X + (0.04 * input.Parallel), largeCR.To.Y, 0) })); } } largeLines.ForEach(x => { PolylineToDashedLine(x, 0.02).ForEach(y => { Debug.Add(RhinoPolylineToSvgar(y)); }); //Parallels.Add(RhinoPolylineToSvgar(x)); }); var proportion = leftEdge.ToNurbsCurve().GetLength() / rightEdge.ToNurbsCurve().GetLength(); var sL = 0.25 * input.Porosity * proportion; var sR = 0.25 * input.Porosity * (1 / proportion); var iL = new Interval(-sL / 2, sL / 2); var iR = new Interval(-sR / 2, sR / 2); var anchorL = new Plane(new Point3d(0.2 * (1 - input.Adjacent), 0.3 * (1 - input.Adjacent), 0), Vector3d.ZAxis); var rectL = new Rectangle3d(anchorL, iL, iL); var rotL = Transform.Rotation((-90 * input.Parallel) * (Math.PI / 180), anchorL.Origin); var stretchL = Transform.Scale(anchorL, 1, 1 + (input.Porosity * proportion), 1); rectL.Transform(rotL); rectL.Transform(stretchL); var rectL2 = rectL.ToPolyline().Duplicate(); rectL2.Transform(Transform.Translation(rectL.Plane.YAxis * -0.2)); var rectL3 = rectL.ToPolyline().Duplicate(); rectL3.Transform(Transform.Translation(rectL.Plane.YAxis * -0.4)); var anchorR = new Plane(new Point3d(1 - (0.2 * (1 - input.Adjacent)), 1 - (0.3 * (1 - input.Adjacent)), 0), Vector3d.ZAxis); var rectR = new Rectangle3d(anchorR, iR, iR); var rotR = Transform.Rotation((-90 * input.Parallel) * (Math.PI / 180), anchorR.Origin); var stretchR = Transform.Scale(anchorR, 1, 1 + (input.Porosity * (1 / proportion)), 1); rectR.Transform(rotR); rectR.Transform(stretchR); var rectR2 = rectR.ToPolyline().Duplicate(); rectR2.Transform(Transform.Translation(rectR.Plane.YAxis * 0.2)); var rectR3 = rectR.ToPolyline().Duplicate(); rectR3.Transform(Transform.Translation(rectR.Plane.YAxis * 0.4)); var allRects = new List <Polyline>() { rectL.ToPolyline(), rectL2, rectL3, rectR.ToPolyline(), rectR2, rectR3 }; var allRectsThickened = new List <Polyline>(allRects); allRectsThickened.ForEach(x => { var left = new Polyline(x); left.Transform(thickenL); allRects.Add(left); var right = new Polyline(x); right.Transform(thickenR); allRects.Add(right); }); var mPlane = Plane.WorldZX; mPlane.Origin = new Point3d(0.5, 0.5, 0); var mirror = Transform.Mirror(mPlane); allRects.ForEach(x => { Debug.Add(RhinoPolylineToSvgar(x)); //Holes.Add(RhinoPolylineToSvgar(x)); var mx = x.Duplicate(); mx.Transform(mirror); Debug.Add(RhinoPolylineToSvgar(mx)); //Holes.Add(RhinoPolylineToSvgar(mx)); }); }
private static double maxRectDirection(Plot plot) { Polyline x; plot.Boundary.TryGetPolyline(out x); //parameters int gridResolution = 23; int angleResolution = 23; int ratioResolution = 5; int binarySearchIteration = 7; double ratioMaximum = 100; int gridSubResolution = 4; int angleSubResolution = 3; int ratioSubResolution = 4; int subIter = 4; double convergenceFactor = 1.1; double maxR = ratioMaximum; int binaryIter = binarySearchIteration; int rRes = ratioResolution; double alpha = 0.01; int edgeAngleNum = 5; //sub constants double gridDom = 0.3; double angleDom = 0.3; double ratioDom = 0.3; //plot Polyline xcurve = x; Curve plotCurve = xcurve.ToNurbsCurve(); //loop start parameters double areaMax = 0; double solWidth = 0; Point3d solPoint = new Point3d(0, 0, 0); double solR = 15; double solAngle = 0; //output List <Point3d> coreOri = new List <Point3d>(); List <Rectangle3d> coreShape = new List <Rectangle3d>(); //search space List <double> angles = new List <double>(); for (int i = 0; i < angleResolution; i++) { angles.Add(Math.PI * 2 * i / angleResolution); } List <Line> outlineSegments = x.GetSegments().ToList(); RhinoList <Line> outSegRL = new RhinoList <Line>(outlineSegments); List <double> outlineSegLength = outlineSegments.Select(n => n.Length).ToList(); outSegRL.Sort(outlineSegLength.ToArray()); outlineSegments = outSegRL.ToList(); outlineSegments.Reverse(); for (int i = 0; i < Math.Min(edgeAngleNum, outlineSegments.Count); i++) { Vector3d vector = outlineSegments[i].UnitTangent; if (vector.Y < 0) { vector.Reverse(); } double angleTemp = -Math.Acos(Vector3d.Multiply(Vector3d.XAxis, vector)); angles.Add(angleTemp); angles.Add(angleTemp + Math.PI / 2); } //loop for (int ang = 0; ang < angles.Count; ang++) { Polyline xClone = new Polyline(x); xClone.Transform(Transform.Rotation(angles[ang], new Point3d(0, 0, 0))); //find bounding box, grid dimensions var bBox = xClone.BoundingBox; Point3d minP = bBox.Min; Point3d maxP = bBox.Max; List <double> ressG = new List <double>(); ressG.Add(maxP.X - minP.X - 2 * alpha); ressG.Add(maxP.Y - minP.Y - 2 * alpha); List <double> resG = new List <double>(ressG.Select(val => val / gridResolution)); //1st search for (int i = 0; i < gridResolution + 1; i++) { //create lines Line lineY = new Line(new Point3d(minP.X + alpha + i * resG[0], minP.Y, 0), new Point3d(minP.X + alpha + i * resG[0], maxP.Y, 0)); Line lineX = new Line(new Point3d(minP.X, minP.Y + i + alpha * resG[1], 0), new Point3d(maxP.X, minP.Y + alpha + i * resG[1], 0)); //create mid points of segments List <Point3d> midsX = new List <Point3d>(intersectionMids(lineX, xClone)); List <Point3d> midsY = new List <Point3d>(intersectionMids(lineY, xClone)); List <Point3d> mids = new List <Point3d>(); foreach (Point3d j in midsX) { mids.Add(j); } foreach (Point3d j in midsY) { mids.Add(j); } foreach (Point3d j in mids) { //get max height and max width Line midlineY = new Line(new Point3d(j.X, minP.Y, 0), new Point3d(j.X, maxP.Y, 0)); Line midlineX = new Line(new Point3d(minP.X, j.Y, 0), new Point3d(maxP.X, j.Y, 0)); List <Point3d> widthP = new List <Point3d>(intersectionPoints(midlineX, xClone)); List <Point3d> heightP = new List <Point3d>(intersectionPoints(midlineY, xClone)); List <double> widthV = new List <double>(); List <double> heightV = new List <double>(); foreach (Point3d k in widthP) { widthV.Add(k.DistanceTo(j)); } foreach (Point3d k in heightP) { heightV.Add(k.DistanceTo(j)); } double maxWidth; double maxHeight; if (widthV.Count == 0) { maxWidth = 0; } else { maxWidth = widthV.Min() * 2; } if (heightV.Count == 0) { maxHeight = 0; } else { maxHeight = heightV.Min() * 2; } //binary search double minRatio = Math.Max(areaMax / maxWidth / maxWidth, 1 / maxR); double maxRatio = Math.Min(maxHeight * maxHeight / areaMax, maxR); double r = 1; if (minRatio < maxRatio) { for (int a = -rRes; a < rRes + 1; a++) { if (a < 0) { r = 1 / (1 + (1 / minRatio - 1) / Math.Pow(2, -a)); } else if (a == 1) { r = 1; } else { r = 1 + (maxRatio - 1) / Math.Pow(2, a); } //solution boundary List <double> minWidths = new List <double>(); minWidths.Add(Math.Sqrt(areaMax / r)); double minSolWidth = minWidths.Max(); double maxSolWidth = Math.Min(maxWidth, maxHeight / r); double searchWidth = (minSolWidth + maxSolWidth) / 2; double binRes = searchWidth / 2; //binary if (minSolWidth < maxSolWidth) { for (int b = 0; b < binaryIter; b++) { if (inCheck(j, searchWidth, r, xClone) == 1) { if (areaMax < searchWidth * searchWidth * r && searchWidth * searchWidth * r * 4 < PolygonArea(xcurve)) { areaMax = searchWidth * searchWidth * r; solWidth = searchWidth; solPoint = j; solR = r; solAngle = angles[ang]; } searchWidth += binRes; } else { searchWidth -= binRes; } binRes /= 2; } } } } } } } Rectangle3d ohGod = new Rectangle3d(Plane.WorldXY, new Point3d(solPoint.X - solWidth, solPoint.Y - solWidth * solR, 0), new Point3d(solPoint.X + solWidth, solPoint.Y + solWidth * solR, 0)); ohGod.Transform(Transform.Rotation(-solAngle, new Point3d(0, 0, 0))); //2nd search double solWidthNew = solWidth; Point3d solPointNew = solPoint; double solRNew = solR; double solAngleNew = solAngle; int token = 0; while (token < subIter) { gridDom /= convergenceFactor; angleDom /= convergenceFactor; ratioDom /= convergenceFactor; for (int ang = -angleSubResolution; ang < angleSubResolution + 1; ang++) { double searchAngle = solAngle + ang * Math.PI / 2 * angleDom / 2 / angleSubResolution; Polyline xCloneNew = new Polyline(x); xCloneNew.Transform(Transform.Rotation(searchAngle, new Point3d(0, 0, 0))); Curve xCloneNewCurve = xCloneNew.ToNurbsCurve(); //find bounding box, grid dimensions var bBox = xCloneNew.BoundingBox; Point3d minP = bBox.Min; Point3d maxP = bBox.Max; List <double> ressG = new List <double>(); ressG.Add(maxP.X - minP.X); ressG.Add(maxP.Y - minP.Y); List <double> resG = new List <double>(ressG.Select(val => val / (2 * gridSubResolution) * gridDom)); List <Point3d> mids = new List <Point3d>(); for (int i = -gridSubResolution; i < gridSubResolution + 1; i++) { for (int ii = -gridSubResolution; ii < gridSubResolution + 1; ii++) { Point3d solPointTemp = solPoint; //solPointTemp.Transform(Transform.Rotation(searchAngle, new Point3d(0, 0, 0))); Point3d gridPoint = new Point3d(solPointTemp.X + i * resG[0], solPointTemp.Y + ii * resG[1], 0); if (xCloneNewCurve.Contains(gridPoint) == PointContainment.Inside) { mids.Add(gridPoint); } } } foreach (Point3d j in mids) { //get max height and max width Line midlineY = new Line(new Point3d(j.X, minP.Y, 0), new Point3d(j.X, maxP.Y, 0)); Line midlineX = new Line(new Point3d(minP.X, j.Y, 0), new Point3d(maxP.X, j.Y, 0)); List <Point3d> widthP = new List <Point3d>(intersectionPoints(midlineX, xCloneNew)); List <Point3d> heightP = new List <Point3d>(intersectionPoints(midlineY, xCloneNew)); List <double> widthV = new List <double>(); List <double> heightV = new List <double>(); foreach (Point3d k in widthP) { widthV.Add(k.DistanceTo(j)); } foreach (Point3d k in heightP) { heightV.Add(k.DistanceTo(j)); } double maxWidth = widthV.Min(); double maxHeight = heightV.Min(); //binary search double r; for (int a = -ratioSubResolution; a < ratioSubResolution + 1; a++) { r = solR * (1 + a * ratioDom / ratioSubResolution); //solution boundary List <double> minWidths = new List <double>(); minWidths.Add(Math.Sqrt(areaMax / r)); double minSolWidth = minWidths.Max(); double maxSolWidth = Math.Min(maxWidth, maxHeight / r); double searchWidth = (minSolWidth + maxSolWidth) / 2; double binRes = searchWidth / 2; //binary if (minSolWidth < maxSolWidth) { for (int b = 0; b < binaryIter; b++) { if (inCheck(j, searchWidth, r, xCloneNew) == 1) { if (areaMax < searchWidth * searchWidth * r && searchWidth * searchWidth * r * 4 < PolygonArea(xcurve)) { areaMax = searchWidth * searchWidth * r; solWidthNew = searchWidth; solPointNew = j; solRNew = r; solAngleNew = searchAngle; } searchWidth += binRes; } else { searchWidth -= binRes; } binRes /= 2; } } } } } solWidth = solWidthNew; solPoint = solPointNew; solR = solRNew; solAngle = solAngleNew; token += 1; } solPoint.Transform(Transform.Rotation(-solAngle, new Point3d(0, 0, 0))); Rectangle3d ohGoditsworkingNew = new Rectangle3d(Plane.WorldXY, new Point3d(solPointNew.X - solWidthNew, solPointNew.Y - solWidthNew * solRNew, 0), new Point3d(solPointNew.X + solWidthNew, solPointNew.Y + solWidthNew * solRNew, 0)); ohGoditsworkingNew.Transform(Transform.Rotation(-solAngleNew, new Point3d(0, 0, 0))); Rectangle3d outlineRectangle = ohGoditsworkingNew; List <Point3d> pts = new List <Point3d>(outlineRectangle.ToPolyline()); Vector3d vectorT = Vector3d.Subtract(new Vector3d(pts[0]), new Vector3d(pts[1])); if (vectorT.Y < 0) { vectorT.Reverse(); } double outAngleTemp = -Math.Acos(Vector3d.Multiply(Vector3d.XAxis, Vector3d.Multiply(vectorT, 1 / vectorT.Length))); return(outAngleTemp); }
public List <GeometryBase> Draw(Plane plane, Vector3d vec) { List <GeometryBase> list = new List <GeometryBase>(); Rectangle3d rec = new Rectangle3d( plane, ZERO_DEGREE.GetLength(), ZERO_DEGREE.GetWidth()); Vector3d move = new Vector3d(rec.Center.X - plane.Origin.X, rec.Center.Y - plane.Origin.Y, rec.Center.Z - plane.Origin.Z); move.Reverse(); rec.Transform(Transform.Translation(move)); if (!isDoubleRow) { list.Add(rec.ToNurbsCurve()); } else { // 分裂 NurbsCurve stallUp = rec.ToNurbsCurve(); NurbsCurve stallDown = rec.ToNurbsCurve(); Vector3d vecUp = new Vector3d(vec); // 平面几何余弦定理 Vector3d a = new Vector3d(rec.Corner(3) - rec.Corner(0)); Vector3d b = new Vector3d((rec.Corner(2) - rec.Corner(3))); if (degree == Math.PI / 2) { vecUp = b / 2; } else if (degree == 0) { vecUp = a / 2; } else { b.Unitize(); b = b * (length - width / Math.Tan(degree)); // () is the b length vecUp = new Vector3d(a + b) / 2; } Vector3d vecDown; /* * // dist * double dist; * if (degree == 0) * { * dist = width / 2; * } else if (degree == Math.PI / 2) * { * dist = length / 2; * } else * { * dist = length * Math.Sin(degree) / 2; * } */ // vecUp.Unitize(); // vecUp = new Vector3d(vecUp.X * dist, vecUp.Y*dist, vecUp.Z*dist); stallUp.Transform(Transform.Translation(vecUp)); list.Add(stallUp); vecDown = new Vector3d(vecUp); vecDown.Reverse(); stallDown.Transform(Transform.Translation(vecDown)); list.Add(stallDown); } return(list); }