xref: /aoo42x/main/basegfx/source/numeric/ftools.cxx (revision b056bc42)
109dbbe93SAndrew Rist /**************************************************************
2*b056bc42Smseidel  *
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
10*b056bc42Smseidel  *
1109dbbe93SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*b056bc42Smseidel  *
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.
19*b056bc42Smseidel  *
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>
272a27d9caSArmin Le Grand #include <algorithm>
28cdf0e10cSrcweir 
29cdf0e10cSrcweir namespace basegfx
30cdf0e10cSrcweir {
31cdf0e10cSrcweir 	// init static member of class fTools
32cdf0e10cSrcweir 	double ::basegfx::fTools::mfSmallValue = 0.000000001;
332a27d9caSArmin Le Grand 
snapToNearestMultiple(double v,const double fStep)342a27d9caSArmin Le Grand 	double snapToNearestMultiple(double v, const double fStep)
352a27d9caSArmin Le Grand 	{
362a27d9caSArmin Le Grand 		if(fTools::equalZero(fStep))
372a27d9caSArmin Le Grand 		{
382a27d9caSArmin Le Grand 			// with a zero step, all snaps to 0.0
392a27d9caSArmin Le Grand 			return 0.0;
402a27d9caSArmin Le Grand 		}
412a27d9caSArmin Le Grand 		else
422a27d9caSArmin Le Grand 		{
432a27d9caSArmin Le Grand 			const double fHalfStep(fStep * 0.5);
442a27d9caSArmin Le Grand 			const double fChange(fHalfStep - fmod(v + fHalfStep, fStep));
452a27d9caSArmin Le Grand 
46*b056bc42Smseidel 			if(basegfx::fTools::equal(fabs(v), fabs(fChange)))
47*b056bc42Smseidel 			{
48*b056bc42Smseidel 				return 0.0;
49*b056bc42Smseidel 			}
50*b056bc42Smseidel 			else
51*b056bc42Smseidel 			{
52*b056bc42Smseidel 				return v + fChange;
53*b056bc42Smseidel 			}
542a27d9caSArmin Le Grand 		}
552a27d9caSArmin Le Grand 	}
562a27d9caSArmin Le Grand 
snapToZeroRange(double v,double fWidth)572a27d9caSArmin Le Grand 	double snapToZeroRange(double v, double fWidth)
582a27d9caSArmin Le Grand 	{
592a27d9caSArmin Le Grand 		if(fTools::equalZero(fWidth))
602a27d9caSArmin Le Grand 		{
612a27d9caSArmin Le Grand 			// with no range all snaps to range bound
622a27d9caSArmin Le Grand 			return 0.0;
632a27d9caSArmin Le Grand 		}
642a27d9caSArmin Le Grand 		else
652a27d9caSArmin Le Grand 		{
662a27d9caSArmin Le Grand 			if(v < 0.0 || v > fWidth)
672a27d9caSArmin Le Grand 			{
682a27d9caSArmin Le Grand 				double fRetval(fmod(v, fWidth));
692a27d9caSArmin Le Grand 
702a27d9caSArmin Le Grand 				if(fRetval < 0.0)
712a27d9caSArmin Le Grand 				{
722a27d9caSArmin Le Grand 					fRetval += fWidth;
732a27d9caSArmin Le Grand 				}
742a27d9caSArmin Le Grand 
752a27d9caSArmin Le Grand 				return fRetval;
762a27d9caSArmin Le Grand 			}
772a27d9caSArmin Le Grand 			else
782a27d9caSArmin Le Grand 			{
792a27d9caSArmin Le Grand 				return v;
802a27d9caSArmin Le Grand 			}
812a27d9caSArmin Le Grand 		}
822a27d9caSArmin Le Grand 	}
832a27d9caSArmin Le Grand 
snapToRange(double v,double fLow,double fHigh)842a27d9caSArmin Le Grand 	double snapToRange(double v, double fLow, double fHigh)
852a27d9caSArmin Le Grand 	{
862a27d9caSArmin Le Grand 		if(fTools::equal(fLow, fHigh))
872a27d9caSArmin Le Grand 		{
882a27d9caSArmin Le Grand 			// with no range all snaps to range bound
892a27d9caSArmin Le Grand 			return 0.0;
902a27d9caSArmin Le Grand 		}
912a27d9caSArmin Le Grand 		else
922a27d9caSArmin Le Grand 		{
932a27d9caSArmin Le Grand 			if(fLow > fHigh)
942a27d9caSArmin Le Grand 			{
952a27d9caSArmin Le Grand 				// correct range order. Evtl. assert this (?)
962a27d9caSArmin Le Grand 				std::swap(fLow, fHigh);
972a27d9caSArmin Le Grand 			}
982a27d9caSArmin Le Grand 
992a27d9caSArmin Le Grand 			if(v < fLow || v > fHigh)
1002a27d9caSArmin Le Grand 			{
1012a27d9caSArmin Le Grand 				return snapToZeroRange(v - fLow, fHigh - fLow) + fLow;
1022a27d9caSArmin Le Grand 			}
1032a27d9caSArmin Le Grand 			else
1042a27d9caSArmin Le Grand 			{
1052a27d9caSArmin Le Grand 				return v;
1062a27d9caSArmin Le Grand 			}
1072a27d9caSArmin Le Grand 		}
1082a27d9caSArmin Le Grand 	}
109cdf0e10cSrcweir } // end of namespace basegfx
110cdf0e10cSrcweir 
111cdf0e10cSrcweir // eof
112