A Discrete-Event Network Simulator
API
test-angles.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011 CTTC
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Nicola Baldo <nbaldo@cttc.es>
18  */
19 
20 #include <ns3/antenna-model.h>
21 #include <ns3/log.h>
22 #include <ns3/test.h>
23 
24 #include <cmath>
25 #include <iostream>
26 #include <sstream>
27 #include <string>
28 
29 using namespace ns3;
30 
37 {
38  public:
44  static std::string BuildNameString(Vector v);
51 
52  private:
53  void DoRun() override;
54 
55  Vector m_v;
57 };
58 
59 std::string
61 {
62  std::ostringstream oss;
63  oss << " v = " << v;
64  return oss.str();
65 }
66 
68  : TestCase(BuildNameString(v)),
69  m_v(v),
70  m_a(a)
71 {
72 }
73 
74 void
76 {
77  Angles a(m_v);
78  NS_TEST_EXPECT_MSG_EQ_TOL(a.GetAzimuth(), m_a.GetAzimuth(), 1e-10, "incorrect phi");
79  NS_TEST_EXPECT_MSG_EQ_TOL(a.GetInclination(), m_a.GetInclination(), 1e-10, "incorrect theta");
80 }
81 
88 {
89  public:
96  static std::string BuildNameString(Vector v, Vector o);
103  TwoVectorsConstructorTestCase(Vector v, Vector o, Angles a);
104 
105  private:
106  void DoRun() override;
107 
108  Vector m_v;
109  Vector m_o;
111 };
112 
113 std::string
115 {
116  std::ostringstream oss;
117  oss << " v = " << v << ", o = " << o;
118  return oss.str();
119 }
120 
122  : TestCase(BuildNameString(v, o)),
123  m_v(v),
124  m_o(o),
125  m_a(a)
126 {
127 }
128 
129 void
131 {
132  Angles a(m_v, m_o);
133  NS_TEST_EXPECT_MSG_EQ_TOL(a.GetAzimuth(), m_a.GetAzimuth(), 1e-10, "incorrect phi");
134  NS_TEST_EXPECT_MSG_EQ_TOL(a.GetInclination(), m_a.GetInclination(), 1e-10, "incorrect theta");
135 }
136 
137 using WrapToRangeFunction = std::function<double(double)>;
138 
146 {
147  public:
154  static std::string BuildNameString(double lowerBound, double upperBound);
161  WrapToRangeTestCase(WrapToRangeFunction wrapper, double lowerBound, double upperBound);
162 
163  protected:
168  void CheckWrappingPoint(double wrapPoint);
169 
170  private:
171  void DoRun() override;
172 
174  double m_lowerBound;
175  double m_upperBound;
176 };
177 
178 std::string
179 WrapToRangeTestCase::BuildNameString(double lowerBound, double upperBound)
180 {
181  std::ostringstream oss;
182  oss << "WrapTo [" << lowerBound << ", " << upperBound << ")";
183  return oss.str();
184 }
185 
187  double lowerBound,
188  double upperBound)
189  : TestCase(BuildNameString(lowerBound, upperBound)),
190  m_wrapper(wrapper),
191  m_lowerBound(lowerBound),
192  m_upperBound(upperBound)
193 {
194 }
195 
196 void
198 {
201 }
202 
203 void
205 {
206  constexpr int STEP_NUM = 100;
207  double directions[] = {std::numeric_limits<double>::lowest(),
209  for (double dir : directions)
210  {
211  int i = 0;
212  for (double x = wrapPoint; i < STEP_NUM; x = std::nextafter(x, dir), ++i)
213  {
214  // If asserts are enabled, this test will crash with an assert instead of failing
215  double result = m_wrapper(x);
217  true,
218  "Invalid wrap (too low) " << x << " maps to " << result << " and "
219  << result - m_lowerBound);
221  true,
222  "Invalid wrap (too high) " << x << " maps to " << result
223  << " and " << result - m_lowerBound);
224  }
225  }
226 }
227 
234 {
235  public:
242  static std::string BuildNameString(double angle, double wrappedAngle);
249  WrapToRangeFunctionalTestCase(WrapToRangeFunction wrapper, double angle, double wrappedAngle);
250 
251  private:
252  void DoRun() override;
253 
255  double m_angle;
256  double m_wrappedAngle;
257 };
258 
259 std::string
260 WrapToRangeFunctionalTestCase::BuildNameString(double angle, double wrappedAngle)
261 {
262  std::ostringstream oss;
263  oss << "Wrap " << angle << " to " << wrappedAngle;
264  return oss.str();
265 }
266 
268  double angle,
269  double wrappedAngle)
270  : TestCase(BuildNameString(angle, wrappedAngle)),
271  m_wrapper(wrapper),
272  m_angle(angle),
273  m_wrappedAngle(wrappedAngle)
274 {
275 }
276 
277 void
279 {
282  1e-6,
283  "Invalid wrap " << m_angle << " wrapped to " << m_wrapper(m_angle)
284  << " instead of " << m_wrappedAngle);
285 }
286 
293 {
294  public:
295  AnglesTestSuite();
296 };
297 
299  : TestSuite("angles", UNIT)
300 {
301  AddTestCase(new OneVectorConstructorTestCase(Vector(1, 0, 0), Angles(0, M_PI_2)),
302  TestCase::QUICK);
303  AddTestCase(new OneVectorConstructorTestCase(Vector(-1, 0, 0), Angles(M_PI, M_PI_2)),
304  TestCase::QUICK);
305  AddTestCase(new OneVectorConstructorTestCase(Vector(0, 1, 0), Angles(M_PI_2, M_PI_2)),
306  TestCase::QUICK);
307  AddTestCase(new OneVectorConstructorTestCase(Vector(0, -1, 0), Angles(-M_PI_2, M_PI_2)),
308  TestCase::QUICK);
309  AddTestCase(new OneVectorConstructorTestCase(Vector(0, 0, 1), Angles(0, 0)), TestCase::QUICK);
310  AddTestCase(new OneVectorConstructorTestCase(Vector(0, 0, -1), Angles(0, M_PI)),
311  TestCase::QUICK);
312 
313  AddTestCase(new OneVectorConstructorTestCase(Vector(2, 0, 0), Angles(0, M_PI_2)),
314  TestCase::QUICK);
315  AddTestCase(new OneVectorConstructorTestCase(Vector(-2, 0, 0), Angles(M_PI, M_PI_2)),
316  TestCase::QUICK);
317  AddTestCase(new OneVectorConstructorTestCase(Vector(0, 2, 0), Angles(M_PI_2, M_PI_2)),
318  TestCase::QUICK);
319  AddTestCase(new OneVectorConstructorTestCase(Vector(0, -2, 0), Angles(-M_PI_2, M_PI_2)),
320  TestCase::QUICK);
321  AddTestCase(new OneVectorConstructorTestCase(Vector(0, 0, 2), Angles(0, 0)), TestCase::QUICK);
322  AddTestCase(new OneVectorConstructorTestCase(Vector(0, 0, -2), Angles(0, M_PI)),
323  TestCase::QUICK);
324 
325  AddTestCase(new OneVectorConstructorTestCase(Vector(1, 0, 1), Angles(0, M_PI_4)),
326  TestCase::QUICK);
327  AddTestCase(new OneVectorConstructorTestCase(Vector(1, 0, -1), Angles(0, 3 * M_PI_4)),
328  TestCase::QUICK);
329  AddTestCase(new OneVectorConstructorTestCase(Vector(1, 1, 0), Angles(M_PI_4, M_PI_2)),
330  TestCase::QUICK);
331  AddTestCase(new OneVectorConstructorTestCase(Vector(1, -1, 0), Angles(-M_PI_4, M_PI_2)),
332  TestCase::QUICK);
333  AddTestCase(new OneVectorConstructorTestCase(Vector(-1, 0, 1), Angles(M_PI, M_PI_4)),
334  TestCase::QUICK);
335  AddTestCase(new OneVectorConstructorTestCase(Vector(-1, 0, -1), Angles(M_PI, 3 * M_PI_4)),
336  TestCase::QUICK);
337  AddTestCase(new OneVectorConstructorTestCase(Vector(-1, 1, 0), Angles(3 * M_PI_4, M_PI_2)),
338  TestCase::QUICK);
339  AddTestCase(new OneVectorConstructorTestCase(Vector(-1, -1, 0), Angles(-3 * M_PI_4, M_PI_2)),
340  TestCase::QUICK);
341  AddTestCase(new OneVectorConstructorTestCase(Vector(0, 1, 1), Angles(M_PI_2, M_PI_4)),
342  TestCase::QUICK);
343  AddTestCase(new OneVectorConstructorTestCase(Vector(0, 1, -1), Angles(M_PI_2, 3 * M_PI_4)),
344  TestCase::QUICK);
345  AddTestCase(new OneVectorConstructorTestCase(Vector(0, -1, 1), Angles(-M_PI_2, M_PI_4)),
346  TestCase::QUICK);
347  AddTestCase(new OneVectorConstructorTestCase(Vector(0, -1, -1), Angles(-M_PI_2, 3 * M_PI_4)),
348  TestCase::QUICK);
349 
350  AddTestCase(
351  new OneVectorConstructorTestCase(Vector(1, 1, std::sqrt(2)), Angles(M_PI_4, M_PI_4)),
352  TestCase::QUICK);
353  AddTestCase(
354  new OneVectorConstructorTestCase(Vector(1, 1, -std::sqrt(2)), Angles(M_PI_4, 3 * M_PI_4)),
355  TestCase::QUICK);
356  AddTestCase(
357  new OneVectorConstructorTestCase(Vector(1, -1, std::sqrt(2)), Angles(-M_PI_4, M_PI_4)),
358  TestCase::QUICK);
359  AddTestCase(
360  new OneVectorConstructorTestCase(Vector(-1, 1, std::sqrt(2)), Angles(3 * M_PI_4, M_PI_4)),
361  TestCase::QUICK);
362 
363  AddTestCase(
364  new TwoVectorsConstructorTestCase(Vector(1, 0, 0), Vector(0, 0, 0), Angles(0, M_PI_2)),
365  TestCase::QUICK);
366  AddTestCase(
367  new TwoVectorsConstructorTestCase(Vector(-1, 0, 0), Vector(0, 0, 0), Angles(M_PI, M_PI_2)),
368  TestCase::QUICK);
369  AddTestCase(
370  new TwoVectorsConstructorTestCase(Vector(0, 1, 0), Vector(0, 0, 0), Angles(M_PI_2, M_PI_2)),
371  TestCase::QUICK);
372  AddTestCase(new TwoVectorsConstructorTestCase(Vector(0, -1, 0),
373  Vector(0, 0, 0),
374  Angles(-M_PI_2, M_PI_2)),
375  TestCase::QUICK);
376  AddTestCase(new TwoVectorsConstructorTestCase(Vector(0, 0, 1), Vector(0, 0, 0), Angles(0, 0)),
377  TestCase::QUICK);
378  AddTestCase(
379  new TwoVectorsConstructorTestCase(Vector(0, 0, -1), Vector(0, 0, 0), Angles(0, M_PI)),
380  TestCase::QUICK);
381 
382  AddTestCase(
383  new TwoVectorsConstructorTestCase(Vector(2, 0, 0), Vector(0, 0, 0), Angles(0, M_PI_2)),
384  TestCase::QUICK);
385  AddTestCase(
386  new TwoVectorsConstructorTestCase(Vector(-2, 0, 0), Vector(0, 0, 0), Angles(M_PI, M_PI_2)),
387  TestCase::QUICK);
388  AddTestCase(
389  new TwoVectorsConstructorTestCase(Vector(0, 2, 0), Vector(0, 0, 0), Angles(M_PI_2, M_PI_2)),
390  TestCase::QUICK);
391  AddTestCase(new TwoVectorsConstructorTestCase(Vector(0, -2, 0),
392  Vector(0, 0, 0),
393  Angles(-M_PI_2, M_PI_2)),
394  TestCase::QUICK);
395  AddTestCase(new TwoVectorsConstructorTestCase(Vector(0, 0, 2), Vector(0, 0, 0), Angles(0, 0)),
396  TestCase::QUICK);
397  AddTestCase(
398  new TwoVectorsConstructorTestCase(Vector(0, 0, -2), Vector(0, 0, 0), Angles(0, M_PI)),
399  TestCase::QUICK);
400 
401  AddTestCase(
402  new TwoVectorsConstructorTestCase(Vector(1, 0, 1), Vector(0, 0, 0), Angles(0, M_PI_4)),
403  TestCase::QUICK);
404  AddTestCase(
405  new TwoVectorsConstructorTestCase(Vector(1, 0, -1), Vector(0, 0, 0), Angles(0, 3 * M_PI_4)),
406  TestCase::QUICK);
407  AddTestCase(
408  new TwoVectorsConstructorTestCase(Vector(1, 1, 0), Vector(0, 0, 0), Angles(M_PI_4, M_PI_2)),
409  TestCase::QUICK);
410  AddTestCase(new TwoVectorsConstructorTestCase(Vector(1, -1, 0),
411  Vector(0, 0, 0),
412  Angles(-M_PI_4, M_PI_2)),
413  TestCase::QUICK);
414  AddTestCase(
415  new TwoVectorsConstructorTestCase(Vector(-1, 0, 1), Vector(0, 0, 0), Angles(M_PI, M_PI_4)),
416  TestCase::QUICK);
417  AddTestCase(new TwoVectorsConstructorTestCase(Vector(-1, 0, -1),
418  Vector(0, 0, 0),
419  Angles(M_PI, 3 * M_PI_4)),
420  TestCase::QUICK);
421  AddTestCase(new TwoVectorsConstructorTestCase(Vector(-1, 1, 0),
422  Vector(0, 0, 0),
423  Angles(3 * M_PI_4, M_PI_2)),
424  TestCase::QUICK);
425  AddTestCase(new TwoVectorsConstructorTestCase(Vector(-1, -1, 0),
426  Vector(0, 0, 0),
427  Angles(-3 * M_PI_4, M_PI_2)),
428  TestCase::QUICK);
429  AddTestCase(
430  new TwoVectorsConstructorTestCase(Vector(0, 1, 1), Vector(0, 0, 0), Angles(M_PI_2, M_PI_4)),
431  TestCase::QUICK);
432  AddTestCase(new TwoVectorsConstructorTestCase(Vector(0, 1, -1),
433  Vector(0, 0, 0),
434  Angles(M_PI_2, 3 * M_PI_4)),
435  TestCase::QUICK);
436  AddTestCase(new TwoVectorsConstructorTestCase(Vector(0, -1, 1),
437  Vector(0, 0, 0),
438  Angles(-M_PI_2, M_PI_4)),
439  TestCase::QUICK);
440  AddTestCase(new TwoVectorsConstructorTestCase(Vector(0, -1, -1),
441  Vector(0, 0, 0),
442  Angles(-M_PI_2, 3 * M_PI_4)),
443  TestCase::QUICK);
444 
445  AddTestCase(new TwoVectorsConstructorTestCase(Vector(1, 1, std::sqrt(2)),
446  Vector(0, 0, 0),
447  Angles(M_PI_4, M_PI_4)),
448  TestCase::QUICK);
449  AddTestCase(new TwoVectorsConstructorTestCase(Vector(1, 1, -std::sqrt(2)),
450  Vector(0, 0, 0),
451  Angles(M_PI_4, 3 * M_PI_4)),
452  TestCase::QUICK);
453  AddTestCase(new TwoVectorsConstructorTestCase(Vector(1, -1, std::sqrt(2)),
454  Vector(0, 0, 0),
455  Angles(-M_PI_4, M_PI_4)),
456  TestCase::QUICK);
457  AddTestCase(new TwoVectorsConstructorTestCase(Vector(-1, 1, std::sqrt(2)),
458  Vector(0, 0, 0),
459  Angles(3 * M_PI_4, M_PI_4)),
460  TestCase::QUICK);
461 
462  AddTestCase(
463  new TwoVectorsConstructorTestCase(Vector(3, 2, 2), Vector(2, 2, 2), Angles(0, M_PI_2)),
464  TestCase::QUICK);
465  AddTestCase(
466  new TwoVectorsConstructorTestCase(Vector(1, 2, 2), Vector(2, 2, 2), Angles(M_PI, M_PI_2)),
467  TestCase::QUICK);
468  AddTestCase(
469  new TwoVectorsConstructorTestCase(Vector(2, 3, 2), Vector(2, 2, 2), Angles(M_PI_2, M_PI_2)),
470  TestCase::QUICK);
471  AddTestCase(new TwoVectorsConstructorTestCase(Vector(-1, 2, 2),
472  Vector(-1, 3, 2),
473  Angles(-M_PI_2, M_PI_2)),
474  TestCase::QUICK);
475  AddTestCase(new TwoVectorsConstructorTestCase(Vector(4, -2, 7), Vector(4, -2, 6), Angles(0, 0)),
476  TestCase::QUICK);
477  AddTestCase(
478  new TwoVectorsConstructorTestCase(Vector(0, -5, -1), Vector(0, -5, 0), Angles(0, M_PI)),
479  TestCase::QUICK);
480 
481  AddTestCase(
482  new TwoVectorsConstructorTestCase(Vector(-2, 2, -1), Vector(-4, 2, -1), Angles(0, M_PI_2)),
483  TestCase::QUICK);
484  AddTestCase(
485  new TwoVectorsConstructorTestCase(Vector(2, 2, 0), Vector(4, 2, 0), Angles(M_PI, M_PI_2)),
486  TestCase::QUICK);
487 
488  AddTestCase(
489  new TwoVectorsConstructorTestCase(Vector(-1, 4, 4), Vector(-2, 4, 3), Angles(0, M_PI_4)),
490  TestCase::QUICK);
491  AddTestCase(new TwoVectorsConstructorTestCase(Vector(0, -2, -6),
492  Vector(-1, -2, -5),
493  Angles(0, 3 * M_PI_4)),
494  TestCase::QUICK);
495  AddTestCase(new TwoVectorsConstructorTestCase(Vector(77, 3, 43),
496  Vector(78, 2, 43),
497  Angles(3 * M_PI_4, M_PI_2)),
498  TestCase::QUICK);
499 
500  AddTestCase(new TwoVectorsConstructorTestCase(Vector(24, -2, -6 - std::sqrt(2)),
501  Vector(23, -3, -6),
502  Angles(M_PI_4, 3 * M_PI_4)),
503  TestCase::QUICK);
504  AddTestCase(new TwoVectorsConstructorTestCase(Vector(0.5, 11.45, std::sqrt(2) - 1),
505  Vector(-0.5, 12.45, -1),
506  Angles(-M_PI_4, M_PI_4)),
507  TestCase::QUICK);
508  AddTestCase(new WrapToRangeTestCase(WrapTo180, -180, 180), TestCase::QUICK);
509  AddTestCase(new WrapToRangeTestCase(WrapToPi, -M_PI, M_PI), TestCase::QUICK);
510  AddTestCase(new WrapToRangeTestCase(WrapTo360, 0, 360), TestCase::QUICK);
511  AddTestCase(new WrapToRangeTestCase(WrapTo2Pi, 0, 2 * M_PI), TestCase::QUICK);
512  AddTestCase(new WrapToRangeFunctionalTestCase(WrapTo180, -182.2, 177.8), TestCase::QUICK);
513  AddTestCase(new WrapToRangeFunctionalTestCase(WrapTo180, -179, -179), TestCase::QUICK);
514  AddTestCase(new WrapToRangeFunctionalTestCase(WrapTo180, 181, -179), TestCase::QUICK);
515  AddTestCase(new WrapToRangeFunctionalTestCase(WrapTo180, 360.6, 0.6), TestCase::QUICK);
516  AddTestCase(new WrapToRangeFunctionalTestCase(WrapTo360, -182.8, 177.2), TestCase::QUICK);
517  AddTestCase(new WrapToRangeFunctionalTestCase(WrapTo360, -179, 181), TestCase::QUICK);
518  AddTestCase(new WrapToRangeFunctionalTestCase(WrapTo360, 181, 181), TestCase::QUICK);
519  AddTestCase(new WrapToRangeFunctionalTestCase(WrapTo360, 360.2, 0.2), TestCase::QUICK);
520 }
521 
#define max(a, b)
Definition: 80211b.c:42
Angles TestSuite.
Definition: test-angles.cc:293
Angles Test using one vector for initialization.
Definition: test-angles.cc:37
void DoRun() override
Implementation to actually run this TestCase.
Definition: test-angles.cc:75
OneVectorConstructorTestCase(Vector v, Angles a)
Constructor.
Definition: test-angles.cc:67
Angles m_a
expected angle
Definition: test-angles.cc:56
static std::string BuildNameString(Vector v)
Build the test name.
Definition: test-angles.cc:60
Angles Test using two vectors for initialization.
Definition: test-angles.cc:88
TwoVectorsConstructorTestCase(Vector v, Vector o, Angles a)
Constructor.
Definition: test-angles.cc:121
void DoRun() override
Implementation to actually run this TestCase.
Definition: test-angles.cc:130
Angles m_a
expected angle
Definition: test-angles.cc:110
static std::string BuildNameString(Vector v, Vector o)
Build the test name.
Definition: test-angles.cc:114
Test the output for WrapToRangeFunction.
Definition: test-angles.cc:234
WrapToRangeFunctionalTestCase(WrapToRangeFunction wrapper, double angle, double wrappedAngle)
Constructor.
Definition: test-angles.cc:267
double m_angle
the input angle
Definition: test-angles.cc:255
double m_wrappedAngle
the expected wrapper angle
Definition: test-angles.cc:256
static std::string BuildNameString(double angle, double wrappedAngle)
Build the test name.
Definition: test-angles.cc:260
void DoRun() override
Implementation to actually run this TestCase.
Definition: test-angles.cc:278
WrapToRangeFunction m_wrapper
the wrapper function
Definition: test-angles.cc:254
Test bounds for various WrapTo...
Definition: test-angles.cc:146
void CheckWrappingPoint(double wrapPoint)
The given wrapper shall wrap an angle into the expected range.
Definition: test-angles.cc:204
double m_lowerBound
the corresponding lower bound
Definition: test-angles.cc:174
WrapToRangeFunction m_wrapper
the wrapper function
Definition: test-angles.cc:173
WrapToRangeTestCase(WrapToRangeFunction wrapper, double lowerBound, double upperBound)
Constructor.
Definition: test-angles.cc:186
void DoRun() override
Implementation to actually run this TestCase.
Definition: test-angles.cc:197
static std::string BuildNameString(double lowerBound, double upperBound)
Build the test name.
Definition: test-angles.cc:179
double m_upperBound
the corresponding upper bound
Definition: test-angles.cc:175
Class holding the azimuth and inclination angles of spherical coordinates.
Definition: angles.h:118
double GetInclination() const
Getter for inclination angle.
Definition: angles.cc:246
double GetAzimuth() const
Getter for azimuth angle.
Definition: angles.cc:240
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1256
Vector3D Vector
Vector alias typedef for compatibility with mobility models.
Definition: vector.h:324
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition: test.h:251
#define NS_TEST_EXPECT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report if ...
Definition: test.h:510
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double WrapToPi(double a)
Wrap angle in [-M_PI, M_PI)
Definition: angles.cc:138
double WrapTo180(double a)
Wrap angle in [-180, 180)
Definition: angles.cc:96
double WrapTo360(double a)
Wrap angle in [0, 360)
Definition: angles.cc:75
double WrapTo2Pi(double a)
Wrap angle in [0, 2*M_PI)
Definition: angles.cc:117
std::string dir
static AnglesTestSuite g_staticAnglesTestSuiteInstance
Static variable for test initialization.
Definition: test-angles.cc:523
std::function< double(double)> WrapToRangeFunction
Definition: test-angles.cc:137