private double ClippedArea() { if (this.Voids == null || this.Voids.Count == 0) { return(this.Perimeter.Area()); } var clipper = new ClipperLib.Clipper(); var normal = Perimeter.Normal(); if (normal.IsAlmostEqualTo(Vector3.ZAxis)) { clipper.AddPath(Perimeter.ToClipperPath(), ClipperLib.PolyType.ptSubject, true); clipper.AddPaths(this.Voids.Select(p => p.ToClipperPath()).ToList(), ClipperLib.PolyType.ptClip, true); } else { var transform = new Transform(Perimeter.Start, normal); transform.Invert(); var perimeter = Perimeter.TransformedPolygon(transform); clipper.AddPath(perimeter.ToClipperPath(), ClipperLib.PolyType.ptSubject, true); clipper.AddPaths(this.Voids.Select(p => p.TransformedPolygon(transform).ToClipperPath()).ToList(), ClipperLib.PolyType.ptClip, true); } var solution = new List <List <ClipperLib.IntPoint> >(); clipper.Execute(ClipperLib.ClipType.ctDifference, solution, ClipperLib.PolyFillType.pftEvenOdd); return(solution.Sum(s => ClipperLib.Clipper.Area(s)) / Math.Pow(1.0 / Vector3.EPSILON, 2)); }
/// <summary> /// Ensure that voids run in an opposite winding direction to the perimeter of the profile. /// Be sure to call this if you modify the Profile's Voids array directly. /// </summary> public void OrientVoids() { // This should only occur in the case of a parametric // profile which defines its own perimeter and void logic // during construction. if (Perimeter == null || Voids == null) { return; } var correctedVoids = new List <Polygon>(); var perimeterNormal = Perimeter.Normal(); foreach (var voidCrv in Voids) { if (voidCrv.Normal().Dot(perimeterNormal) > 0) { correctedVoids.Add(voidCrv.Reversed()); } else { correctedVoids.Add(voidCrv); } } this.Voids = correctedVoids; }
/// <summary> /// Ensure that voids run in an opposite winding direction to the perimeter of the profile. /// Be sure to call this if you modify the Profile's Voids array directly. /// </summary> public void OrientVoids() { var correctedVoids = new List <Polygon>(); var perimeterNormal = Perimeter.Normal(); foreach (var voidCrv in Voids) { if (voidCrv.Normal().Dot(perimeterNormal) > 0) { correctedVoids.Add(voidCrv.Reversed()); } else { correctedVoids.Add(voidCrv); } } this.Voids = correctedVoids; }