178 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			178 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 
								 | 
							
								package math
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import (
							 | 
						||
| 
								 | 
							
									"math"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									"golang.org/x/exp/constraints"
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Various useful constants.
							 | 
						||
| 
								 | 
							
								var (
							 | 
						||
| 
								 | 
							
									MinNormal = float32(1.1754943508222875e-38) // 1 / 2**(127 - 1)
							 | 
						||
| 
								 | 
							
									MinValue  = float32(math.SmallestNonzeroFloat32)
							 | 
						||
| 
								 | 
							
									MaxValue  = float32(math.MaxFloat32)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									InfPos = float32(math.Inf(1))
							 | 
						||
| 
								 | 
							
									InfNeg = float32(math.Inf(-1))
							 | 
						||
| 
								 | 
							
									NaN    = float32(math.NaN())
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									E       = float32(math.E)
							 | 
						||
| 
								 | 
							
									Pi      = float32(math.Pi)
							 | 
						||
| 
								 | 
							
									PiOver2 = Pi / 2
							 | 
						||
| 
								 | 
							
									PiOver4 = Pi / 4
							 | 
						||
| 
								 | 
							
									Sqrt2   = float32(math.Sqrt2)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									Epsilon = float32(1e-10)
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Abs returns the absolute value of a number
							 | 
						||
| 
								 | 
							
								func Abs[T constraints.Float | constraints.Integer](v T) T {
							 | 
						||
| 
								 | 
							
									if v < 0 {
							 | 
						||
| 
								 | 
							
										return -v
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return v
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Min returns the smaller of two numbers
							 | 
						||
| 
								 | 
							
								func Min[T constraints.Ordered](a, b T) T {
							 | 
						||
| 
								 | 
							
									if a < b {
							 | 
						||
| 
								 | 
							
										return a
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return b
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Max returns the greater of two numbers
							 | 
						||
| 
								 | 
							
								func Max[T constraints.Ordered](a, b T) T {
							 | 
						||
| 
								 | 
							
									if a > b {
							 | 
						||
| 
								 | 
							
										return a
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return b
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Clamp a value between a minimum and a maximum value
							 | 
						||
| 
								 | 
							
								func Clamp[T constraints.Ordered](v, min, max T) T {
							 | 
						||
| 
								 | 
							
									if v > max {
							 | 
						||
| 
								 | 
							
										return max
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if v < min {
							 | 
						||
| 
								 | 
							
										return min
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return v
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Ceil a number to the closest integer
							 | 
						||
| 
								 | 
							
								func Ceil(x float32) float32 {
							 | 
						||
| 
								 | 
							
									return float32(math.Ceil(float64(x)))
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Floor a number to the closest integer
							 | 
						||
| 
								 | 
							
								func Floor(x float32) float32 {
							 | 
						||
| 
								 | 
							
									return float32(math.Floor(float64(x)))
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Mod returns the remainder of a floating point division
							 | 
						||
| 
								 | 
							
								func Mod(x, y float32) float32 {
							 | 
						||
| 
								 | 
							
									return float32(math.Mod(float64(x), float64(y)))
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Sqrt returns the square root of a number
							 | 
						||
| 
								 | 
							
								func Sqrt(x float32) float32 {
							 | 
						||
| 
								 | 
							
									return float32(math.Sqrt(float64(x)))
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Sin computes the sine of x
							 | 
						||
| 
								 | 
							
								func Sin(x float32) float32 {
							 | 
						||
| 
								 | 
							
									return float32(math.Sin(float64(x)))
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Cos computes the cosine of x
							 | 
						||
| 
								 | 
							
								func Cos(x float32) float32 {
							 | 
						||
| 
								 | 
							
									return float32(math.Cos(float64(x)))
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Tan computes the tangent of x
							 | 
						||
| 
								 | 
							
								func Tan(x float32) float32 {
							 | 
						||
| 
								 | 
							
									return float32(math.Tan(float64(x)))
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func Sincos(x float32) (float32, float32) {
							 | 
						||
| 
								 | 
							
									sin, cos := math.Sincos(float64(x))
							 | 
						||
| 
								 | 
							
									return float32(sin), float32(cos)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func Acos(x float32) float32 {
							 | 
						||
| 
								 | 
							
									return float32(math.Acos(float64(x)))
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func Asin(x float32) float32 {
							 | 
						||
| 
								 | 
							
									return float32(math.Asin(float64(x)))
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func Atan2(y, x float32) float32 {
							 | 
						||
| 
								 | 
							
									return float32(math.Atan2(float64(y), float64(x)))
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Sign returns the sign of x (-1 or 1)
							 | 
						||
| 
								 | 
							
								func Sign(x float32) float32 {
							 | 
						||
| 
								 | 
							
									if x > 0 {
							 | 
						||
| 
								 | 
							
										return 1
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return -1
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func Copysign(f, sign float32) float32 {
							 | 
						||
| 
								 | 
							
									return float32(math.Copysign(float64(f), float64(sign)))
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// DegToRad converts degrees to radians
							 | 
						||
| 
								 | 
							
								func DegToRad(deg float32) float32 {
							 | 
						||
| 
								 | 
							
									return Pi * deg / 180.0
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// RadToDeg converts radians to degrees
							 | 
						||
| 
								 | 
							
								func RadToDeg(rad float32) float32 {
							 | 
						||
| 
								 | 
							
									return 180.0 * rad / Pi
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Equal checks two floats for (approximate) equality
							 | 
						||
| 
								 | 
							
								func Equal(a, b float32) bool {
							 | 
						||
| 
								 | 
							
									return EqualThreshold(a, b, Epsilon)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// EqualThreshold is a utility function to compare floats.
							 | 
						||
| 
								 | 
							
								// It's Taken from http://floating-point-gui.de/errors/comparison/
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// It is slightly altered to not call Abs when not needed.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// This differs from FloatEqual in that it lets you pass in your comparison threshold, so that you can adjust the comparison value to your specific needs
							 | 
						||
| 
								 | 
							
								func EqualThreshold(a, b, epsilon float32) bool {
							 | 
						||
| 
								 | 
							
									if a == b { // Handles the case of inf or shortcuts the loop when no significant error has accumulated
							 | 
						||
| 
								 | 
							
										return true
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									diff := Abs(a - b)
							 | 
						||
| 
								 | 
							
									if a*b == 0 || diff < MinNormal { // If a or b are 0 or both are extremely close to it
							 | 
						||
| 
								 | 
							
										return diff < epsilon*epsilon
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// Else compare difference
							 | 
						||
| 
								 | 
							
									return diff/(Abs(a)+Abs(b)) < epsilon
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Lerp performs linear interpolation between a and b
							 | 
						||
| 
								 | 
							
								func Lerp(a, b, f float32) float32 {
							 | 
						||
| 
								 | 
							
									return a + f*(b-a)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func Round(f float32) float32 {
							 | 
						||
| 
								 | 
							
									return float32(math.Round(float64(f)))
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func Snap(f, multiple float32) float32 {
							 | 
						||
| 
								 | 
							
									return Ceil(f/multiple) * multiple
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func Pow(f, x float32) float32 {
							 | 
						||
| 
								 | 
							
									return float32(math.Pow(float64(f), float64(x)))
							 | 
						||
| 
								 | 
							
								}
							 |