2019-08-06 14:20:11 +02:00
using System ;
2019-08-07 00:45:40 +02:00
using Microsoft.Xna.Framework ;
2019-11-02 14:53:59 +01:00
using MLEM.Misc ;
2019-08-06 14:20:11 +02:00
namespace MLEM.Extensions {
2020-05-21 12:53:42 +02:00
/// <summary>
/// A set of extensions for dealing with <see cref="float"/>, <see cref="Vector2"/>, <see cref="Vector3"/>, <see cref="Vector4"/>, <see cref="Point"/>, <see cref="Rectangle"/> and <see cref="RectangleF"/>
/// </summary>
2019-08-06 14:20:11 +02:00
public static class NumberExtensions {
2020-05-20 23:59:40 +02:00
/// <inheritdoc cref="Math.Floor(decimal)"/>
2019-08-06 14:20:11 +02:00
public static int Floor ( this float f ) {
return ( int ) Math . Floor ( f ) ;
}
2020-05-20 23:59:40 +02:00
/// <inheritdoc cref="Math.Ceiling(decimal)"/>
2019-08-06 14:20:11 +02:00
public static int Ceil ( this float f ) {
return ( int ) Math . Ceiling ( f ) ;
}
2020-05-20 23:59:40 +02:00
/// <summary>
/// Checks for decimal equality with a given tolerance.
/// </summary>
/// <param name="first">The first number to equate</param>
/// <param name="second">The second number to equate</param>
/// <param name="tolerance">The equality tolerance</param>
2020-05-21 17:21:34 +02:00
/// <returns>Whether or not the two values are different by at most <c>tolerance</c></returns>
2019-12-26 12:49:04 +01:00
public static bool Equals ( this float first , float second , float tolerance ) {
2020-05-20 23:59:40 +02:00
return Math . Abs ( first - second ) < = tolerance ;
2019-12-26 12:49:04 +01:00
}
2020-05-20 23:59:40 +02:00
/// <inheritdoc cref="Equals(float,float,float)"/>
2019-12-26 12:49:04 +01:00
public static bool Equals ( this Vector2 first , Vector2 second , float tolerance ) {
return Math . Abs ( first . X - second . X ) < = tolerance & & Math . Abs ( first . Y - second . Y ) < = tolerance ;
}
2020-05-20 23:59:40 +02:00
/// <inheritdoc cref="Equals(float,float,float)"/>
2019-12-26 12:49:04 +01:00
public static bool Equals ( this Vector3 first , Vector3 second , float tolerance ) {
return Math . Abs ( first . X - second . X ) < = tolerance & & Math . Abs ( first . Y - second . Y ) < = tolerance & & Math . Abs ( first . Z - second . Z ) < = tolerance ;
}
2020-05-20 23:59:40 +02:00
/// <inheritdoc cref="Equals(float,float,float)"/>
2019-12-26 12:49:04 +01:00
public static bool Equals ( this Vector4 first , Vector4 second , float tolerance ) {
return Math . Abs ( first . X - second . X ) < = tolerance & & Math . Abs ( first . Y - second . Y ) < = tolerance & & Math . Abs ( first . Z - second . Z ) < = tolerance & & Math . Abs ( first . W - second . W ) < = tolerance ;
}
2020-05-20 23:59:40 +02:00
/// <inheritdoc cref="Math.Floor(decimal)"/>
2019-08-07 00:45:40 +02:00
public static Vector2 Floor ( this Vector2 vec ) {
return new Vector2 ( vec . X . Floor ( ) , vec . Y . Floor ( ) ) ;
}
2020-05-20 23:59:40 +02:00
/// <inheritdoc cref="Math.Floor(decimal)"/>
2019-08-07 00:45:40 +02:00
public static Vector3 Floor ( this Vector3 vec ) {
return new Vector3 ( vec . X . Floor ( ) , vec . Y . Floor ( ) , vec . Z . Floor ( ) ) ;
}
2020-05-20 23:59:40 +02:00
/// <inheritdoc cref="Math.Floor(decimal)"/>
2019-08-07 00:45:40 +02:00
public static Vector4 Floor ( this Vector4 vec ) {
return new Vector4 ( vec . X . Floor ( ) , vec . Y . Floor ( ) , vec . Z . Floor ( ) , vec . W . Floor ( ) ) ;
}
2019-08-06 14:20:11 +02:00
2020-05-20 23:59:40 +02:00
/// <summary>
/// Multiplies a point by a given scalar.
/// </summary>
/// <param name="point">The point</param>
/// <param name="f">The scalar</param>
/// <returns>The point, multiplied by the scalar memberwise</returns>
2019-08-11 21:24:09 +02:00
public static Point Multiply ( this Point point , float f ) {
return new Point ( ( point . X * f ) . Floor ( ) , ( point . Y * f ) . Floor ( ) ) ;
}
2020-05-20 23:59:40 +02:00
/// <summary>
/// Divides a point by a given scalar.
/// </summary>
/// <param name="point">The point</param>
/// <param name="f">The scalar</param>
/// <returns>The point, divided by the scalar memberwise</returns>
2019-08-15 14:59:15 +02:00
public static Point Divide ( this Point point , float f ) {
return new Point ( ( point . X / f ) . Floor ( ) , ( point . Y / f ) . Floor ( ) ) ;
}
2020-05-20 23:59:40 +02:00
/// <summary>
/// Transforms a point by a given matrix.
/// </summary>
/// <param name="position">The point</param>
/// <param name="matrix">The matrix</param>
/// <returns>The point, transformed by the matrix</returns>
2019-09-02 19:55:26 +02:00
public static Point Transform ( this Point position , Matrix matrix ) {
return new Point (
( position . X * matrix . M11 + position . Y * matrix . M21 + matrix . M41 ) . Floor ( ) ,
( position . X * matrix . M12 + position . Y * matrix . M22 + matrix . M42 ) . Floor ( ) ) ;
}
2020-05-20 23:59:40 +02:00
/// <summary>
/// Returns a copy of the given rectangle, moved by the given point.
/// The rectangle's size remains unchanged.
/// </summary>
/// <param name="rect">The rectangle to move</param>
/// <param name="offset">The amount to move by</param>
/// <returns>The moved rectangle</returns>
2019-08-12 19:44:16 +02:00
public static Rectangle OffsetCopy ( this Rectangle rect , Point offset ) {
rect . X + = offset . X ;
rect . Y + = offset . Y ;
return rect ;
}
2020-05-20 23:59:40 +02:00
/// <inheritdoc cref="OffsetCopy(Microsoft.Xna.Framework.Rectangle,Microsoft.Xna.Framework.Point)"/>
2019-11-02 14:53:59 +01:00
public static RectangleF OffsetCopy ( this RectangleF rect , Vector2 offset ) {
rect . X + = offset . X ;
rect . Y + = offset . Y ;
return rect ;
}
2020-05-20 23:59:40 +02:00
/// <summary>
/// Shrinks the rectangle by the given padding, causing its size to decrease by twice the amount and its position to be moved inwards by the amount.
/// </summary>
/// <param name="rect">The rectangle to shrink</param>
/// <param name="padding">The padding to shrink by</param>
/// <returns>The shrunk rectangle</returns>
2019-09-10 23:28:25 +02:00
public static Rectangle Shrink ( this Rectangle rect , Point padding ) {
rect . X + = padding . X ;
rect . Y + = padding . Y ;
rect . Width - = padding . X * 2 ;
rect . Height - = padding . Y * 2 ;
return rect ;
}
2020-05-20 23:59:40 +02:00
/// <inheritdoc cref="Shrink(Microsoft.Xna.Framework.Rectangle,Microsoft.Xna.Framework.Point)"/>
2019-11-02 14:53:59 +01:00
public static RectangleF Shrink ( this RectangleF rect , Vector2 padding ) {
rect . X + = padding . X ;
rect . Y + = padding . Y ;
rect . Width - = padding . X * 2 ;
rect . Height - = padding . Y * 2 ;
return rect ;
}
2020-05-20 23:59:40 +02:00
/// <inheritdoc cref="Shrink(Microsoft.Xna.Framework.Rectangle,Microsoft.Xna.Framework.Point)"/>
2019-12-14 14:00:12 +01:00
public static RectangleF Shrink ( this RectangleF rect , Padding padding ) {
rect . X + = padding . Left ;
2019-12-14 14:07:00 +01:00
rect . Y + = padding . Top ;
2019-12-14 14:00:12 +01:00
rect . Width - = padding . Width ;
rect . Height - = padding . Height ;
return rect ;
}
2019-08-06 14:20:11 +02:00
}
}