/// <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; }