A game framework written with osu! in mind.
at master 114 lines 5.0 kB view raw
1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. 2// See the LICENCE file in the repository root for full licence text. 3 4using System; 5using System.Runtime.CompilerServices; 6using osu.Framework.Graphics.Primitives; 7using osuTK; 8 9namespace osu.Framework.Graphics 10{ 11 public static class Vector2Extensions 12 { 13 /// <summary>Transform a Position by the given Matrix</summary> 14 /// <param name="pos">The position to transform</param> 15 /// <param name="mat">The desired transformation</param> 16 /// <returns>The transformed position</returns> 17 public static Vector2 Transform(Vector2 pos, Matrix3 mat) 18 { 19 Transform(ref pos, ref mat, out Vector2 result); 20 return result; 21 } 22 23 /// <summary>Transform a Position by the given Matrix</summary> 24 /// <param name="pos">The position to transform</param> 25 /// <param name="mat">The desired transformation</param> 26 /// <param name="result">The transformed vector</param> 27 public static void Transform(ref Vector2 pos, ref Matrix3 mat, out Vector2 result) 28 { 29 result.X = mat.Row0.X * pos.X + mat.Row1.X * pos.Y + mat.Row2.X; 30 result.Y = mat.Row0.Y * pos.X + mat.Row1.Y * pos.Y + mat.Row2.Y; 31 } 32 33 /// <summary> 34 /// Compute the euclidean distance between two vectors. 35 /// </summary> 36 /// <param name="vec1">The first vector</param> 37 /// <param name="vec2">The second vector</param> 38 /// <returns>The distance</returns> 39 public static float Distance(Vector2 vec1, Vector2 vec2) 40 { 41 Distance(ref vec1, ref vec2, out float result); 42 return result; 43 } 44 45 /// <summary> 46 /// Compute the euclidean distance between two vectors. 47 /// </summary> 48 /// <param name="vec1">The first vector</param> 49 /// <param name="vec2">The second vector</param> 50 /// <param name="result">The distance</param> 51 public static void Distance(ref Vector2 vec1, ref Vector2 vec2, out float result) 52 { 53 result = MathF.Sqrt((vec2.X - vec1.X) * (vec2.X - vec1.X) + (vec2.Y - vec1.Y) * (vec2.Y - vec1.Y)); 54 } 55 56 /// <summary> 57 /// Compute the squared euclidean distance between two vectors. 58 /// </summary> 59 /// <param name="vec1">The first vector</param> 60 /// <param name="vec2">The second vector</param> 61 /// <returns>The squared distance</returns> 62 public static float DistanceSquared(Vector2 vec1, Vector2 vec2) 63 { 64 DistanceSquared(ref vec1, ref vec2, out float result); 65 return result; 66 } 67 68 /// <summary> 69 /// Compute the squared euclidean distance between two vectors. 70 /// </summary> 71 /// <param name="vec1">The first vector</param> 72 /// <param name="vec2">The second vector</param> 73 /// <param name="result">The squared distance</param> 74 public static void DistanceSquared(ref Vector2 vec1, ref Vector2 vec2, out float result) 75 { 76 result = (vec2.X - vec1.X) * (vec2.X - vec1.X) + (vec2.Y - vec1.Y) * (vec2.Y - vec1.Y); 77 } 78 79 /// <summary> 80 /// Retrieves the orientation of a set of vertices using the Shoelace formula (https://en.wikipedia.org/wiki/Shoelace_formula) 81 /// </summary> 82 /// <param name="vertices">The vertices.</param> 83 /// <returns>Twice the area enclosed by the vertices. 84 /// The vertices are clockwise-oriented if the value is positive. 85 /// The vertices are counter-clockwise-oriented if the value is negative.</returns> 86 [MethodImpl(MethodImplOptions.AggressiveInlining)] 87 public static float GetOrientation(in ReadOnlySpan<Vector2> vertices) 88 { 89 if (vertices.Length == 0) 90 return 0; 91 92 float rotation = 0; 93 for (int i = 0; i < vertices.Length - 1; ++i) 94 rotation += (vertices[i + 1].X - vertices[i].X) * (vertices[i + 1].Y + vertices[i].Y); 95 96 rotation += (vertices[0].X - vertices[^1].X) * (vertices[0].Y + vertices[^1].Y); 97 98 return rotation; 99 } 100 101 /// <summary> 102 /// Determines whether a point is within the right half-plane of a line. 103 /// </summary> 104 /// <param name="line">The line.</param> 105 /// <param name="point">The point.</param> 106 /// <returns>Whether <paramref name="point"/> is in the right half-plane of <paramref name="line"/>. 107 /// If the point is colinear to the line, it is said to be in the right half-plane of the line. 108 /// </returns> 109 [MethodImpl(MethodImplOptions.AggressiveInlining)] 110 public static bool InRightHalfPlaneOf(this Vector2 point, in Line line) 111 => (line.EndPoint.X - line.StartPoint.X) * (point.Y - line.StartPoint.Y) 112 - (line.EndPoint.Y - line.StartPoint.Y) * (point.X - line.StartPoint.X) <= 0; 113 } 114}