public static Ngons MinkowskiSumSegment(Ngon pattern, IntPoint p1, IntPoint p2, bool flip_pattern) { Clipper clipper = new Clipper(); Ngon p1_c = pattern.Clone(p1.X, p1.Y, flip_pattern); if (p1 == p2) { return new Ngons() { p1_c } } ; Ngon p2_c = pattern.Clone(p2.X, p2.Y, flip_pattern); Ngons full = new Ngons(); clipper.AddPath(p1_c, PolyType.ptSubject, true); clipper.AddPath(p2_c, PolyType.ptSubject, true); clipper.AddPaths(Clipper.MinkowskiSum(pattern.Clone(0, 0, flip_pattern), new Ngon() { p1, p2 }, false), PolyType.ptSubject, true); clipper.Execute(ClipType.ctUnion, full, PolyFillType.pftNonZero); return(full); }
public static IPolygon MinkowskiDifference(IPolygon p, IPolygon q) { if (p.IsEmpty || q.IsEmpty) { return(Polygon.Empty); } var boundingBox = Box2.Hull(p.BoundingBox(), q.BoundingBox()); boundingBox = Box2.Hull(boundingBox, new Box2(-boundingBox.MaxCorner, boundingBox.Dimensions)); var fixedAnswer = new ClipperPolygon(); var fixedP = ConvertToFixedPoint(p, boundingBox); foreach (var qContour in q.Contours) { var fixedQContour = MinusConvertToFixedPoint(qContour, boundingBox); try { var clipper = new Clipper(); clipper.AddPaths(fixedAnswer, PolyType.ptSubject, closed: true); clipper.AddPaths(Clipper.MinkowskiSum(fixedQContour, fixedP, pathIsClosed: true), PolyType.ptClip, closed: true); var tempAnswer = new ClipperPolygon(); clipper.Execute(ClipType.ctUnion, tempAnswer); fixedAnswer = tempAnswer; } catch (Exception e) { Console.WriteLine("EXCEPTION: {0}", e); } } return(ConvertToFloatingPoint(fixedAnswer, boundingBox)); }
public static NFP MinkowskiSum(NFP pattern, NFP path, bool useChilds = false, bool takeOnlyBiggestArea = true) { var ac = ScaleUpPaths(pattern); List <List <IntPoint> > solution = null; if (useChilds) { var bc = nfpToClipperCoordinates(path); for (var i = 0; i < bc.Length; i++) { for (int j = 0; j < bc[i].Length; j++) { bc[i][j].X *= -1; bc[i][j].Y *= -1; } } solution = ClipperLib.Clipper.MinkowskiSum(new List <IntPoint>(ac), new List <List <IntPoint> >(bc.Select(z => z.ToList())), true); } else { var bc = ScaleUpPaths(path); for (var i = 0; i < bc.Length; i++) { bc[i].X *= -1; bc[i].Y *= -1; } solution = Clipper.MinkowskiSum(new List <IntPoint>(ac), new List <IntPoint>(bc), true); } NFP clipperNfp = null; double?largestArea = null; int largestIndex = -1; for (int i = 0; i < solution.Count(); i++) { var n = toNestCoordinates(solution[i].ToArray(), 10000000); var sarea = Math.Abs(GeometryUtil.polygonArea(n)); if (largestArea == null || largestArea < sarea) { clipperNfp = n; largestArea = sarea; largestIndex = i; } } if (!takeOnlyBiggestArea) { for (int j = 0; j < solution.Count; j++) { if (j == largestIndex) { continue; } var n = toNestCoordinates(solution[j].ToArray(), 10000000); if (clipperNfp.Childrens == null) { clipperNfp.Childrens = new List <NFP>(); } clipperNfp.Childrens.Add(n); } } for (var i = 0; i < clipperNfp.Length; i++) { clipperNfp[i].X *= -1; clipperNfp[i].Y *= -1; clipperNfp[i].X += pattern[0].X; clipperNfp[i].Y += pattern[0].Y; } var minx = clipperNfp.Points.Min(z => z.X); var miny = clipperNfp.Points.Min(z => z.Y); var minx2 = path.Points.Min(z => z.X); var miny2 = path.Points.Min(z => z.Y); var shiftx = minx2 - minx; var shifty = miny2 - miny; if (clipperNfp.Childrens != null) { foreach (var nFP in clipperNfp.Childrens) { for (int j = 0; j < nFP.Length; j++) { nFP.Points[j].X *= -1; nFP.Points[j].Y *= -1; nFP.Points[j].X += pattern[0].X; nFP.Points[j].Y += pattern[0].Y; } } } return(clipperNfp); }
//Here comes Drawing private void DrawBitmap(bool justClip = false) { Cursor.Current = Cursors.WaitCursor; try { GenerateFigures(textBox1.Text, textBox2.Text); using (Graphics newgraphic = Graphics.FromImage(mybitmap)) using (GraphicsPath path = new GraphicsPath()) { newgraphic.SmoothingMode = SmoothingMode.AntiAlias; newgraphic.Clear(Color.White); path.FillMode = FillMode.Winding; float scale = trackBar1.Value; PointF[] pts = PolygonToPointFArray(figure1, scale); path.AddPolygon(pts); pts = null; //draw subjects ... using (Pen myPen = new Pen(Color.FromArgb(196, 0xC3, 0xC9, 0xCF), (float)0.6)) using (SolidBrush myBrush = new SolidBrush(Color.FromArgb(127, 0xDD, 0xDD, 0xF0))) { newgraphic.FillPath(myBrush, path); newgraphic.DrawPath(myPen, path); path.Reset(); //draw clips ... path.FillMode = FillMode.Winding; pts = PolygonToPointFArray(figure2, scale); path.AddPolygon(pts); pts = null; myPen.Color = Color.FromArgb(196, 0xEF, 0xBE, 0xA6); myBrush.Color = Color.FromArgb(127, 0xEF, 0xE0, 0xE0); newgraphic.FillPath(myBrush, path); newgraphic.DrawPath(myPen, path); //Minkovski w/ Timer if (numericUpDown1.Value != 0) { solution = Clipper.MinkowskiSum(figure1, figure2, false); for (int i = 0; i < numericUpDown1.Value; i++) { solution = Clipper.SimplifyPolygons(solution); solution = Clipper.MinkowskiSum(figure2, solution, true); } path.FillMode = FillMode.Winding; foreach (Polygon poly in solution) { pts = PolygonToPointFArray(poly, scale); path.AddPolygon(pts); pts = null; } } myPen.Color = Color.FromArgb(196, 0xF9, 0xBE, 0xA6); myBrush.Color = Color.FromArgb(127, 0xFE, 0x04, 0x00); newgraphic.FillPath(myBrush, path); newgraphic.DrawPath(myPen, path); path.Reset(); //Convert Obs to ints int count = Convert.ToInt32(numericUpDown2.Value); cubes = GenerateRandomCubes(count); foreach (Polygon poly in cubes) { pts = PolygonToPointFArray(poly, scale); path.AddPolygon(pts); pts = null; } myPen.Color = Color.FromArgb(196, 0x00, 0x00, 0x00); myBrush.Color = Color.FromArgb(255, 0xFF, 0xFF, 0xFF); newgraphic.FillPath(myBrush, path); newgraphic.DrawPath(myPen, path); path.Reset(); /*------ * Polygons filler = new Polygons(); * Clipper d = new Clipper(); * d.AddPaths(cubes, PolyType.ptSubject, true); * d.AddPaths(cubes, PolyType.ptClip, true); * path.FillMode = FillMode.Winding; * d.Execute(ClipType.ctIntersection, filler, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); * * foreach (Polygon poly in filler) * { * pts = PolygonToPointFArray(poly, scale); * path.AddPolygon(pts); * pts = null; * } * myPen.Color = Color.FromArgb(255, 0xFF, 0xFF, 0xFF); * myBrush.Color = Color.FromArgb(255, 0xFF, 0xFF, 0xFF); * newgraphic.FillPath(myBrush, path); * newgraphic.DrawPath(myPen, path); * path.Reset(); */ //----- Polygons solution_2 = new Polygons(); Clipper c = new Clipper(); c.AddPaths(solution, PolyType.ptSubject, true); c.AddPaths(cubes, PolyType.ptClip, true); path.FillMode = FillMode.Winding; c.Execute(ClipType.ctIntersection, solution_2, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd); foreach (Polygon poly in solution_2) { pts = PolygonToPointFArray(poly, scale); path.AddPolygon(pts); pts = null; } myPen.Color = Color.FromArgb(196, 0x00, 0x00, 0x00); myBrush.Color = Color.FromArgb(255, 0xFF, 0x00, 0xFF); newgraphic.FillPath(myBrush, path); newgraphic.DrawPath(myPen, path); path.Reset(); //------- } } pictureBox1.Image = mybitmap; } finally { Cursor.Current = Cursors.Default; } }