//public static NFP[] Convolve(NFP A, NFP B) //{ // Dictionary<string, List<PointF>> dic1 = new Dictionary<string, List<PointF>>(); // Dictionary<string, List<double>> dic2 = new Dictionary<string, List<double>>(); // dic2.Add("A", new List<double>()); // foreach (var item in A.Points) // { // var target = dic2["A"]; // target.Add(item.X); // target.Add(item.Y); // } // dic2.Add("B", new List<double>()); // foreach (var item in B.Points) // { // var target = dic2["B"]; // target.Add(item.X); // target.Add(item.Y); // } // List<double> hdat = new List<double>(); // foreach (var item in A.Childrens) // { // foreach (var pitem in item.Points) // { // hdat.Add(pitem.X); // hdat.Add(pitem.Y); // } // } // var aa = dic2["A"]; // var bb = dic2["B"]; // var arr1 = A.Childrens.Select(z => z.Points.Count() * 2).ToArray(); // MinkowskiWrapper.setData(aa.Count, aa.ToArray(), A.Childrens.Count, arr1, hdat.ToArray(), bb.Count, bb.ToArray()); // MinkowskiWrapper.calculateNFP(); // int[] sizes = new int[2]; // MinkowskiWrapper.getSizes1(sizes); // int[] sizes1 = new int[sizes[0]]; // int[] sizes2 = new int[sizes[1]]; // MinkowskiWrapper.getSizes2(sizes1, sizes2); // double[] dat1 = new double[sizes1.Sum()]; // double[] hdat1 = new double[sizes2.Sum()]; // MinkowskiWrapper.getResults(dat1, hdat1); // if (sizes1.Count() > 1) // { // throw new ArgumentException("sizes1 cnt >1"); // } // //convert back to answer here // bool isa = true; // List<PointF> Apts = new List<PointF>(); // List<List<double>> holesval = new List<List<double>>(); // bool holes = false; // for (int i = 0; i < dat1.Length; i += 2) // { // var x1 = (float)dat1[i]; // var y1 = (float)dat1[i + 1]; // Apts.Add(new PointF(x1, y1)); // } // int index = 0; // for (int i = 0; i < sizes2.Length; i++) // { // holesval.Add(new List<double>()); // for (int j = 0; j < sizes2[i]; j++) // { // holesval.Last().Add(hdat1[index]); // index++; // } // } // List<List<PointF>> holesout = new List<List<PointF>>(); // foreach (var item in holesval) // { // holesout.Add(new List<PointF>()); // for (int i = 0; i < item.Count; i += 2) // { // var x = (float)item[i]; // var y = (float)item[i + 1]; // holesout.Last().Add(new PointF(x, y)); // } // } // NFP ret = new NFP(); // ret.Points = new SvgPoint[] { }; // foreach (var item in Apts) // { // ret.AddPoint(new SvgPoint(item.X, item.Y)); // } // foreach (var item in holesout) // { // if (ret.Childrens == null) // ret.Childrens = new List<NFP>(); // ret.Childrens.Add(new NFP()); // ret.Childrens.Last().Points = new SvgPoint[] { }; // foreach (var hitem in item) // { // ret.Childrens.Last().AddPoint(new SvgPoint(hitem.X, hitem.Y)); // } // } // var res = new NFP[] { ret }; // return res; //} public static NFP getOuterNfp(NFP A, NFP B, bool inside = false) { NFP[] nfp = null; if (inside || (A.Childrens != null && A.Childrens.Count > 0)) { nfp = DeepNest.Convolve(A, B); } else { var Ac = ClipperHelper.ScaleUpPaths(A, 10000000); var Bc = ClipperHelper.ScaleUpPaths(B, 10000000); for (var i = 0; i < Bc.Length; i++) { Bc[i].X *= -1; Bc[i].Y *= -1; } var solution = ClipperLib.Clipper.MinkowskiSum(new List <IntPoint>(Ac), new List <IntPoint>(Bc), true); NFP clipperNfp = null; double?largestArea = null; for (int i = 0; i < solution.Count(); i++) { var n = toNestCoordinates(solution[i].ToArray(), 10000000); var sarea = GeometryUtil.polygonArea(n); if (largestArea == null || largestArea > sarea) { clipperNfp = n; largestArea = sarea; } } for (var i = 0; i < clipperNfp.Length; i++) { clipperNfp[i].X += B[0].X; clipperNfp[i].Y += B[0].Y; } nfp = new NFP[] { new NFP() { Points = clipperNfp.Points } }; } if (nfp == null || nfp.Length == 0) { //console.log('holy shit', nfp, A, B, JSON.stringify(A), JSON.stringify(B)); return(null); } NFP nfps = nfp.First(); if (nfps == null || nfps.Length == 0) { return(null); } return(nfps); }
public static Vector2d[] GetMinimumBox(Vector2d[] vv) { var hull = DeepNest.getHull(new NFP() { Points = vv.Select(z => new SvgPoint(z.X, z.Y)).ToArray() }); double minArea = double.MaxValue; List <Vector2d> rect = new List <Vector2d>(); for (int i = 0; i < hull.Length; i++) { var p0 = hull.Points[i]; var p1 = hull.Points[(i + 1) % hull.Length]; var dx = p1.X - p0.X; var dy = p1.Y - p0.Y; var atan = Math.Atan2(dy, dx); List <Vector2d> dd = new List <Vector2d>(); for (int j = 0; j < vv.Length; j++) { var r = RotatePoint(new Vector2d(vv[j].X, vv[j].Y), 0, 0, -atan); dd.Add(r); } var maxx = dd.Max(z => z.X); var maxy = dd.Max(z => z.Y); var minx = dd.Min(z => z.X); var miny = dd.Min(z => z.Y); var area = (maxx - minx) * (maxy - miny); if (area < minArea) { minArea = area; rect.Clear(); rect.Add(new Vector2d(minx, miny)); rect.Add(new Vector2d(maxx, miny)); rect.Add(new Vector2d(maxx, maxy)); rect.Add(new Vector2d(minx, maxy)); for (int j = 0; j < rect.Count; j++) { rect[j] = RotatePoint(new Vector2d(rect[j].X, rect[j].Y), 0, 0, atan); } } } return(rect.ToArray()); }