xref: /aoo41x/main/basegfx/source/numeric/ftools.cxx (revision 2a27d9ca)
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
1009dbbe93SAndrew Rist  *
1109dbbe93SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
1209dbbe93SAndrew Rist  *
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.
1909dbbe93SAndrew Rist  *
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 
snapToNearestMultiple(double v,const double fStep)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 
snapToZeroRange(double v,double fWidth)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 
snapToRange(double v,double fLow,double fHigh)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