/// <summary> /// Determines whether any of the fields of the specified bounding sphere evaluates to a value that is not a number. /// </summary> /// <param name="value">A bounding sphere.</param> /// <returns>True if any of the fields of <paramref name="value"/> evaluates to a value that is not a number, otherwise false.</returns> public static bool IsNaN(BoundingSphere value) { return Vector3.IsNaN(value.Position) || Number.IsNaN(value.Radius); }
/// <summary> /// Determines whether the specified plane intersects with the specified bounding sphere. /// </summary> /// <param name="plane">A plane.</param> /// <param name="boundingSphere">A bounding sphere.</param> /// <param name="intersection">Output variable for the intersection.</param> /// <returns>True if the <paramref name="plane"/> and the <paramref name="boundingSphere"/> intersect, otherwise false.</returns> public static bool PlaneWithBoundingSphere(Plane plane, BoundingSphere boundingSphere, out Vector3 intersection) { var distance = Distance.PointToPlane(boundingSphere.Position, plane); if (Math.Abs(distance) < boundingSphere.Radius) { intersection = new Vector3 { X = boundingSphere.Position.X - plane.A * distance, Y = boundingSphere.Position.Y - plane.B * distance, Z = boundingSphere.Position.Z - plane.C * distance, }; return true; } else { intersection = default(Vector3); return false; } }
/// <summary> /// Determines whether the specified bounding box intersects with the specified bounding sphere. /// </summary> /// <param name="boundingBox">A bounding box.</param> /// <param name="boundingSphere">A bounding sphere.</param> /// <returns>True if the <paramref name="boundingBox"/> and the <paramref name="boundingSphere"/> intersect, otherwise false.</returns> public static bool BoundingBoxWithBoundingSphere(BoundingBox boundingBox, BoundingSphere boundingSphere) { var closestPoint = Vector3.Clamp(boundingSphere.Position, boundingBox.Minimum, boundingBox.Maximum); return Distance.PointToPointSquared(boundingSphere.Position, closestPoint) <= boundingSphere.Radius * boundingSphere.Radius; }
/// <summary> /// Determines whether the current bounding sphere is equal to the specified bounding sphere. /// </summary> /// <param name="value">A bounding sphere.</param> /// <returns>True if the current bounding sphere is equal to the <paramref name="value"/>, otherwise false.</returns> public bool Equals(BoundingSphere value) { return this.Position == value.Position && this.Radius == value.Radius; }
/// <summary> /// Returns the distance between the specified bounding sphere and the specified line segment. /// </summary> /// <param name="boundingSphere">A bounding sphere.</param> /// <param name="lineSegment">A line segment.</param> /// <returns>The distance between the <paramref name="boundingSphere"/> and the <paramref name="lineSegment"/>.</returns> public static Number BoundingSphereToLineSegment(BoundingSphere boundingSphere, LineSegment lineSegment) { return Math.Max(0, Distance.PointToLineSegment(boundingSphere.Position, lineSegment) - boundingSphere.Radius); }
/// <summary> /// Attempts to parse the bounding sphere from the specified string. /// </summary> /// <param name="value">The string to parse.</param> /// <param name="result">The output variable for the bounding sphere parsed from the <paramref name="value"/>.</param> /// <returns>True if the <paramref name="value"/> was parsed successfully, otherwise false.</returns> public static bool TryParse(string value, out BoundingSphere result) { return TryParse(value, NumberStyles.Float | NumberStyles.AllowThousands, null, out result); }
/// <summary> /// Attempts to parse the bounding sphere from the specified string. /// </summary> /// <param name="value">The string to parse.</param> /// <param name="formatProvider">The format provider for each component.</param> /// <param name="result">The output variable for the bounding sphere parsed from the <paramref name="value"/>.</param> /// <returns>True if the <paramref name="value"/> was parsed successfully, otherwise false.</returns> public static bool TryParse(string value, IFormatProvider formatProvider, out BoundingSphere result) { return TryParse(value, NumberStyles.Float | NumberStyles.AllowThousands, formatProvider, out result); }
/// <summary> /// Determines whether the specified bounding spheres intersect. /// </summary> /// <param name="boundingSphere1">A bounding sphere.</param> /// <param name="boundingSphere2">A bounding sphere.</param> /// <returns>True if the <paramref name="boundingSphere1"/> and the <paramref name="boundingSphere2"/> intersect, otherwise false.</returns> public static bool BoundingSphereWithBoundingSphere(BoundingSphere boundingSphere1, BoundingSphere boundingSphere2) { var distance = Distance.PointToPoint(boundingSphere1.Position, boundingSphere2.Position); return distance <= boundingSphere1.Radius + boundingSphere2.Radius; }
/// <summary> /// Determines whether the specified bounding spheres intersect. /// </summary> /// <param name="boundingSphere1">A bounding sphere.</param> /// <param name="boundingSphere2">A bounding sphere.</param> /// <param name="intersection">Output variable for the intersection.</param> /// <returns>True if the <paramref name="boundingSphere1"/> and the <paramref name="boundingSphere2"/> intersect, otherwise false.</returns> public static bool BoundingSphereWithBoundingSphere(BoundingSphere boundingSphere1, BoundingSphere boundingSphere2, out BoundingSphere intersection) { var x = boundingSphere2.Position.X - boundingSphere1.Position.X; var y = boundingSphere2.Position.Y - boundingSphere1.Position.Y; var z = boundingSphere2.Position.Z - boundingSphere1.Position.Z; var distance = (Number)Math.Sqrt(x * x + y * y + z * z); if (distance > boundingSphere1.Radius + boundingSphere2.Radius) { intersection = default(BoundingSphere); return false; } else if (distance <= boundingSphere1.Radius - boundingSphere2.Radius) { intersection = boundingSphere2; return true; } else if (distance <= boundingSphere2.Radius - boundingSphere1.Radius) { intersection = boundingSphere1; return true; } else { var radius = (Number)(Math.Sqrt( (boundingSphere1.Radius - boundingSphere2.Radius - distance) * (boundingSphere2.Radius - boundingSphere1.Radius - distance) * (boundingSphere1.Radius + boundingSphere2.Radius - distance) * (boundingSphere2.Radius + boundingSphere1.Radius + distance)) / distance); var r1 = boundingSphere1.Radius * boundingSphere1.Radius; var r2 = boundingSphere2.Radius * boundingSphere2.Radius; var d1 = distance * distance; var d2 = (d1 + r1 - r2) / (2 * d1); intersection.Position.X = boundingSphere1.Position.X + x * d2; intersection.Position.Y = boundingSphere1.Position.Y + y * d2; intersection.Position.Z = boundingSphere1.Position.Z + z * d2; intersection.Radius = radius; return true; } }
/// <summary> /// Returns the distance between the specified bounding box and the specified bounding sphere. /// </summary> /// <param name="boundingBox">A bounding box.</param> /// <param name="boundingSphere">A bounding sphere.</param> /// <returns>The distance between the <paramref name="boundingBox"/> and the <paramref name="boundingSphere"/>.</returns> public static Number BoundingBoxToBoundingSphere(BoundingBox boundingBox, BoundingSphere boundingSphere) { var closestPoint = Vector3.Clamp(boundingSphere.Position, boundingBox.Minimum, boundingBox.Maximum); return Distance.PointToBoundingSphere(closestPoint, boundingSphere); }
/// <summary> /// Determines whether the specified bounding box intersects with the specified bounding sphere. /// </summary> /// <param name="boundingBox">A bounding box.</param> /// <param name="boundingSphere">A bounding sphere.</param> /// <param name="intersection">Output variable for the intersection.</param> /// <returns>True if the <paramref name="boundingBox"/> and the <paramref name="boundingSphere"/> intersect, otherwise false.</returns> public static bool BoundingBoxWithBoundingSphere(BoundingBox boundingBox, BoundingSphere boundingSphere, out Vector3 intersection) { var closestPoint = Vector3.Clamp(boundingSphere.Position, boundingBox.Minimum, boundingBox.Maximum); if (Distance.PointToPointSquared(closestPoint, boundingSphere.Position) <= boundingSphere.Radius * boundingSphere.Radius) { intersection = closestPoint; return true; } else { intersection = default(Vector3); return false; } }
/// <summary> /// Returns the distance between the specified point and the specified bounding sphere. /// </summary> /// <param name="point">A point.</param> /// <param name="boundingSphere">A bounding sphere.</param> /// <returns>The distance between the <paramref name="point"/> and the <paramref name="boundingSphere"/>.</returns> public static Number PointToBoundingSphere(Vector3 point, BoundingSphere boundingSphere) { return Math.Max(0, Distance.PointToPoint(point, boundingSphere.Position) - boundingSphere.Radius); }
/// <summary> /// Returns the distance between the specified bounding sphere and the specified ray. /// </summary> /// <param name="boundingSphere">A bounding sphere.</param> /// <param name="ray">A ray.</param> /// <returns>The distance between the <paramref name="boundingSphere"/> and the <paramref name="ray"/>.</returns> public static Number BoundingSphereToRay(BoundingSphere boundingSphere, Ray ray) { return Math.Max(0, Distance.PointToRay(boundingSphere.Position, ray) - boundingSphere.Radius); }
/// <summary> /// Returns the distance between the specified bounding sphere and the specified plane. /// </summary> /// <param name="boundingSphere">A bounding sphere.</param> /// <param name="plane">A plane.</param> /// <returns>The distance between the <paramref name="boundingSphere"/> and the <paramref name="plane"/>.</returns> public static Number BoundingSphereToPlane(BoundingSphere boundingSphere, Plane plane) { var distance = Distance.PointToPlane(boundingSphere.Position, plane); if (distance < -boundingSphere.Radius) { return distance + boundingSphere.Radius; } if (distance > boundingSphere.Radius) { return distance - boundingSphere.Radius; } return 0; }
/// <summary> /// Determines whether any of the fields of the specified bounding sphere evaluates to positive infinity. /// </summary> /// <param name="value">A bounding sphere.</param> /// <returns>True if any of the fields of <paramref name="value"/> evaluates to positive infinity, otherwise false.</returns> public static bool IsPositiveInfinity(BoundingSphere value) { return Vector3.IsPositiveInfinity(value.Position) || Number.IsPositiveInfinity(value.Radius); }
/// <summary> /// Determines whether the specified bounding sphere intersects with the specified point. /// </summary> /// <param name="boundingSphere">A bounding sphere.</param> /// <param name="point">A point.</param> /// <returns>True if the <paramref name="boundingSphere"/> and the <paramref name="point"/> intersect, otherwise false.</returns> public static bool BoundingSphereWithPoint(BoundingSphere boundingSphere, Vector3 point) { return Distance.PointToPointSquared(point, boundingSphere.Position) <= boundingSphere.Radius * boundingSphere.Radius; }
/// <summary> /// Returns the smallest bounding sphere containing both of the specified bounding spheres. /// </summary> /// <param name="value1">A bouding sphere.</param> /// <param name="value2">A bouding sphere.</param> /// <returns>The smallest bounding sphere containing both of the <paramref name="value1"/> and the <paramref name="value2"/>.</returns> public static BoundingSphere Merge(BoundingSphere value1, BoundingSphere value2) { var separation = value2.Position - value1.Position; var distance = separation.Magnitude; if (value1.Radius - value2.Radius >= distance) { return value1; } else if (value2.Radius - value1.Radius >= distance) { return value2; } else { var radius = (distance + value1.Radius + value2.Radius) * 0.5f; var d = (radius - value1.Radius) / distance; return new BoundingSphere { Position = value1.Position + separation * d, Radius = radius, }; } }
/// <summary> /// Determines whether the specified bounding sphere intersects with the specified ray. /// </summary> /// <param name="boundingSphere">A bounding sphere.</param> /// <param name="ray">A ray.</param> /// <returns>True if the <paramref name="boundingSphere"/> and the <paramref name="ray"/> intersect, otherwise false.</returns> public static bool BoundingSphereWithRay(BoundingSphere boundingSphere, Ray ray) { var separation = boundingSphere.Position - ray.Position; var lengthSquared = separation.MagnitudeSquared; var radiusSquared = boundingSphere.Radius * boundingSphere.Radius; if (lengthSquared <= radiusSquared) { return true; } else { var dot = Vector3.Dot(ray.Direction, separation); if (dot >= 0) { var discriminant = lengthSquared - (dot * dot); if (discriminant <= radiusSquared) { return true; } } } return false; }
/// <summary> /// Attempts to parse the bounding sphere from the specified string. /// </summary> /// <param name="value">The string to parse.</param> /// <param name="numberStyle">The number style for each component.</param> /// <param name="result">The output variable for the bounding sphere parsed from the <paramref name="value"/>.</param> /// <returns>True if the <paramref name="value"/> was parsed successfully, otherwise false.</returns> public static bool TryParse(string value, NumberStyles numberStyle, out BoundingSphere result) { return TryParse(value, numberStyle, null, out result); }
/// <summary> /// Determines whether the specified bounding sphere intersects with the specified ray. /// </summary> /// <param name="boundingSphere">A bounding sphere.</param> /// <param name="ray">A ray.</param> /// <param name="intersection">Output variable for the intersection.</param> /// <returns>True if the <paramref name="boundingSphere"/> and the <paramref name="ray"/> intersect, otherwise false.</returns> public static bool BoundingSphereWithRay(BoundingSphere boundingSphere, Ray ray, out Vector3 intersection) { var separation = boundingSphere.Position - ray.Position; var lengthSquared = separation.MagnitudeSquared; var radiusSquared = boundingSphere.Radius * boundingSphere.Radius; if (lengthSquared <= radiusSquared) { intersection = ray.Position; return true; } else { var dot = Vector3.Dot(ray.Direction, separation); if (dot >= 0) { var discriminant = lengthSquared - (dot * dot); if (discriminant <= radiusSquared) { var u = dot - (Number)Math.Sqrt(radiusSquared - discriminant); intersection = ray.Position + ray.Direction * u; return true; } } } intersection = default(Vector3); return false; }
/// <summary> /// Attempts to parse the bounding sphere from the specified string. /// </summary> /// <param name="value">The string to parse.</param> /// <param name="numberStyle">The number style for each component.</param> /// <param name="formatProvider">The format provider for each component.</param> /// <param name="result">The output variable for the bounding sphere parsed from the <paramref name="value"/>.</param> /// <returns>True if the <paramref name="value"/> was parsed successfully, otherwise false.</returns> public static bool TryParse(string value, NumberStyles numberStyle, IFormatProvider formatProvider, out BoundingSphere result) { if (value == null) { throw new ArgumentNullException("value"); } var numbers = Float.Parse(value, numberStyle, formatProvider); if (numbers.Length == ValueCount) { result.Position.X = numbers[0]; result.Position.Y = numbers[1]; result.Position.Z = numbers[2]; result.Radius = numbers[3]; return true; } else { result = default(BoundingSphere); return false; } }
/// <summary> /// Determines whether the specified plane intersects with the specified bounding sphere. /// </summary> /// <param name="plane">A plane.</param> /// <param name="boundingSphere">A bounding sphere.</param> /// <returns>True if the <paramref name="plane"/> and the <paramref name="boundingSphere"/> intersect, otherwise false.</returns> public static bool PlaneWithBoundingSphere(Plane plane, BoundingSphere boundingSphere) { var distance = plane.A * boundingSphere.Position.X + plane.B * boundingSphere.Position.Y + plane.C * boundingSphere.Position.Z + plane.D; return Math.Abs(distance) < boundingSphere.Radius; }
/// <summary> /// Initializes a new instance of the struct. /// </summary> /// <param name="boundingSphere">Bounding sphere to copy.</param> public BoundingSphere(BoundingSphere boundingSphere) { this.Position = boundingSphere.Position; this.Radius = boundingSphere.Radius; }
/// <summary> /// Returns the distance between the specified bounding spheres. /// </summary> /// <param name="boundingSphere1">A bounding sphere.</param> /// <param name="boundingSphere2">A bounding sphere.</param> /// <returns>The distance between the <paramref name="boundingSphere1"/> and the <paramref name="boundingSphere2"/>.</returns> public static Number BoundingSphereToBoundingSphere(BoundingSphere boundingSphere1, BoundingSphere boundingSphere2) { return Math.Max(0, Distance.PointToPoint(boundingSphere1.Position, boundingSphere2.Position) - boundingSphere1.Radius - boundingSphere2.Radius); }