Exemplo n.º 1
0
        /// <summary>
        /// Attempts to encapsulate a cloud of points within a capsule. This may not produce an optimal or exact fit. The results
        /// are approximate.
        /// </summary>
        /// <param name="points">The list of points with which to build an enclosing capsule.</param>
        /// <param name="capsule">Returns the capsule containing all points.</param>
        public static void Fit(IList <Vector3> points, out Capsule capsule)
        {
            capsule = new Capsule();
            Vector3 axis, axisNeg;

            GeometryHelper.ComputeMaxSpreadAxis(points, out axis);
            Vector3.Negate(ref axis, out axisNeg);
            if (axis.LengthSquared() < Constants.Epsilon)
            {
                return;
            }
            GeometryHelper.ComputeExtremePoint(points, ref axis, out capsule.P2);
            GeometryHelper.ComputeExtremePoint(points, ref axisNeg, out capsule.P1);
            Segment s = new Segment(capsule.P1, capsule.P2);

            for (int i = 0; i < points.Count; i++)
            {
                var   p = points[i];
                float x = s.DistanceSquaredTo(ref p);
                if (x > capsule.Radius)
                {
                    capsule.Radius = x;
                }
            }
            capsule.Radius = (float)Math.Sqrt(capsule.Radius);
            Vector3.Multiply(ref axis, capsule.Radius, out axis);
            Vector3.Negate(ref axis, out axisNeg);
            Vector3.Add(ref capsule.P1, ref axis, out capsule.P1);
            Vector3.Add(ref capsule.P2, ref axisNeg, out capsule.P2);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Determines whether the specified point, when projected onto the face plane of the polyhedron, is within the face.
        /// </summary>
        /// <param name="faceIndex">The index of the face in which to check containment.</param>
        /// <param name="p">The point in world-space that is either inside or outside the face.</param>
        /// <param name="inclusive">Indicates whether points on the edge or vertices of a face should be considered within the face.</param>
        /// <returns>Returns a value indicating whether the point is contained within the face.</returns>
        public bool IsPointOnFace(int faceIndex, ref Vector3 p, bool inclusive)
        {
            int[]   face = Face(faceIndex);
            int     low = 0, high = face.Length;
            Vector3 normal;

            FaceNormal(faceIndex, out normal);
            Segment s;
            Vector3 p0;

            World(face[0], out p0);
            do
            {
                int     mid = (low + high) / 2;
                Vector3 p1;
                World(face[mid], out p1);
                s = new Segment(p0, p1);
                if ((mid == face.Length - 1 || mid == 1) &&
                    s.DistanceSquaredTo(ref p) < Constants.Epsilon)
                {
                    return(inclusive);
                }
                if (GeometryHelper.IsTriangleCcw(ref normal, ref s.P1, ref s.P2, ref p))
                {
                    low = mid;
                }
                else
                {
                    high = mid;
                }
            }while (low + 1 < high);
            if (low == 0 || high == face.Length)
            {
                return(false);
            }
            World(face[low], out s.P1);
            World(face[high], out s.P2);
            return(GeometryHelper.IsTriangleCcw(ref normal, ref s.P1, ref s.P2, ref p) ||
                   (inclusive && s.DistanceSquaredTo(ref p) < Constants.Epsilon));
        }
Exemplo n.º 3
0
		/// <summary>
		/// Attempts to encapsulate a cloud of points within a capsule. This may not produce an optimal or exact fit. The results
		/// are approximate.
		/// </summary>
		/// <param name="points">The list of points with which to build an enclosing capsule.</param>
		/// <param name="capsule">Returns the capsule containing all points.</param>
		public static void Fit(IList<Vector3> points, out Capsule capsule)
		{
			capsule = new Capsule();
			Vector3 axis, axisNeg;
			GeometryHelper.ComputeMaxSpreadAxis(points, out axis);
			Vector3.Negate(ref axis, out axisNeg);
			if (axis.LengthSquared() < Constants.Epsilon)
				return;
			GeometryHelper.ComputeExtremePoint(points, ref axis, out capsule.P2);
			GeometryHelper.ComputeExtremePoint(points, ref axisNeg, out capsule.P1);
			Segment s = new Segment(capsule.P1, capsule.P2);
			for (int i = 0; i < points.Count; i++)
			{
				var p = points[i];
				float x = s.DistanceSquaredTo(ref p);
				if (x > capsule.Radius)
				{
					capsule.Radius = x;
				}
			}
			capsule.Radius = (float)Math.Sqrt(capsule.Radius);
			Vector3.Multiply(ref axis, capsule.Radius, out axis);
			Vector3.Negate(ref axis, out axisNeg);
			Vector3.Add(ref capsule.P1, ref axis, out capsule.P1);
			Vector3.Add(ref capsule.P2, ref axisNeg, out capsule.P2);
		}
Exemplo n.º 4
0
		/// <summary>
		/// Determines whether the specified point, when projected onto the face plane of the polyhedron, is within the face.
		/// </summary>
		/// <param name="faceIndex">The index of the face in which to check containment.</param>
		/// <param name="p">The point in world-space that is either inside or outside the face.</param>
		/// <param name="inclusive">Indicates whether points on the edge or vertices of a face should be considered within the face.</param>
		/// <returns>Returns a value indicating whether the point is contained within the face.</returns>
		public bool IsPointOnFace(int faceIndex, ref Vector3 p, bool inclusive)
		{
			int[] face = Face(faceIndex);
			int low = 0, high = face.Length;
			Vector3 normal;
			FaceNormal(faceIndex, out normal);
			Segment s;
			Vector3 p0;
			World(face[0], out p0);
			do
			{
				int mid = (low + high) / 2;
				Vector3 p1;
				World(face[mid], out p1);
				s = new Segment(p0, p1);
				if ((mid == face.Length - 1 || mid == 1) &&
					s.DistanceSquaredTo(ref p) < Constants.Epsilon)
				{
					return inclusive;
				}
				if (GeometryHelper.IsTriangleCcw(ref normal, ref s.P1, ref s.P2, ref p))
				{
					low = mid;
				}
				else
				{
					high = mid;
				}
			}
			while (low + 1 < high);
			if (low == 0 || high == face.Length) return false;
			World(face[low], out s.P1);
			World(face[high], out s.P2);
			return GeometryHelper.IsTriangleCcw(ref normal, ref s.P1, ref s.P2, ref p) ||
				(inclusive && s.DistanceSquaredTo(ref p) < Constants.Epsilon);
		}