Update ooo320-m1
[ooovba.git] / svtools / source / dialogs / mcvmath.cxx
blobfbf4fd40a5bd8aa359076ca3682ac69d4cc767c4
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: mcvmath.cxx,v $
10 * $Revision: 1.5 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
34 #include <mcvmath.hxx>
36 // ---------------------------------------------------------------------
37 // die folgenden Tabellen enthalten sin(phi) * 2**14
38 // fuer phi= 360Grad*2**-32 bis 360 Grad
39 // def. fuer x: phi=360Grad * 2**(x-16)
40 // d.h. x = 16 -> 360 Grad
41 // x = -16 -> (2**-16) * 360 Grad
42 // x: -16 ... 0 ... 15
43 //x= 0, 1, 2, 3, 4, 5, 6, 7,
44 // 8, 9, 10, 11, 12, 13, 14, 15
46 static const short CosTab[16] =
48 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16383,
49 16379, 16364, 16305, 16069, 15137, 11585, 0, -16383
51 static const short SinTab[16]=
53 2, 3, 6, 13, 25, 50, 101, 201,
54 402, 804, 1606, 3196, 6270, 11585, 16384, 0
57 /**************************************************************************
59 |* ImpMultBig2()
61 |* Beschreibung Multiplikation fuer FixPoint-Berechnungen
62 |* Ersterstellung SH 01.07.93
63 |* Letzte Aenderung SH 01.07.93
65 **************************************************************************/
67 // first parameter should be the bigger one
69 Fix ImpMultBig2( const Fix& a, const Fix& b )
71 Fix f;
72 f.x = (((b.x+FIX_A2)>>FIX_P2)*a.x+FIX_A3)>>FIX_P3;
73 return f;
76 /**************************************************************************
78 |* ImpMultBig2()
80 |* Beschreibung Multiplikation fuer FixPoint-Berechnungen
81 |* Ersterstellung SH 01.07.93
82 |* Letzte Aenderung SH 01.07.93
84 **************************************************************************/
86 // first parameter should be the bigger one
88 FixCpx ImpMultBig2( const FixCpx& ra, const FixCpx& rb )
90 Fix rr = ImpMultBig2(ra.r,rb.r)-ImpMultBig2(ra.i,rb.i);
91 Fix ii = ImpMultBig2(ra.r,rb.i)+ImpMultBig2(ra.i,rb.r);
92 return FixCpx( rr,ii );
95 /**************************************************************************
97 |* ImpSqrt()
99 |* Beschreibung Wurzelfunktion fuer FixPoint-Berechnungen
100 |* Ersterstellung SH 01.07.93
101 |* Letzte Aenderung SH 01.07.93
103 **************************************************************************/
105 USHORT ImpSqrt( ULONG nRadi )
107 register ULONG inf = 1;
108 register ULONG sup = nRadi;
109 register ULONG sqr;
111 if ( !nRadi )
112 return 0;
114 while ( (inf<<1) <= sup )
116 sup >>= 1;
117 inf <<= 1;
119 sqr = (sup+inf) >> 1; // Anfangswert der Iteration
121 sqr = (nRadi/sqr + sqr) >> 1; // 2 Newton-Iterationen reichen fuer
122 sqr = (nRadi/sqr + sqr) >> 1; // +- 1 Digit
124 return sal::static_int_cast< USHORT >(sqr);
127 /**************************************************************************
129 |* ImpExPI()
131 |* Beschreibung EXPI-Funktion fuer FixPoint-Berechnungen
132 |* Ersterstellung SH 01.07.93
133 |* Letzte Aenderung SH 01.07.93
135 **************************************************************************/
137 // e**(i*nPhi), Einheit nPhi: 2**16 == 360 Grad
139 FixCpx ImpExPI( USHORT nPhi )
141 short i;
142 FixCpx aIter(1L); // e**(0*i)
143 FixCpx Mul;
144 const char Sft=14-FIX_POST;
146 for ( i = 15; i >= 0; i-- )
148 if ( (1L<<i) & nPhi )
150 Mul.r.x = CosTab[i]>>Sft; // e**(i(phi1+phi2)) =
151 Mul.i.x = SinTab[i]>>Sft; // e**(i*phi1)) * e**(i*phi2))
152 aIter *= Mul;
156 return aIter;
159 /**************************************************************************
161 |* ImpATanx2()
163 |* Beschreibung ATANX2-Funktion fuer FixPoint-Berechnungen
164 |* Ersterstellung SH 01.07.93
165 |* Letzte Aenderung SH 01.07.93
167 **************************************************************************/
169 // use for x*x+y*y==1 only
171 static USHORT ImpATanx2( const Fix& rX, const Fix& rY )
173 USHORT phi0 = 0; // result angel higher part
174 USHORT phi = 0; // dito lower part
175 long x = rX.x;
176 long y = rY.x;
177 long z;
178 const char Sft=14-FIX_POST;
179 short i;
180 FixCpx aTry;
181 FixCpx aInc;
182 FixCpx aIter(1L);
183 BOOL Small = FALSE;
185 if ( (x==0) && (y==0) )
186 return 0;
188 if ( y < 0)
190 // reduce 3. to 1. quadrant (0..90 Degree)
191 phi0 += 180L * 65536L / 360L;
192 // turn 180 degree
193 y *= -1;
194 x *= -1;
197 if ( x < 0)
199 // 2. to 1. q.
200 phi0 += 90L * 65536L / 360L;
201 // turn 90 degree clockwise
202 z = y;
203 y = -x;
204 x = z;
207 for ( i = 13; i >= 0; i-- )
209 aInc.r.x = CosTab[i]>>Sft; // e**(i(phi1+phi2)) =
210 aInc.i.x = SinTab[i]>>Sft; // e**(i*phi1)) * e**(i*phi2))
211 aTry = aIter*aInc;
213 if ( Small )
215 // is try ok
216 if ( aTry.r.x >= x )
218 aIter = aTry;
219 phi += (1<<i);
222 else
224 // is try ok
225 if ( aTry.i.x <= y )
227 aIter = aTry;
228 phi += (1<<i);
230 if ( i > 11 )
231 Small=TRUE;
236 return phi0+phi;
239 /**************************************************************************
241 |* ImpATan2()
243 |* Beschreibung ATAN-Funktion fuer FixPoint-Berechnungen
244 |* Ersterstellung SH 01.07.93
245 |* Letzte Aenderung SH 01.07.93
247 **************************************************************************/
249 USHORT ImpATan2( const short x, const short y )
251 Fix rRad = ImpSqrt(ULONG(long(x)*x+long(y)*y));
253 if ( !rRad.x )
254 return 0;
255 Fix fx = x;
256 fx.DivBig( rRad ); // Normiere auf Einheitskreis
257 Fix fy = y;
258 fy.DivBig( rRad );
260 return ImpATanx2( fx, fy );
263 /**************************************************************************
265 |* ImpCartToPolar()
267 |* Beschreibung Koordinaaten-Wandlung
268 |* Ersterstellung SH 01.07.93
269 |* Letzte Aenderung SH 01.07.93
271 **************************************************************************/
273 void ImpCartToPolar( const short x, const short y, Fix& rRad, USHORT& rPhi )
275 rRad = Fix( ImpSqrt( ULONG( long(x)*x+long(y)*y ) ) );
277 if ( !rRad.x )
278 rPhi=0;
279 else
281 // Normiere auf Einheitskreis
282 Fix fx = x;
283 fx.DivBig(rRad);
284 Fix fy = y;
285 fy.DivBig(rRad);
286 rPhi = ImpATanx2(fx, fy);
290 /**************************************************************************
292 |* ImpPolarToCart()
294 |* Beschreibung Koordinaaten-Wandlung
295 |* Ersterstellung SH 01.07.93
296 |* Letzte Aenderung SH 01.07.93
298 **************************************************************************/
300 void ImpPolarToCart( const Fix& rR, const USHORT Phi, short& rX, short& rY )
302 FixCpx fc = ImpExPI( Phi ); // calculate sin() & cos()
303 fc.GetReal().MultBig( rR );
304 rX = sal::static_int_cast< short >(long( fc.GetReal() ));
305 fc.GetImag().MultBig( rR );
306 rY = sal::static_int_cast< short >(long( fc.GetImag() ));