Skip to content

Commit 7ab4cdb

Browse files
committed
More range type
1 parent 5d02a25 commit 7ab4cdb

File tree

1 file changed

+76
-62
lines changed
  • common/src/main/kotlin/com/lambda/util/math

1 file changed

+76
-62
lines changed
Lines changed: 76 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,99 @@
11
package com.lambda.util.math
22

3-
import net.minecraft.util.math.Box
43
import 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

Comments
 (0)