ScummVM API documentation
angle.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef PHOENIXVR_ANGLE_H
23 #define PHOENIXVR_ANGLE_H
24 
25 #include "common/util.h"
26 #include "math/utils.h"
27 #include "phoenixvr/math.h"
28 
29 namespace Common {
30 class String;
31 }
32 
33 namespace PhoenixVR {
34 class Angle {
35 protected:
36  float _angle;
37  float _min;
38  float _max;
39 
40  float _rangeMin;
41  float _rangeMax;
42 
43 public:
44  Angle(float angle, float min, float max) : _min(min), _max(max) {
45  resetRange();
46  set(angle);
47  }
48 
49  Angle &operator=(float angle) {
50  set(angle);
51  return *this;
52  }
53 
54  float angle() const { return _angle; }
55 
56  static float mod(float v, float min, float max) {
57  auto range = max - min;
58  auto a = fmod(v - min, range);
59  if (a < 0)
60  a += range;
61  return a + min;
62  }
63 
64  float mod(float v) const {
65  return mod(v, _min, _max);
66  }
67 
68  void set(float v) {
69  _angle = mod(v, _min, _max);
70  auto range = _max - _min;
71  auto min = _rangeMin, max = _rangeMax;
72  if (_angle >= min && _angle <= max)
73  return;
74  if (_angle >= min - range && _angle <= max - range)
75  return;
76  if (_angle >= min + range && _angle <= max + range)
77  return;
78 
79  // out of bounds, find left or right
80  auto l0 = ABS(_angle - _rangeMin);
81  auto l1 = ABS(_angle - _rangeMin - range);
82  auto l = MIN(l0, l1);
83  auto r0 = ABS(_rangeMax - _angle);
84  auto r1 = ABS(range + _rangeMax - _angle);
85  auto r = MIN(r0, r1);
86  _angle = l < r ? _rangeMin : _rangeMax;
87  }
88 
89  void add(float v) {
90  set(_angle + v);
91  }
92 
93  float rangeMin() const {
94  return _rangeMin;
95  }
96 
97  float rangeMax() const {
98  return _rangeMax;
99  }
100 
101  void setRange(float min, float max) {
102  _rangeMin = min;
103  _rangeMax = max;
104  }
105 
106  void resetRange() {
107  setRange(-INFINITY, INFINITY);
108  }
109 };
110 struct AngleX : Angle {
111  AngleX(float angle) : Angle(angle, 0, kTau) {}
112 };
113 
114 struct AngleY : Angle {
115  AngleY(float angle) : Angle(angle, -kPi, -Math::epsilon) {}
116  void add(float v) {
117  v += angle();
118  if (v <= _min)
119  v = _min + Math::epsilon;
120  if (v >= _max)
121  v = _max - Math::epsilon;
122  set(v);
123  }
124 };
125 } // namespace PhoenixVR
126 
127 #endif
Definition: angle.h:34
Definition: angle.h:114
Definition: angle.h:110
Definition: angle.h:33
Definition: algorithm.h:29
T MIN(T a, T b)
Definition: util.h:61
T ABS(T x)
Definition: util.h:58