예제 #1
0
파일: Profile.cs 프로젝트: jmerlan/Elements
        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));
        }
예제 #2
0
파일: Profile.cs 프로젝트: jmerlan/Elements
        /// <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;
        }
예제 #3
0
        /// <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;
        }