Exemplo n.º 1
0
        /// <summary>
        ///     Initializes a new instance of the <see cref="Cylinder" /> class.
        /// </summary>
        /// <param name="facesAll">The faces all.</param>
        /// <param name="axis">The axis.</param>
        public Cylinder(IEnumerable <PolygonalFace> facesAll, Vector3 axis)
            : base(facesAll)
        {
            var faces           = Faces.FacesWithDistinctNormals();
            var n               = faces.Count;
            var centers         = new List <Vector3>();
            var signedDistances = new List <double>();

            MiscFunctions.SkewedLineIntersection(faces[0].Center, faces[0].Normal,
                                                 faces[n - 1].Center, faces[n - 1].Normal, out var center, out _, out _,
                                                 out var t1, out var t2);
            if (!center.IsNull() && !center.IsNegligible())
            {
                centers.Add(center);
                signedDistances.Add(t1);
                signedDistances.Add(t2);
            }
            for (var i = 1; i < n; i++)
            {
                MiscFunctions.SkewedLineIntersection(faces[i].Center, faces[i].Normal,
                                                     faces[i - 1].Center, faces[i - 1].Normal, out center, out _, out _,
                                                     out t1, out t2);
                if (!center.IsNull() && !center.IsNegligible())
                {
                    centers.Add(center);
                    signedDistances.Add(t1);
                    signedDistances.Add(t2);
                }
            }
            center = new Vector3();
            center = centers.Aggregate(center, (current, c) => current + c);
            center = center.Divide(centers.Count);
            /* move center to origin plane */
            var distBackToOrigin = -1 * axis.Dot(center);

            center = center - (axis * distBackToOrigin);
            /* determine is positive or negative */
            var numNeg     = signedDistances.Count(d => d < 0);
            var numPos     = signedDistances.Count(d => d > 0);
            var isPositive = numNeg > numPos;
            var radii      = new List <double>();

            foreach (var face in faces)
            {
                radii.AddRange(face.Vertices.Select(v => MiscFunctions.DistancePointToLine(v.Coordinates, center, axis)));
            }
            var averageRadius = radii.Average();

            Axis       = axis;
            Anchor     = center;
            IsPositive = isPositive;
            Radius     = averageRadius;
        }