示例#1
0
        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);
        }
示例#3
0
        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);
        }
示例#4
0
        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));
        }
示例#5
0
        /// <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);
        }
示例#6
0
        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);
        }
示例#7
0
        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));
            });
        }
示例#9
0
        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);
        }
示例#10
0
        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);
        }