xref: /trunk/main/basegfx/source/numeric/ftools.cxx (revision 45d1b581a3afed2711c07fe77472516d35fbd7b3)
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 
22cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
23cdf0e10cSrcweir #include "precompiled_basegfx.hxx"
24cdf0e10cSrcweir #include <basegfx/numeric/ftools.hxx>
252a27d9caSArmin Le Grand #include <algorithm>
26cdf0e10cSrcweir 
27cdf0e10cSrcweir namespace basegfx
28cdf0e10cSrcweir {
29cdf0e10cSrcweir     // init static member of class fTools
30cdf0e10cSrcweir     double ::basegfx::fTools::mfSmallValue = 0.000000001;
312a27d9caSArmin Le Grand 
snapToNearestMultiple(double v,const double fStep)322a27d9caSArmin Le Grand     double snapToNearestMultiple(double v, const double fStep)
332a27d9caSArmin Le Grand     {
342a27d9caSArmin Le Grand         if(fTools::equalZero(fStep))
352a27d9caSArmin Le Grand         {
362a27d9caSArmin Le Grand             // with a zero step, all snaps to 0.0
372a27d9caSArmin Le Grand             return 0.0;
382a27d9caSArmin Le Grand         }
392a27d9caSArmin Le Grand         else
402a27d9caSArmin Le Grand         {
412a27d9caSArmin Le Grand             const double fHalfStep(fStep * 0.5);
422a27d9caSArmin Le Grand             const double fChange(fHalfStep - fmod(v + fHalfStep, fStep));
432a27d9caSArmin Le Grand 
442a27d9caSArmin Le Grand             if(basegfx::fTools::equal(fabs(v), fabs(fChange)))
452a27d9caSArmin Le Grand             {
462a27d9caSArmin Le Grand                 return 0.0;
472a27d9caSArmin Le Grand             }
482a27d9caSArmin Le Grand             else
492a27d9caSArmin Le Grand             {
502a27d9caSArmin Le Grand                 return v + fChange;
512a27d9caSArmin Le Grand             }
522a27d9caSArmin Le Grand         }
532a27d9caSArmin Le Grand     }
542a27d9caSArmin Le Grand 
snapToZeroRange(double v,double fWidth)552a27d9caSArmin Le Grand     double snapToZeroRange(double v, double fWidth)
562a27d9caSArmin Le Grand     {
572a27d9caSArmin Le Grand         if(fTools::equalZero(fWidth))
582a27d9caSArmin Le Grand         {
592a27d9caSArmin Le Grand             // with no range all snaps to range bound
602a27d9caSArmin Le Grand             return 0.0;
612a27d9caSArmin Le Grand         }
622a27d9caSArmin Le Grand         else
632a27d9caSArmin Le Grand         {
642a27d9caSArmin Le Grand             if(v < 0.0 || v > fWidth)
652a27d9caSArmin Le Grand             {
662a27d9caSArmin Le Grand                 double fRetval(fmod(v, fWidth));
672a27d9caSArmin Le Grand 
682a27d9caSArmin Le Grand                 if(fRetval < 0.0)
692a27d9caSArmin Le Grand                 {
702a27d9caSArmin Le Grand                     fRetval += fWidth;
712a27d9caSArmin Le Grand                 }
722a27d9caSArmin Le Grand 
732a27d9caSArmin Le Grand                 return fRetval;
742a27d9caSArmin Le Grand             }
752a27d9caSArmin Le Grand             else
762a27d9caSArmin Le Grand             {
772a27d9caSArmin Le Grand                 return v;
782a27d9caSArmin Le Grand             }
792a27d9caSArmin Le Grand         }
802a27d9caSArmin Le Grand     }
812a27d9caSArmin Le Grand 
snapToRange(double v,double fLow,double fHigh)822a27d9caSArmin Le Grand     double snapToRange(double v, double fLow, double fHigh)
832a27d9caSArmin Le Grand     {
842a27d9caSArmin Le Grand         if(fTools::equal(fLow, fHigh))
852a27d9caSArmin Le Grand         {
862a27d9caSArmin Le Grand             // with no range all snaps to range bound
872a27d9caSArmin Le Grand             return 0.0;
882a27d9caSArmin Le Grand         }
892a27d9caSArmin Le Grand         else
902a27d9caSArmin Le Grand         {
912a27d9caSArmin Le Grand             if(fLow > fHigh)
922a27d9caSArmin Le Grand             {
932a27d9caSArmin Le Grand                 // correct range order. Evtl. assert this (?)
942a27d9caSArmin Le Grand                 std::swap(fLow, fHigh);
952a27d9caSArmin Le Grand             }
962a27d9caSArmin Le Grand 
972a27d9caSArmin Le Grand             if(v < fLow || v > fHigh)
982a27d9caSArmin Le Grand             {
992a27d9caSArmin Le Grand                 return snapToZeroRange(v - fLow, fHigh - fLow) + fLow;
1002a27d9caSArmin Le Grand             }
1012a27d9caSArmin Le Grand             else
1022a27d9caSArmin Le Grand             {
1032a27d9caSArmin Le Grand                 return v;
1042a27d9caSArmin Le Grand             }
1052a27d9caSArmin Le Grand         }
1062a27d9caSArmin Le Grand     }
107cdf0e10cSrcweir } // end of namespace basegfx
108cdf0e10cSrcweir 
109*45d1b581Smseidel /* vim: set noet sw=4 ts=4: */
110