1
+ package io.monstarlab.mosaic.slider
2
+
3
+ public class ValueCheckPointDistribution (valuesMap : List <Pair <Float , Float >>) :
4
+ SliderValueDistribution {
5
+
6
+ private var equations: List <RangedLinearEquation >
7
+
8
+ init {
9
+ require(valuesMap.isNotEmpty()) { " values map can't be empty" }
10
+ val offsetRange = valuesMap.minOf { it.first }.. valuesMap.maxOf { it.first }
11
+ val valueRange = valuesMap.minOf { it.second }.. valuesMap.maxOf { it.second }
12
+ val zipped = valuesMap.sortedBy { it.first }
13
+ .zipWithNext()
14
+ // make sure all values are increasing, otherwise throw an exception
15
+ zipped.firstOrNull { it.first.second >= it.second.second }
16
+ ?.let {
17
+ throw DecreasingValueException (it.first)
18
+ }
19
+ equations = zipped.map {
20
+ val x1Fraction = it.first.first.valueToFraction(offsetRange)
21
+ val x2Fraction = it.second.first.valueToFraction(offsetRange)
22
+ val y1Fraction = it.first.second.valueToFraction(valueRange)
23
+ val y2Fraction = it.second.second.valueToFraction(valueRange)
24
+ val equation = LinearEquation .fromTowPoints(
25
+ x1 = x1Fraction,
26
+ x2 = x2Fraction,
27
+ y1 = y1Fraction,
28
+ y2 = y2Fraction,
29
+ )
30
+ RangedLinearEquation (
31
+ equation = equation,
32
+ offsetRange = x1Fraction.. x2Fraction,
33
+ valueRange = y1Fraction.. y2Fraction,
34
+
35
+ )
36
+ }
37
+ }
38
+
39
+
40
+ override fun interpolate (value : Float ): Float =
41
+ equations.first { it.offsetRange.contains(value) }.equation.valueFromOffset(value)
42
+
43
+
44
+ override fun inverse (value : Float ): Float =
45
+ equations.first { it.valueRange.contains(value) }.equation.offsetFromValue(value)
46
+
47
+
48
+ public class DecreasingValueException (progressValuePair : Pair <Float , Float >) :
49
+ Exception (
50
+ " Values must be always increasing with increasing progress," +
51
+ " item at progress ${progressValuePair.first} with value " +
52
+ " ${progressValuePair.second} is breaking this rule "
53
+ )
54
+ }
0 commit comments