1
1
# SPDX-FileCopyrightText: Copyright (c) 2021 Dan Halbert for Adafruit Industries LLC
2
+ # SPDX-FileCopyrightText: 2021 James Carr
2
3
#
3
4
# SPDX-License-Identifier: MIT
4
5
"""
8
9
Math utility functions
9
10
10
11
11
- * Author(s): Adafruit Industries
12
+ * Author(s): Dan Halbert, James Carr
12
13
13
14
Implementation Notes
14
15
--------------------
@@ -27,12 +28,59 @@ def map_range(
27
28
x : float , in_min : float , in_max : float , out_min : float , out_max : float
28
29
) -> float :
29
30
"""
30
- Maps a number from one range to another. Somewhat similar to the Arduino ``map()`` function,
31
- but returns a floating point result, and constrains the output value to be between
32
- ``out_min`` and ``out_max``.
33
- If ``in_min`` is greater than ``in_max`` or ``out_min`` is greater than ``out_max``,
34
- the corresponding range is reversed, allowing, for example, mapping a range of 0-10 to 50-0.
31
+ Maps a number from one range to another. Somewhat similar to the Arduino
32
+ :attr:`map()` function, but returns a floating point result, and
33
+ constrains the output value to be between :attr:`out_min` and
34
+ :attr:`out_max`. If :attr:`in_min` is greater than :attr:`in_max` or
35
+ :attr:`out_min` is greater than :attr:`out_max`, the corresponding range
36
+ is reversed, allowing, for example, mapping a range of 0-10 to 50-0.
35
37
38
+ See also :py:func:`map_unconstrained_range`
39
+
40
+ .. code-block::
41
+
42
+ from adafruit_simplemath import map_range
43
+
44
+ percent = 23
45
+ screen_width = 320 # or board.DISPLAY.width
46
+ x = map_range(percent, 0, 100, 0, screen_width - 1)
47
+ print("X position", percent, "% from the left of screen is", x)
48
+
49
+ :param float x: Value to convert
50
+ :param float in_min: Start value of input range.
51
+ :param float in_max: End value of input range.
52
+ :param float out_min: Start value of output range.
53
+ :param float out_max: End value of output range.
54
+ :return: Returns value mapped to new range.
55
+ :rtype: float
56
+ """
57
+
58
+ mapped = map_unconstrained_range (x , in_min , in_max , out_min , out_max )
59
+ return constrain (mapped , out_min , out_max )
60
+
61
+
62
+ def map_unconstrained_range (
63
+ x : float , in_min : float , in_max : float , out_min : float , out_max : float
64
+ ) -> float :
65
+ """
66
+ Maps a number from one range to another. Somewhat similar to the Arduino
67
+ :attr:`map()` function, but returns a floating point result, and
68
+ does not constrain the output value to be between :attr:`out_min` and
69
+ :attr:`out_max`. If :attr:`in_min` is greater than :attr:`in_max` or
70
+ :attr:`out_min` is greater than :attr:`out_max`, the corresponding range
71
+ is reversed, allowing, for example, mapping a range of 0-10 to 50-0.
72
+
73
+ See also :py:func:`map_range`
74
+
75
+ .. code-block::
76
+
77
+ from adafruit_simplemath import map_unconstrained_range
78
+
79
+ celsius = -20
80
+ fahrenheit = map_unconstrained_range(celsius, 0, 100, 32, 212)
81
+ print(celsius, "degress Celsius =", fahrenheit, "degrees Fahrenheit")
82
+
83
+ :param float x: Value to convert
36
84
:param float in_min: Start value of input range.
37
85
:param float in_max: End value of input range.
38
86
:param float out_min: Start value of output range.
@@ -50,22 +98,26 @@ def map_range(
50
98
mapped = 0.5
51
99
mapped *= out_max - out_min
52
100
mapped += out_min
53
- if out_min <= out_max :
54
- return max (min (mapped , out_max ), out_min )
55
- return min (max (mapped , out_max ), out_min )
101
+
102
+ return mapped
56
103
57
104
58
105
def constrain (x : float , out_min : float , out_max : float ) -> float :
59
- """Constrains ``x`` to be within the inclusive range [``out_min``, ``out_max``].
60
- Sometimes called ``clip`` or ``clamp`` in other libraries.
61
- ``out_min`` should be less than or equal to ``out_max``.
62
- If ``x`` is less than ``out_min``, return ``out_min``.
63
- If ``x`` is greater than ``out_max``, return ``out_max``.
64
- Otherwise just return ``x``.
106
+ """Constrains :attr:`x` to be within the inclusive range
107
+ [:attr:`out_min`, :attr:`out_max`]. Sometimes called :attr:`clip` or
108
+ :attr:`clamp` in other libraries. :attr:`out_min` should be less than or
109
+ equal to :attr:`out_max`.
110
+ If :attr:`x` is less than :attr:`out_min`, return :attr:`out_min`.
111
+ If :attr:`x` is greater than :attr:`out_max`, return :attr:`out_max`.
112
+ Otherwise just return :attr:`x`.
113
+ If :attr:`max_value` is less than :attr:`min_value`, they will be swapped.
65
114
115
+ :param float x: Value to constrain
66
116
:param float out_min: Lower bound of output range.
67
117
:param float out_max: Upper bound of output range.
68
118
:return: Returns value constrained to given range.
69
119
:rtype: float
70
120
"""
71
- return max (out_min , min (x , out_max ))
121
+ if out_min <= out_max :
122
+ return max (min (x , out_max ), out_min )
123
+ return min (max (x , out_max ), out_min )
0 commit comments