Whiplash141

TempPaste

Sep 6th, 2018
193
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.49 KB | None | 0 0
  1. void PointRotorAtVector(
  2.     IMyMotorStator rotor, // Rotor of interest
  3.     Vector3D targetDirection, // World direction to the target
  4.     Vector3D currentDirection, // World direction of current orientation
  5.     double proportionalGain) // Essentially how fast this thing will spin
  6. {
  7.     // This is also the rotation axis of the rotor
  8.     var upDirection = rotor.WorldMatrix.Up;
  9.  
  10.     // This removes any out-of-rotation-plane vector components
  11.     var currentDirectionFlat = VectorMath.Rejection(currentDirection, upDirection);
  12.     var targetDirectionFlat = VectorMath.Rejection(targetDirection, upDirection);
  13.  
  14.     // Get the unsigned angle between the target direction and current direction
  15.     var angle = VectorMath.AngleBetween(currentDirectionFlat, targetDirectionFlat);
  16.  
  17.     // Get the sign of the angle
  18.     var num = Vector3D.Dot(Vector3D.Cross(targetDirectionFlat, currentDirectionFlat), upDirection);
  19.     num = num > 0 ? 1 : -1;
  20.  
  21.     rotor.TargetVelocityRPM = (float)(proportionalGain * angle * num);
  22. }
  23.  
  24. public static class VectorMath
  25. {
  26.     /// <summary>
  27.     ///  Normalizes a vector only if it is non-zero and non-unit
  28.     /// </summary>
  29.     public static Vector3D SafeNormalize(Vector3D a)
  30.     {
  31.         if (Vector3D.IsZero(a))
  32.             return Vector3D.Zero;
  33.  
  34.         if (Vector3D.IsUnit(ref a))
  35.             return a;
  36.  
  37.         return Vector3D.Normalize(a);
  38.     }
  39.  
  40.     /// <summary>
  41.     /// Reflects vector a over vector b with an optional rejection factor
  42.     /// </summary>
  43.     public static Vector3D Reflection(Vector3D a, Vector3D b, double rejectionFactor = 1) //reflect a over b
  44.     {
  45.         Vector3D project_a = Projection(a, b);
  46.         Vector3D reject_a = a - project_a;
  47.         return project_a - reject_a * rejectionFactor;
  48.     }
  49.  
  50.     /// <summary>
  51.     /// Rejects vector a on vector b
  52.     /// </summary>
  53.     public static Vector3D Rejection(Vector3D a, Vector3D b) //reject a on b
  54.     {
  55.         if (Vector3D.IsZero(a) || Vector3D.IsZero(b))
  56.             return Vector3D.Zero;
  57.  
  58.         return a - a.Dot(b) / b.LengthSquared() * b;
  59.     }
  60.  
  61.     /// <summary>
  62.     /// Projects vector a onto vector b
  63.     /// </summary>
  64.     public static Vector3D Projection(Vector3D a, Vector3D b)
  65.     {
  66.         if (Vector3D.IsZero(a) || Vector3D.IsZero(b))
  67.             return Vector3D.Zero;
  68.  
  69.         return a.Dot(b) / b.LengthSquared() * b;
  70.     }
  71.  
  72.     /// <summary>
  73.     /// Scalar projection of a onto b
  74.     /// </summary>
  75.     public static double ScalarProjection(Vector3D a, Vector3D b)
  76.     {
  77.         if (Vector3D.IsZero(a) || Vector3D.IsZero(b))
  78.             return 0;
  79.  
  80.         if (Vector3D.IsUnit(ref b))
  81.             return a.Dot(b);
  82.  
  83.         return a.Dot(b) / b.Length();
  84.     }
  85.  
  86.     /// <summary>
  87.     /// Computes angle between 2 vectors
  88.     /// </summary>
  89.     public static double AngleBetween(Vector3D a, Vector3D b) //returns radians
  90.     {
  91.         if (Vector3D.IsZero(a) || Vector3D.IsZero(b))
  92.             return 0;
  93.         else
  94.             return Math.Acos(MathHelper.Clamp(a.Dot(b) / Math.Sqrt(a.LengthSquared() * b.LengthSquared()), -1, 1));
  95.     }
  96.  
  97.     /// <summary>
  98.     /// Computes cosine of the angle between 2 vectors
  99.     /// </summary>
  100.     public static double CosBetween(Vector3D a, Vector3D b, bool useSmallestAngle = false) //returns radians
  101.     {
  102.         if (Vector3D.IsZero(a) || Vector3D.IsZero(b))
  103.             return 0;
  104.         else
  105.             return MathHelper.Clamp(a.Dot(b) / Math.Sqrt(a.LengthSquared() * b.LengthSquared()), -1, 1);
  106.     }
  107. }
Advertisement
Add Comment
Please, Sign In to add comment