Code

Translations. POTFILES.in cleanup and inkscape.pot update.
[inkscape.git] / src / libnr / nr-types.cpp
1 /** \file
2  * Implements NR::Point::normalize()
3  */
5 #include <libnr/nr-types.h>
7 #include "2geom/isnan.h"
9 /** Scales this vector to make it a unit vector (within rounding error).
10  *
11  *  The current version tries to handle infinite coordinates gracefully,
12  *  but it's not clear that any callers need that.
13  *
14  *  \pre *this != Point(0, 0).
15  *  \pre Neither coordinate is NaN.
16  *  \post L2(*this) very near 1.0.
17  */
18 void NR::Point::normalize() {
19         double len = hypot(_pt[0], _pt[1]);
20         g_return_if_fail(len != 0);
21         g_return_if_fail(!IS_NAN(len));
22         static double const inf = 1e400;
23         if(len != inf) {
24                 *this /= len;
25         } else {
26                 unsigned n_inf_coords = 0;
27                 /* Delay updating pt in case neither coord is infinite. */
28                 NR::Point tmp;
29                 for ( unsigned i = 0 ; i < 2 ; ++i ) {
30                         if ( _pt[i] == inf ) {
31                                 ++n_inf_coords;
32                                 tmp[i] = 1.0;
33                         } else if ( _pt[i] == -inf ) {
34                                 ++n_inf_coords;
35                                 tmp[i] = -1.0;
36                         } else {
37                                 tmp[i] = 0.0;
38                         }
39                 }
40                 switch (n_inf_coords) {
41                 case 0:
42                         /* Can happen if both coords are near +/-DBL_MAX. */
43                         *this /= 4.0;
44                         len = hypot(_pt[0], _pt[1]);
45                         g_assert(len != inf);
46                         *this /= len;
47                         break;
49                 case 1:
50                         *this = tmp;
51                         break;
53                 case 2:
54                         *this = sqrt(0.5) * tmp;
55                         break;
56                 }
57         }
58 }
59 /*
60   Local Variables:
61   mode:c++
62   c-file-style:"stroustrup"
63   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
64   indent-tabs-mode:nil
65   fill-column:99
66   End:
67 */
68 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :