11# SPDX-FileCopyrightText: Copyright (c) 2021 Dan Halbert for Adafruit Industries LLC
2+ # SPDX-FileCopyrightText: 2021 James Carr
23#
34# SPDX-License-Identifier: MIT
45"""
89Math utility functions
910
1011
11- * Author(s): Adafruit Industries
12+ * Author(s): Dan Halbert, James Carr
1213
1314Implementation Notes
1415--------------------
@@ -27,12 +28,59 @@ def map_range(
2728 x : float , in_min : float , in_max : float , out_min : float , out_max : float
2829) -> float :
2930 """
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.
3537
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
3684 :param float in_min: Start value of input range.
3785 :param float in_max: End value of input range.
3886 :param float out_min: Start value of output range.
@@ -50,22 +98,26 @@ def map_range(
5098 mapped = 0.5
5199 mapped *= out_max - out_min
52100 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
56103
57104
58105def 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.
65114
115+ :param float x: Value to constrain
66116 :param float out_min: Lower bound of output range.
67117 :param float out_max: Upper bound of output range.
68118 :return: Returns value constrained to given range.
69119 :rtype: float
70120 """
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