Home | History | Annotate | Download | only in Imath
      1 ///////////////////////////////////////////////////////////////////////////
      2 //
      3 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
      4 // Digital Ltd. LLC
      5 //
      6 // All rights reserved.
      7 //
      8 // Redistribution and use in source and binary forms, with or without
      9 // modification, are permitted provided that the following conditions are
     10 // met:
     11 // *       Redistributions of source code must retain the above copyright
     12 // notice, this list of conditions and the following disclaimer.
     13 // *       Redistributions in binary form must reproduce the above
     14 // copyright notice, this list of conditions and the following disclaimer
     15 // in the documentation and/or other materials provided with the
     16 // distribution.
     17 // *       Neither the name of Industrial Light & Magic nor the names of
     18 // its contributors may be used to endorse or promote products derived
     19 // from this software without specific prior written permission.
     20 //
     21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32 //
     33 ///////////////////////////////////////////////////////////////////////////
     34 
     35 
     36 
     37 #ifndef INCLUDED_IMATHFUN_H
     38 #define INCLUDED_IMATHFUN_H
     39 
     40 //-----------------------------------------------------------------------------
     41 //
     42 //	Miscellaneous utility functions
     43 //
     44 //-----------------------------------------------------------------------------
     45 
     46 #include "ImathLimits.h"
     47 #include "ImathInt64.h"
     48 
     49 namespace Imath {
     50 
     51 template <class T>
     52 inline T
     53 abs (T a)
     54 {
     55     return (a > T(0)) ? a : -a;
     56 }
     57 
     58 
     59 template <class T>
     60 inline int
     61 sign (T a)
     62 {
     63     return (a > T(0))? 1 : ((a < T(0)) ? -1 : 0);
     64 }
     65 
     66 
     67 template <class T, class Q>
     68 inline T
     69 lerp (T a, T b, Q t)
     70 {
     71     return (T) (a * (1 - t) + b * t);
     72 }
     73 
     74 
     75 template <class T, class Q>
     76 inline T
     77 ulerp (T a, T b, Q t)
     78 {
     79     return (T) ((a > b)? (a - (a - b) * t): (a + (b - a) * t));
     80 }
     81 
     82 
     83 template <class T>
     84 inline T
     85 lerpfactor(T m, T a, T b)
     86 {
     87     //
     88     // Return how far m is between a and b, that is return t such that
     89     // if:
     90     //     t = lerpfactor(m, a, b);
     91     // then:
     92     //     m = lerp(a, b, t);
     93     //
     94     // If a==b, return 0.
     95     //
     96 
     97     T d = b - a;
     98     T n = m - a;
     99 
    100     if (abs(d) > T(1) || abs(n) < limits<T>::max() * abs(d))
    101     return n / d;
    102 
    103     return T(0);
    104 }
    105 
    106 
    107 template <class T>
    108 inline T
    109 clamp (T a, T l, T h)
    110 {
    111     return (a < l)? l : ((a > h)? h : a);
    112 }
    113 
    114 
    115 template <class T>
    116 inline int
    117 cmp (T a, T b)
    118 {
    119     return Imath::sign (a - b);
    120 }
    121 
    122 
    123 template <class T>
    124 inline int
    125 cmpt (T a, T b, T t)
    126 {
    127     return (Imath::abs (a - b) <= t)? 0 : cmp (a, b);
    128 }
    129 
    130 
    131 template <class T>
    132 inline bool
    133 iszero (T a, T t)
    134 {
    135     return (Imath::abs (a) <= t) ? 1 : 0;
    136 }
    137 
    138 
    139 template <class T1, class T2, class T3>
    140 inline bool
    141 equal (T1 a, T2 b, T3 t)
    142 {
    143     return Imath::abs (a - b) <= t;
    144 }
    145 
    146 template <class T>
    147 inline int
    148 floor (T x)
    149 {
    150     return (x >= 0)? int (x): -(int (-x) + (-x > int (-x)));
    151 }
    152 
    153 
    154 template <class T>
    155 inline int
    156 ceil (T x)
    157 {
    158     return -floor (-x);
    159 }
    160 
    161 template <class T>
    162 inline int
    163 trunc (T x)
    164 {
    165     return (x >= 0) ? int(x) : -int(-x);
    166 }
    167 
    168 
    169 //
    170 // Integer division and remainder where the
    171 // remainder of x/y has the same sign as x:
    172 //
    173 //	divs(x,y) == (abs(x) / abs(y)) * (sign(x) * sign(y))
    174 //	mods(x,y) == x - y * divs(x,y)
    175 //
    176 
    177 inline int
    178 divs (int x, int y)
    179 {
    180     return (x >= 0)? ((y >= 0)?  ( x / y): -( x / -y)):
    181              ((y >= 0)? -(-x / y):  (-x / -y));
    182 }
    183 
    184 
    185 inline int
    186 mods (int x, int y)
    187 {
    188     return (x >= 0)? ((y >= 0)?  ( x % y):  ( x % -y)):
    189              ((y >= 0)? -(-x % y): -(-x % -y));
    190 }
    191 
    192 
    193 //
    194 // Integer division and remainder where the
    195 // remainder of x/y is always positive:
    196 //
    197 //	divp(x,y) == floor (double(x) / double (y))
    198 //	modp(x,y) == x - y * divp(x,y)
    199 //
    200 
    201 inline int
    202 divp (int x, int y)
    203 {
    204     return (x >= 0)? ((y >= 0)?  (     x  / y): -(      x  / -y)):
    205              ((y >= 0)? -((y-1-x) / y):  ((-y-1-x) / -y));
    206 }
    207 
    208 
    209 inline int
    210 modp (int x, int y)
    211 {
    212     return x - y * divp (x, y);
    213 }
    214 
    215 //----------------------------------------------------------
    216 // Successor and predecessor for floating-point numbers:
    217 //
    218 // succf(f)     returns float(f+e), where e is the smallest
    219 //              positive number such that float(f+e) != f.
    220 //
    221 // predf(f)     returns float(f-e), where e is the smallest
    222 //              positive number such that float(f-e) != f.
    223 //
    224 // succd(d)     returns double(d+e), where e is the smallest
    225 //              positive number such that double(d+e) != d.
    226 //
    227 // predd(d)     returns double(d-e), where e is the smallest
    228 //              positive number such that double(d-e) != d.
    229 //
    230 // Exceptions:  If the input value is an infinity or a nan,
    231 //              succf(), predf(), succd(), and predd() all
    232 //              return the input value without changing it.
    233 //
    234 //----------------------------------------------------------
    235 
    236 float succf (float f);
    237 float predf (float f);
    238 
    239 double succd (double d);
    240 double predd (double d);
    241 
    242 //
    243 // Return true if the number is not a NaN or Infinity.
    244 //
    245 
    246 inline bool
    247 finitef (float f)
    248 {
    249     union {float f; int i;} u;
    250     u.f = f;
    251 
    252     return (u.i & 0x7f800000) != 0x7f800000;
    253 }
    254 
    255 inline bool
    256 finited (double d)
    257 {
    258     union {double d; Int64 i;} u;
    259     u.d = d;
    260 
    261     return (u.i & 0x7ff0000000000000LL) != 0x7ff0000000000000LL;
    262 }
    263 
    264 
    265 } // namespace Imath
    266 
    267 #endif
    268