11package com.lambda.util.math
22
3- import net.minecraft.util.math.Box
43import kotlin.random.Random.Default.nextDouble
54
6- class DoubleRange (
7- override val start : Double ,
8- override val endInclusive : Double ,
9- ) : ClosedRange<Double> {
10- infix fun step (step : Double ): DoubleIterator {
11- return object : DoubleIterator () {
12- private var next = start
13- override fun hasNext () = next <= endInclusive
14- override fun nextDouble () = next.also { next + = step }
15- }
16- }
17-
18- /* *
19- * Returns a random value within the range.
20- */
21- fun random () = nextDouble(start, endInclusive)
22-
23- /* *
24- * Returns a bounding box from two additional ranges.
25- * @param y The second range.
26- * @param z The third range.
27- * @return The bounding box.
28- */
29- fun box (y : DoubleRange , z : DoubleRange ) =
30- Box (this .start, y.start, z.start, this .endInclusive, y.endInclusive, z.endInclusive)
5+ /* *
6+ * Iterates over the double range with the specified step.
7+ */
8+ fun ClosedRange<Double>.step (step : Double ) = object : DoubleIterator () {
9+ private var next = start
10+ override fun hasNext () = next <= endInclusive
11+ override fun nextDouble () = next.also { next + = step }
3112}
3213
33- infix fun Double.to (that : Double ) = DoubleRange (this , that)
14+ /* *
15+ * Iterates over the float range with the specified step.
16+ */
17+ fun ClosedRange<Float>.step (step : Float ) = object : FloatIterator () {
18+ private var next = start
19+ override fun hasNext () = next <= endInclusive
20+ override fun nextFloat () = next.also { next + = step }
21+ }
22+
23+ /* *
24+ * Returns a random number within the range.
25+ */
26+ fun ClosedRange<Double>.random () = nextDouble(start, endInclusive)
27+
28+ /* *
29+ * Converts a value from one range to a normalized value between 0 and 1.
30+ */
31+ fun ClosedRange<Double>.normalize (value : Double ): Double =
32+ scale(value, 0.0 , 1.0 )
3433
3534/* *
3635 * Converts a value from one range to a normalized value between 0 and 1.
3736 */
38- fun <T > ClosedRange<T>.normalized (value : T ): T where T : Comparable <T >, T : Number =
39- scale(value, 0.0 as T , 1.0 as T ) // hacky
37+ fun ClosedRange<Float>.normalize (value : Float ): Float =
38+ scale(value, 0.0f , 1.0f )
39+
40+ /* *
41+ * Inverts the range.
42+ */
43+ fun ClosedRange<Double>.inverted () = endInclusive to start
4044
4145/* *
4246 * Inverts the range.
4347 */
44- fun <T > ClosedRange<T>.inverted (): ClosedRange <T > where T : Comparable <T >, T : Number = endInclusive.. start
48+ fun ClosedRange<Float>.inverted () = endInclusive to start
49+
50+ /* *
51+ * Sinusoidal interpolation between two values.
52+ */
53+ fun ClosedRange<Double>.sinInterpolate (value : Double ): Double =
54+ transform(value, start, endInclusive, - 1.0 , 1.0 )
55+
56+ /* *
57+ * Sinusoidal interpolation between two values.
58+ */
59+ fun ClosedRange<Float>.sinInterpolate (value : Float ): Float =
60+ transform(value, start, endInclusive, - 1.0f , 1.0f )
61+
62+ /* *
63+ * Converts a value from one range to another while keeping the ratio using linear interpolation.
64+ * @param value The value to convert.
65+ * @param minIn The minimum of the new range.
66+ * @param maxIn The maximum of the new range.
67+ * @return The converted value.
68+ */
69+ fun ClosedRange<Double>.scale (value : Double , minIn : Double , maxIn : Double ): Double =
70+ transform(value, start, endInclusive, minIn, maxIn)
4571
4672/* *
47- * Converts a value from one range to another while keeping the ratio using exponential interpolation.
73+ * Converts a value from one range to another while keeping the ratio using linear interpolation.
4874 * @param value The value to convert.
4975 * @param minIn The minimum of the new range.
5076 * @param maxIn The maximum of the new range.
5177 * @return The converted value.
5278 */
53- fun < T > ClosedRange<T >.scale (value : T , minIn : T , maxIn : T ): T where T : Comparable < T >, T : Number =
79+ fun ClosedRange<Float >.scale (value : Float , minIn : Float , maxIn : Float ): Float =
5480 transform(value, start, endInclusive, minIn, maxIn)
5581
5682/* *
57- * Converts a value from one range to another while keeping the ratio using exponential interpolation.
83+ * Converts a value from one range to another while keeping the ratio using linear interpolation.
84+ * @param value The value to convert.
85+ * @param x1 The minimum of the old range.
86+ * @param y1 The maximum of the old range.
87+ * @param x2 The minimum of the new range.
88+ * @param y2 The maximum of the new range.
89+ * @return The converted value.
90+ * @see <a href="https://en.wikipedia.org/wiki/Linear_interpolation">Linear Interpolation</a>
91+ */
92+ fun transform (value : Double , x1 : Double , y1 : Double , x2 : Double , y2 : Double ): Double =
93+ (x2 + (value - x1) * ((y2 - x2) / (y1 - x1)))
94+
95+ /* *
96+ * Converts a value from one range to another while keeping the ratio using linear interpolation.
5897 * @param value The value to convert.
5998 * @param x1 The minimum of the old range.
6099 * @param y1 The maximum of the old range.
@@ -63,38 +102,13 @@ fun <T> ClosedRange<T>.scale(value: T, minIn: T, maxIn: T): T where T : Comparab
63102 * @return The converted value.
64103 * @see <a href="https://en.wikipedia.org/wiki/Linear_interpolation">Linear Interpolation</a>
65104 */
66- fun < T > transform (value : T , x1 : T , y1 : T , x2 : T , y2 : T ): T where T : Comparable < T >, T : Number =
67- x2 + (value - x1) * ((y2 - x2) / (y1 - x1))
105+ fun transform (value : Float , x1 : Float , y1 : Float , x2 : Float , y2 : Float ): Float =
106+ ( x2 + (value - x1) * ((y2 - x2) / (y1 - x1) ))
68107
69108
70109/* *
71- * Clamps a value to the range.
110+ * Coerces a value to be within the range.
72111 * @param value The value to clamp.
73112 * @return The clamped value.
74113 */
75- fun <T : Comparable <T >> ClosedRange<T>.coerceIn (value : T ) = value.coerceIn(start, endInclusive)
76- fun <T : Comparable <T >> T.coerceIn (range : ClosedRange <T >) = range.coerceIn(this )
77-
78- private operator fun <T > T.minus (oldMin : T ): T where T : Comparable <T >, T : Number {
79- return (this .toDouble() - oldMin.toDouble()) as T
80- }
81-
82- private operator fun <T > T.div (other : T ): T where T : Comparable <T >, T : Number {
83- return (this .toDouble() / other.toDouble()) as T
84- }
85-
86- private operator fun <T > T.times (other : T ): T where T : Comparable <T >, T : Number {
87- return (this .toDouble() * other.toDouble()) as T
88- }
89-
90- private operator fun <T > T.plus (other : T ): T where T : Comparable <T >, T : Number {
91- return (this .toDouble() + other.toDouble()) as T
92- }
93-
94- fun <T > min (newMin : T , newMax : T ): T where T : Comparable <T >, T : Number {
95- return if (newMin < newMax) newMin else newMax
96- }
97-
98- fun <T > max (newMin : T , newMax : T ): T where T : Comparable <T >, T : Number {
99- return if (newMin > newMax) newMin else newMax
100- }
114+ fun ClosedRange<Double>.coerceIn (value : Double ) = value.coerceIn(start, endInclusive)
0 commit comments