/// <summary> /// Computes a minimum bounding shape that contains all given points. /// </summary> /// <param name="points">The points.</param> /// <returns>A minimum bounding shape that contains all given points.</returns> /// <remarks> /// The returned shape will be a <see cref="SphereShape"/>, a <see cref="CapsuleShape"/>, /// a <see cref="BoxShape"/>, or a <see cref="TransformedShape"/> (containing a sphere, capsule, /// or a box). The bounding shape is not guaranteed to be optimal, it is only guaranteed that /// the bounding shape includes all given points. /// </remarks> /// <exception cref="ArgumentNullException"> /// <paramref name="points"/> is <see langword="null"/>. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="points"/> is empty. /// </exception> public static Shape CreateBoundingShape(IList<Vector3F> points) { if (points == null) throw new ArgumentNullException("points"); if (points.Count == 0) throw new ArgumentException("The list of 'points' is empty."); // Compute minimal sphere. Vector3F center; float radius; ComputeBoundingSphere(points, out radius, out center); SphereShape sphere = new SphereShape(radius); float sphereVolume = sphere.GetVolume(); // Compute minimal capsule. float height; Pose capsulePose; ComputeBoundingCapsule(points, out radius, out height, out capsulePose); CapsuleShape capsule = new CapsuleShape(radius, height); float capsuleVolume = capsule.GetVolume(); // Compute minimal box. Vector3F boxExtent; Pose boxPose; ComputeBoundingBox(points, out boxExtent, out boxPose); var box = new BoxShape(boxExtent); float boxVolume = box.GetVolume(); // Return the object with the smallest volume. // A TransformedShape is used if the shape needs to be translated or rotated. if (sphereVolume < boxVolume && sphereVolume < capsuleVolume) { if (center.IsNumericallyZero) return sphere; return new TransformedShape(new GeometricObject(sphere, new Pose(center))); } else if (capsuleVolume < boxVolume) { if (!capsulePose.HasTranslation && !capsulePose.HasRotation) return capsule; return new TransformedShape(new GeometricObject(capsule, capsulePose)); } else { if (!boxPose.HasTranslation && !boxPose.HasRotation) return box; return new TransformedShape(new GeometricObject(box, boxPose)); } }
public void SphereTest() { var s = new SphereShape(1); var v0 = s.GetVolume(0.001f, 10); var m = s.GetMesh(0.001f, 10); var v1 = m.GetVolume(); Assert.IsTrue(Numeric.AreEqual(v0, v1, 0.01f * (1 + v0))); // 1% error is allowed. }