tests.h 2.91 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/* ALTA --- Analysis of Bidirectional Reflectance Distribution Functions

   Copyright (C) 2015 CNRS
   Copyright (C) 2015 Inria

   This file is part of ALTA.

   This Source Code Form is subject to the terms of the Mozilla Public
   License, v. 2.0.  If a copy of the MPL was not distributed with this
   file, You can obtain one at http://mozilla.org/MPL/2.0/.  */

/* Utilities for unit tests.  */

#pragma once

16 17 18
// Make sure 'assert' does its job in tests.
#undef NDEBUG

19 20
#include <iostream>
#include <cstdlib>
21 22
#include <cmath>

23
namespace alta { namespace tests
24
{
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39

#define STRINGIFY_(x) #x
#define STRINGIFY(x)  STRINGIFY_(x)

#define TEST_ASSERT(exp)                                          \
    do																														\
    {																															\
        std::cerr << "evaluating '" << STRINGIFY(exp) << "'... ";	\
        bool result = (exp);																			\
        std::cerr << (result ? "PASS" : "FAIL") << std::endl;			\
        if (!result)																							\
            abort();																							\
    }																															\
    while(0)

40 41 42 43 44
    template<typename T>
    static bool in_range(const T x, const T a, const T b)
    {
      return x >= a && x <= b;
    }
45

46 47 48 49 50 51
    template<typename T>
    static T degrees_to_radians(const T degrees)
    {
        static const T d2r = M_PI / 180.;
        return degrees * d2r;
    }
52

53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
    template<typename T>
    static Eigen::Matrix<T, 3, 1> spherical_to_cartesian(T theta, T phi)
    {
        Eigen::Matrix<T, 3, 1> v(cos(phi) * sin(theta),
                                 sin(phi) * sin(theta),
                                 cos(theta));
        // cart[3] = clamp(cos(phi) * sin(theta), 0., 1.);
        // cart[4] = clamp(sin(phi) * sin(theta), 0., 1.);
        // cart[5] = clamp(cos(theta), 0., 1.);

        // Make sure V is on the hemisphere.
        v.normalize();

        return v;
    }

69 70
    template<typename T>
    class angle_range
71 72
    {
    public:
73
        class angle_iterator
74
        {
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
        public:
            angle_iterator(const T start, const T step):
            _value(start), _step(step) { }

            bool operator!=(const angle_iterator& other) const
            {
                return _value != other._value;
            }

            T operator*() const
            {
                return degrees_to_radians(_value);
            }

            const angle_iterator& operator++()
            {
                _value += _step;
                return *this;
            }

        private:
            T _value;
            const T _step;
        };

        angle_range(T start, T end, T step)
            : _start(start), _end(end), _step(step)
        { }

        angle_iterator begin()
105
        {
106
            return angle_iterator(_start, _step);
107 108
        }

109
        angle_iterator end()
110
        {
111
            return angle_iterator(_end + _step, _step);
112 113 114
        }

    private:
115
        const T _start, _end, _step;
116
    };
117
}};