xref: /trunk/main/basegfx/source/numeric/ftools.cxx (revision 2a27d9ca92002687c22a80f87b4827f1c65aad4c)
109dbbe93SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
309dbbe93SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
409dbbe93SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
509dbbe93SAndrew Rist  * distributed with this work for additional information
609dbbe93SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
709dbbe93SAndrew Rist  * to you under the Apache License, Version 2.0 (the
809dbbe93SAndrew Rist  * "License"); you may not use this file except in compliance
909dbbe93SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
1109dbbe93SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
1309dbbe93SAndrew Rist  * Unless required by applicable law or agreed to in writing,
1409dbbe93SAndrew Rist  * software distributed under the License is distributed on an
1509dbbe93SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1609dbbe93SAndrew Rist  * KIND, either express or implied.  See the License for the
1709dbbe93SAndrew Rist  * specific language governing permissions and limitations
1809dbbe93SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
2009dbbe93SAndrew Rist  *************************************************************/
2109dbbe93SAndrew Rist 
2209dbbe93SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_basegfx.hxx"
26cdf0e10cSrcweir #include <basegfx/numeric/ftools.hxx>
27*2a27d9caSArmin Le Grand #include <algorithm>
28cdf0e10cSrcweir 
29cdf0e10cSrcweir namespace basegfx
30cdf0e10cSrcweir {
31cdf0e10cSrcweir     // init static member of class fTools
32cdf0e10cSrcweir     double ::basegfx::fTools::mfSmallValue = 0.000000001;
33*2a27d9caSArmin Le Grand 
34*2a27d9caSArmin Le Grand     double snapToNearestMultiple(double v, const double fStep)
35*2a27d9caSArmin Le Grand     {
36*2a27d9caSArmin Le Grand         if(fTools::equalZero(fStep))
37*2a27d9caSArmin Le Grand         {
38*2a27d9caSArmin Le Grand             // with a zero step, all snaps to 0.0
39*2a27d9caSArmin Le Grand             return 0.0;
40*2a27d9caSArmin Le Grand         }
41*2a27d9caSArmin Le Grand         else
42*2a27d9caSArmin Le Grand         {
43*2a27d9caSArmin Le Grand             const double fHalfStep(fStep * 0.5);
44*2a27d9caSArmin Le Grand             const double fChange(fHalfStep - fmod(v + fHalfStep, fStep));
45*2a27d9caSArmin Le Grand 
46*2a27d9caSArmin Le Grand             if(basegfx::fTools::equal(fabs(v), fabs(fChange)))
47*2a27d9caSArmin Le Grand             {
48*2a27d9caSArmin Le Grand                 return 0.0;
49*2a27d9caSArmin Le Grand             }
50*2a27d9caSArmin Le Grand             else
51*2a27d9caSArmin Le Grand             {
52*2a27d9caSArmin Le Grand                 return v + fChange;
53*2a27d9caSArmin Le Grand             }
54*2a27d9caSArmin Le Grand         }
55*2a27d9caSArmin Le Grand     }
56*2a27d9caSArmin Le Grand 
57*2a27d9caSArmin Le Grand     double snapToZeroRange(double v, double fWidth)
58*2a27d9caSArmin Le Grand     {
59*2a27d9caSArmin Le Grand         if(fTools::equalZero(fWidth))
60*2a27d9caSArmin Le Grand         {
61*2a27d9caSArmin Le Grand             // with no range all snaps to range bound
62*2a27d9caSArmin Le Grand             return 0.0;
63*2a27d9caSArmin Le Grand         }
64*2a27d9caSArmin Le Grand         else
65*2a27d9caSArmin Le Grand         {
66*2a27d9caSArmin Le Grand             if(v < 0.0 || v > fWidth)
67*2a27d9caSArmin Le Grand             {
68*2a27d9caSArmin Le Grand                 double fRetval(fmod(v, fWidth));
69*2a27d9caSArmin Le Grand 
70*2a27d9caSArmin Le Grand                 if(fRetval < 0.0)
71*2a27d9caSArmin Le Grand                 {
72*2a27d9caSArmin Le Grand                     fRetval += fWidth;
73*2a27d9caSArmin Le Grand                 }
74*2a27d9caSArmin Le Grand 
75*2a27d9caSArmin Le Grand                 return fRetval;
76*2a27d9caSArmin Le Grand             }
77*2a27d9caSArmin Le Grand             else
78*2a27d9caSArmin Le Grand             {
79*2a27d9caSArmin Le Grand                 return v;
80*2a27d9caSArmin Le Grand             }
81*2a27d9caSArmin Le Grand         }
82*2a27d9caSArmin Le Grand     }
83*2a27d9caSArmin Le Grand 
84*2a27d9caSArmin Le Grand     double snapToRange(double v, double fLow, double fHigh)
85*2a27d9caSArmin Le Grand     {
86*2a27d9caSArmin Le Grand         if(fTools::equal(fLow, fHigh))
87*2a27d9caSArmin Le Grand         {
88*2a27d9caSArmin Le Grand             // with no range all snaps to range bound
89*2a27d9caSArmin Le Grand             return 0.0;
90*2a27d9caSArmin Le Grand         }
91*2a27d9caSArmin Le Grand         else
92*2a27d9caSArmin Le Grand         {
93*2a27d9caSArmin Le Grand             if(fLow > fHigh)
94*2a27d9caSArmin Le Grand             {
95*2a27d9caSArmin Le Grand                 // correct range order. Evtl. assert this (?)
96*2a27d9caSArmin Le Grand                 std::swap(fLow, fHigh);
97*2a27d9caSArmin Le Grand             }
98*2a27d9caSArmin Le Grand 
99*2a27d9caSArmin Le Grand             if(v < fLow || v > fHigh)
100*2a27d9caSArmin Le Grand             {
101*2a27d9caSArmin Le Grand                 return snapToZeroRange(v - fLow, fHigh - fLow) + fLow;
102*2a27d9caSArmin Le Grand             }
103*2a27d9caSArmin Le Grand             else
104*2a27d9caSArmin Le Grand             {
105*2a27d9caSArmin Le Grand                 return v;
106*2a27d9caSArmin Le Grand             }
107*2a27d9caSArmin Le Grand         }
108*2a27d9caSArmin Le Grand     }
109cdf0e10cSrcweir } // end of namespace basegfx
110cdf0e10cSrcweir 
111cdf0e10cSrcweir // eof
112