| | | 1 | | //======================================================================= |
| | | 2 | | // FixedSlabProjection.cs |
| | | 3 | | //======================================================================= |
| | | 4 | | // MIT License, Copyright (c) 2024–present David Oravsky (mrdav30) |
| | | 5 | | // See LICENSE file in the project root for full license information. |
| | | 6 | | //======================================================================= |
| | | 7 | | |
| | | 8 | | using System; |
| | | 9 | | |
| | | 10 | | namespace FixedMathSharp.Geometry; |
| | | 11 | | |
| | | 12 | | /// <summary> |
| | | 13 | | /// Provides planar support points for centered finite shapes clipped to a |
| | | 14 | | /// closed world-Y slab. |
| | | 15 | | /// </summary> |
| | | 16 | | public static class FixedSlabProjection |
| | | 17 | | { |
| | | 18 | | /// <summary> |
| | | 19 | | /// Attempts to return the support point of a centered capsule's X/Z |
| | | 20 | | /// projection after clipping the capsule to <paramref name="slabY"/>. |
| | | 21 | | /// </summary> |
| | | 22 | | public static bool TryGetCapsuleSupport( |
| | | 23 | | Vector3d center, |
| | | 24 | | Vector3d axisDirection, |
| | | 25 | | Fixed64 axisLength, |
| | | 26 | | Fixed64 radius, |
| | | 27 | | FixedRange slabY, |
| | | 28 | | Vector2d direction, |
| | | 29 | | out Vector2d support) |
| | | 30 | | { |
| | 147 | 31 | | Validate(axisDirection, axisLength, nameof(axisLength), radius, slabY, direction, requirePositiveLength: false); |
| | 144 | 32 | | return WideSlabProjection.TryGetCapsuleSupport( |
| | 144 | 33 | | center, axisDirection, axisLength, radius, slabY, direction, out support); |
| | | 34 | | } |
| | | 35 | | |
| | | 36 | | /// <summary> |
| | | 37 | | /// Attempts to return the support point of a centered finite cylinder's |
| | | 38 | | /// X/Z projection after clipping the cylinder to <paramref name="slabY"/>. |
| | | 39 | | /// </summary> |
| | | 40 | | public static bool TryGetCylinderSupport( |
| | | 41 | | Vector3d center, |
| | | 42 | | Vector3d axisDirection, |
| | | 43 | | Fixed64 axisLength, |
| | | 44 | | Fixed64 radius, |
| | | 45 | | FixedRange slabY, |
| | | 46 | | Vector2d direction, |
| | | 47 | | out Vector2d support) |
| | | 48 | | { |
| | 16 | 49 | | Validate(axisDirection, axisLength, nameof(axisLength), radius, slabY, direction, requirePositiveLength: true); |
| | 15 | 50 | | return WideSlabProjection.TryGetCylinderSupport( |
| | 15 | 51 | | center, axisDirection, axisLength, radius, slabY, direction, out support); |
| | | 52 | | } |
| | | 53 | | |
| | | 54 | | /// <summary> |
| | | 55 | | /// Attempts to return the support point of a centered finite cone's X/Z |
| | | 56 | | /// projection after clipping the cone to <paramref name="slabY"/>. |
| | | 57 | | /// </summary> |
| | | 58 | | /// <param name="center">The cone center.</param> |
| | | 59 | | /// <param name="axisDirection">The normalized direction from base to apex.</param> |
| | | 60 | | /// <param name="height">The positive full parametric height.</param> |
| | | 61 | | /// <param name="radius">The nonnegative base radius.</param> |
| | | 62 | | /// <param name="slabY">The inclusive world-Y clipping interval.</param> |
| | | 63 | | /// <param name="direction">The normalized X/Z support direction.</param> |
| | | 64 | | /// <param name="support">The winning planar support point when representable.</param> |
| | | 65 | | /// <returns><see langword="true"/> when the clipped cone has a representable support point.</returns> |
| | | 66 | | public static bool TryGetConeSupport( |
| | | 67 | | Vector3d center, |
| | | 68 | | Vector3d axisDirection, |
| | | 69 | | Fixed64 height, |
| | | 70 | | Fixed64 radius, |
| | | 71 | | FixedRange slabY, |
| | | 72 | | Vector2d direction, |
| | | 73 | | out Vector2d support) |
| | | 74 | | { |
| | 25 | 75 | | Validate(axisDirection, height, nameof(height), radius, slabY, direction, requirePositiveLength: true); |
| | 22 | 76 | | return WideSlabProjection.TryGetConeSupport( |
| | 22 | 77 | | center, axisDirection, height, radius, slabY, direction, out support); |
| | | 78 | | } |
| | | 79 | | |
| | | 80 | | private static void Validate( |
| | | 81 | | Vector3d axisDirection, |
| | | 82 | | Fixed64 length, |
| | | 83 | | string lengthParameterName, |
| | | 84 | | Fixed64 radius, |
| | | 85 | | FixedRange slabY, |
| | | 86 | | Vector2d direction, |
| | | 87 | | bool requirePositiveLength) |
| | | 88 | | { |
| | 188 | 89 | | if (!axisDirection.IsNormalized()) |
| | 1 | 90 | | throw new ArgumentException("Shape axis direction must be normalized.", nameof(axisDirection)); |
| | 187 | 91 | | if (requirePositiveLength ? length <= Fixed64.Zero : length < Fixed64.Zero) |
| | 3 | 92 | | throw new ArgumentOutOfRangeException(lengthParameterName); |
| | 184 | 93 | | if (radius < Fixed64.Zero) |
| | 1 | 94 | | throw new ArgumentOutOfRangeException(nameof(radius)); |
| | 183 | 95 | | if (slabY.Min > slabY.Max) |
| | 1 | 96 | | throw new ArgumentException("Slab minimum must not exceed its maximum.", nameof(slabY)); |
| | 182 | 97 | | if (!direction.IsNormalized()) |
| | 1 | 98 | | throw new ArgumentException("Planar support direction must be normalized.", nameof(direction)); |
| | 181 | 99 | | } |
| | | 100 | | } |