/// <summary> /// increase of decrease polygon points offseting /// </summary> public static IEnumerable <Vector3D> Offset(this IReadOnlyList <Vector3D> pts, double tol, double offset) { var intmap = new Int64Map(tol, pts.SelectMany(x => x.Coordinates)); var clipper = new ClipperOffset(); { var path = pts.Select(p => new IntPoint(intmap.ToInt64(p.X), intmap.ToInt64(p.Y))).ToList(); // http://www.angusj.com/delphi/clipper.php clipper.AddPath(path, JoinType.jtMiter, EndType.etClosedPolygon); } var intoffset = intmap.ToInt64(intmap.Origin + offset) - intmap.ToInt64(intmap.Origin); var sol = new List <List <IntPoint> >(); clipper.Execute(ref sol, intoffset); return(sol.SelectMany(s => s.Select(si => new Vector3D(intmap.FromInt64(si.X), intmap.FromInt64(si.Y), 0)))); }
/// <summary> /// can generate a Int64MapExceptionRange exception if double values can't fit into a In64 representation. /// In that case try with tolerances not too small. /// It is suggested to use a lenTol/10 to avoid lost of precision during domain conversions. /// </summary> public static IEnumerable <IEnumerable <Vector3D> > Boolean(this IEnumerable <Vector3D> polyA, double tol, IEnumerable <Vector3D> polyB, ClipType type, bool selfCheckInt64MapTolerance = true) { var intmap = new Int64Map(tol, polyA.SelectMany(x => x.Coordinates).Union(polyB.SelectMany(x => x.Coordinates)), selfCheckInt64MapTolerance); var clipper = new Clipper(); { var path = polyA.Select(p => new IntPoint(intmap.ToInt64(p.X), intmap.ToInt64(p.Y))).ToList(); clipper.AddPath(path, PolyType.ptSubject, true); } { var path = polyB.Select(p => new IntPoint(intmap.ToInt64(p.X), intmap.ToInt64(p.Y))).ToList(); clipper.AddPath(path, PolyType.ptClip, true); } var sol = new List <List <IntPoint> >(); clipper.Execute(type, sol); var res = sol.Select(s => s.Select(si => new Vector3D(intmap.FromInt64(si.X), intmap.FromInt64(si.Y), 0))); return(res); }