Пример #1
0
        /// <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));
              }
        }
Пример #2
0
        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.
        }