Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <rtl/instance.hxx>
30 : : #include <basegfx/matrix/b3dhommatrix.hxx>
31 : : #include <hommatrixtemplate.hxx>
32 : : #include <basegfx/vector/b3dvector.hxx>
33 : :
34 : : namespace basegfx
35 : : {
36 : 382890 : class Impl3DHomMatrix : public ::basegfx::internal::ImplHomMatrixTemplate< 4 >
37 : : {
38 : : };
39 : :
40 : : namespace { struct IdentityMatrix : public rtl::Static< B3DHomMatrix::ImplType,
41 : : IdentityMatrix > {}; }
42 : :
43 : 160179 : B3DHomMatrix::B3DHomMatrix() :
44 : 160179 : mpImpl( IdentityMatrix::get() ) // use common identity matrix
45 : : {
46 : 160179 : }
47 : :
48 : 78663 : B3DHomMatrix::B3DHomMatrix(const B3DHomMatrix& rMat) :
49 : 78663 : mpImpl(rMat.mpImpl)
50 : : {
51 : 78663 : }
52 : :
53 : 238832 : B3DHomMatrix::~B3DHomMatrix()
54 : : {
55 : 238832 : }
56 : :
57 : 75599 : B3DHomMatrix& B3DHomMatrix::operator=(const B3DHomMatrix& rMat)
58 : : {
59 : 75599 : mpImpl = rMat.mpImpl;
60 : 75599 : return *this;
61 : : }
62 : :
63 : 1366157 : double B3DHomMatrix::get(sal_uInt16 nRow, sal_uInt16 nColumn) const
64 : : {
65 : 1366157 : return mpImpl->get(nRow, nColumn);
66 : : }
67 : :
68 : 803213 : void B3DHomMatrix::set(sal_uInt16 nRow, sal_uInt16 nColumn, double fValue)
69 : : {
70 : 803213 : mpImpl->set(nRow, nColumn, fValue);
71 : 803213 : }
72 : :
73 : 87345 : bool B3DHomMatrix::isLastLineDefault() const
74 : : {
75 : 87345 : return mpImpl->isLastLineDefault();
76 : : }
77 : :
78 : 121015 : bool B3DHomMatrix::isIdentity() const
79 : : {
80 [ + + ]: 121015 : if(mpImpl.same_object(IdentityMatrix::get()))
81 : 41964 : return true;
82 : :
83 : 121015 : return mpImpl->isIdentity();
84 : : }
85 : :
86 : 4466 : void B3DHomMatrix::identity()
87 : : {
88 : 4466 : mpImpl = IdentityMatrix::get();
89 : 4466 : }
90 : :
91 : 5200 : bool B3DHomMatrix::invert()
92 : : {
93 [ + - ][ + - ]: 5200 : Impl3DHomMatrix aWork(*mpImpl);
94 [ + - ][ + - ]: 5200 : sal_uInt16* pIndex = new sal_uInt16[mpImpl->getEdgeLength()];
95 : : sal_Int16 nParity;
96 : :
97 [ + - ][ + - ]: 5200 : if(aWork.ludcmp(pIndex, nParity))
98 : : {
99 [ + - ][ + - ]: 5200 : mpImpl->doInvert(aWork, pIndex);
100 [ + - ]: 5200 : delete[] pIndex;
101 : :
102 : 5200 : return true;
103 : : }
104 : :
105 [ # # ]: 0 : delete[] pIndex;
106 [ + - ]: 5200 : return false;
107 : : }
108 : :
109 : 1277 : double B3DHomMatrix::determinant() const
110 : : {
111 : 1277 : return mpImpl->doDeterminant();
112 : : }
113 : :
114 : 0 : B3DHomMatrix& B3DHomMatrix::operator+=(const B3DHomMatrix& rMat)
115 : : {
116 : 0 : mpImpl->doAddMatrix(*rMat.mpImpl);
117 : 0 : return *this;
118 : : }
119 : :
120 : 0 : B3DHomMatrix& B3DHomMatrix::operator-=(const B3DHomMatrix& rMat)
121 : : {
122 : 0 : mpImpl->doSubMatrix(*rMat.mpImpl);
123 : 0 : return *this;
124 : : }
125 : :
126 : 0 : B3DHomMatrix& B3DHomMatrix::operator*=(double fValue)
127 : : {
128 : 0 : const double fOne(1.0);
129 : :
130 [ # # ]: 0 : if(!fTools::equal(fOne, fValue))
131 [ # # ][ # # ]: 0 : mpImpl->doMulMatrix(fValue);
132 : :
133 : 0 : return *this;
134 : : }
135 : :
136 : 0 : B3DHomMatrix& B3DHomMatrix::operator/=(double fValue)
137 : : {
138 : 0 : const double fOne(1.0);
139 : :
140 [ # # ]: 0 : if(!fTools::equal(fOne, fValue))
141 [ # # ][ # # ]: 0 : mpImpl->doMulMatrix(1.0 / fValue);
142 : :
143 : 0 : return *this;
144 : : }
145 : :
146 : 52837 : B3DHomMatrix& B3DHomMatrix::operator*=(const B3DHomMatrix& rMat)
147 : : {
148 [ + + ]: 52837 : if(!rMat.isIdentity())
149 : 34440 : mpImpl->doMulMatrix(*rMat.mpImpl);
150 : :
151 : 52837 : return *this;
152 : : }
153 : :
154 : 15551 : bool B3DHomMatrix::operator==(const B3DHomMatrix& rMat) const
155 : : {
156 [ + + ]: 15551 : if(mpImpl.same_object(rMat.mpImpl))
157 : 11513 : return true;
158 : :
159 : 15551 : return mpImpl->isEqual(*rMat.mpImpl);
160 : : }
161 : :
162 : 4099 : bool B3DHomMatrix::operator!=(const B3DHomMatrix& rMat) const
163 : : {
164 : 4099 : return !(*this == rMat);
165 : : }
166 : :
167 : 2425 : void B3DHomMatrix::rotate(double fAngleX,double fAngleY,double fAngleZ)
168 : : {
169 [ + + ][ + - ]: 2425 : if(!fTools::equalZero(fAngleX) || !fTools::equalZero(fAngleY) || !fTools::equalZero(fAngleZ))
[ - + ][ + + ]
170 : : {
171 [ + - ]: 105 : if(!fTools::equalZero(fAngleX))
172 : : {
173 [ + - ]: 105 : Impl3DHomMatrix aRotMatX;
174 : 105 : double fSin(sin(fAngleX));
175 : 105 : double fCos(cos(fAngleX));
176 : :
177 [ + - ]: 105 : aRotMatX.set(1, 1, fCos);
178 [ + - ]: 105 : aRotMatX.set(2, 2, fCos);
179 [ + - ]: 105 : aRotMatX.set(2, 1, fSin);
180 [ + - ]: 105 : aRotMatX.set(1, 2, -fSin);
181 : :
182 [ + - ][ + - ]: 105 : mpImpl->doMulMatrix(aRotMatX);
[ + - ]
183 : : }
184 : :
185 [ + + ]: 105 : if(!fTools::equalZero(fAngleY))
186 : : {
187 [ + - ]: 101 : Impl3DHomMatrix aRotMatY;
188 : 101 : double fSin(sin(fAngleY));
189 : 101 : double fCos(cos(fAngleY));
190 : :
191 [ + - ]: 101 : aRotMatY.set(0, 0, fCos);
192 [ + - ]: 101 : aRotMatY.set(2, 2, fCos);
193 [ + - ]: 101 : aRotMatY.set(0, 2, fSin);
194 [ + - ]: 101 : aRotMatY.set(2, 0, -fSin);
195 : :
196 [ + - ][ + - ]: 101 : mpImpl->doMulMatrix(aRotMatY);
[ + - ]
197 : : }
198 : :
199 [ + + ]: 105 : if(!fTools::equalZero(fAngleZ))
200 : : {
201 [ + - ]: 101 : Impl3DHomMatrix aRotMatZ;
202 : 101 : double fSin(sin(fAngleZ));
203 : 101 : double fCos(cos(fAngleZ));
204 : :
205 [ + - ]: 101 : aRotMatZ.set(0, 0, fCos);
206 [ + - ]: 101 : aRotMatZ.set(1, 1, fCos);
207 [ + - ]: 101 : aRotMatZ.set(1, 0, fSin);
208 [ + - ]: 101 : aRotMatZ.set(0, 1, -fSin);
209 : :
210 [ + - ][ + - ]: 101 : mpImpl->doMulMatrix(aRotMatZ);
[ + - ]
211 : : }
212 : : }
213 : 2425 : }
214 : :
215 : 50903 : void B3DHomMatrix::translate(double fX, double fY, double fZ)
216 : : {
217 [ + + ][ + + ]: 50903 : if(!fTools::equalZero(fX) || !fTools::equalZero(fY) || !fTools::equalZero(fZ))
[ + + ][ + + ]
218 : : {
219 [ + - ]: 39753 : Impl3DHomMatrix aTransMat;
220 : :
221 [ + - ]: 39753 : aTransMat.set(0, 3, fX);
222 [ + - ]: 39753 : aTransMat.set(1, 3, fY);
223 [ + - ]: 39753 : aTransMat.set(2, 3, fZ);
224 : :
225 [ + - ][ + - ]: 39753 : mpImpl->doMulMatrix(aTransMat);
[ + - ]
226 : : }
227 : 50903 : }
228 : :
229 : 15011 : void B3DHomMatrix::scale(double fX, double fY, double fZ)
230 : : {
231 : 15011 : const double fOne(1.0);
232 : :
233 [ + + ][ - + ]: 15011 : if(!fTools::equal(fOne, fX) || !fTools::equal(fOne, fY) ||!fTools::equal(fOne, fZ))
[ # # ][ + - ]
234 : : {
235 [ + - ]: 15011 : Impl3DHomMatrix aScaleMat;
236 : :
237 [ + - ]: 15011 : aScaleMat.set(0, 0, fX);
238 [ + - ]: 15011 : aScaleMat.set(1, 1, fY);
239 [ + - ]: 15011 : aScaleMat.set(2, 2, fZ);
240 : :
241 [ + - ][ + - ]: 15011 : mpImpl->doMulMatrix(aScaleMat);
[ + - ]
242 : : }
243 : 15011 : }
244 : :
245 : 11 : void B3DHomMatrix::shearXY(double fSx, double fSy)
246 : : {
247 : : // #i76239# do not test againt 1.0, but against 0.0. We are talking about a value not on the diagonal (!)
248 [ - + ][ # # ]: 11 : if(!fTools::equalZero(fSx) || !fTools::equalZero(fSy))
[ + - ]
249 : : {
250 [ + - ]: 11 : Impl3DHomMatrix aShearXYMat;
251 : :
252 [ + - ]: 11 : aShearXYMat.set(0, 2, fSx);
253 [ + - ]: 11 : aShearXYMat.set(1, 2, fSy);
254 : :
255 [ + - ][ + - ]: 11 : mpImpl->doMulMatrix(aShearXYMat);
[ + - ]
256 : : }
257 : 11 : }
258 : :
259 : 150 : void B3DHomMatrix::frustum(double fLeft, double fRight, double fBottom, double fTop, double fNear, double fFar)
260 : : {
261 : 150 : const double fZero(0.0);
262 : 150 : const double fOne(1.0);
263 : :
264 [ - + ]: 150 : if(!fTools::more(fNear, fZero))
265 : : {
266 : 0 : fNear = 0.001;
267 : : }
268 : :
269 [ - + ]: 150 : if(!fTools::more(fFar, fZero))
270 : : {
271 : 0 : fFar = fOne;
272 : : }
273 : :
274 [ - + ]: 150 : if(fTools::equal(fNear, fFar))
275 : : {
276 : 0 : fFar = fNear + fOne;
277 : : }
278 : :
279 [ + + ]: 150 : if(fTools::equal(fLeft, fRight))
280 : : {
281 : 14 : fLeft -= fOne;
282 : 14 : fRight += fOne;
283 : : }
284 : :
285 [ - + ]: 150 : if(fTools::equal(fTop, fBottom))
286 : : {
287 : 0 : fBottom -= fOne;
288 : 0 : fTop += fOne;
289 : : }
290 : :
291 [ + - ]: 150 : Impl3DHomMatrix aFrustumMat;
292 : :
293 [ + - ]: 150 : aFrustumMat.set(0, 0, 2.0 * fNear / (fRight - fLeft));
294 [ + - ]: 150 : aFrustumMat.set(1, 1, 2.0 * fNear / (fTop - fBottom));
295 [ + - ]: 150 : aFrustumMat.set(0, 2, (fRight + fLeft) / (fRight - fLeft));
296 [ + - ]: 150 : aFrustumMat.set(1, 2, (fTop + fBottom) / (fTop - fBottom));
297 [ + - ]: 150 : aFrustumMat.set(2, 2, -fOne * ((fFar + fNear) / (fFar - fNear)));
298 [ + - ]: 150 : aFrustumMat.set(3, 2, -fOne);
299 [ + - ]: 150 : aFrustumMat.set(2, 3, -fOne * ((2.0 * fFar * fNear) / (fFar - fNear)));
300 [ + - ]: 150 : aFrustumMat.set(3, 3, fZero);
301 : :
302 [ + - ][ + - ]: 150 : mpImpl->doMulMatrix(aFrustumMat);
[ + - ]
303 : 150 : }
304 : :
305 : 960 : void B3DHomMatrix::ortho(double fLeft, double fRight, double fBottom, double fTop, double fNear, double fFar)
306 : : {
307 [ - + ]: 960 : if(fTools::equal(fNear, fFar))
308 : : {
309 : 0 : fFar = fNear + 1.0;
310 : : }
311 : :
312 [ - + ]: 960 : if(fTools::equal(fLeft, fRight))
313 : : {
314 : 0 : fLeft -= 1.0;
315 : 0 : fRight += 1.0;
316 : : }
317 : :
318 [ - + ]: 960 : if(fTools::equal(fTop, fBottom))
319 : : {
320 : 0 : fBottom -= 1.0;
321 : 0 : fTop += 1.0;
322 : : }
323 : :
324 [ + - ]: 960 : Impl3DHomMatrix aOrthoMat;
325 : :
326 [ + - ]: 960 : aOrthoMat.set(0, 0, 2.0 / (fRight - fLeft));
327 [ + - ]: 960 : aOrthoMat.set(1, 1, 2.0 / (fTop - fBottom));
328 [ + - ]: 960 : aOrthoMat.set(2, 2, -1.0 * (2.0 / (fFar - fNear)));
329 [ + - ]: 960 : aOrthoMat.set(0, 3, -1.0 * ((fRight + fLeft) / (fRight - fLeft)));
330 [ + - ]: 960 : aOrthoMat.set(1, 3, -1.0 * ((fTop + fBottom) / (fTop - fBottom)));
331 [ + - ]: 960 : aOrthoMat.set(2, 3, -1.0 * ((fFar + fNear) / (fFar - fNear)));
332 : :
333 [ + - ][ + - ]: 960 : mpImpl->doMulMatrix(aOrthoMat);
[ + - ]
334 : 960 : }
335 : :
336 : 555 : void B3DHomMatrix::orientation(B3DPoint aVRP, B3DVector aVPN, B3DVector aVUV)
337 : : {
338 [ + - ]: 555 : Impl3DHomMatrix aOrientationMat;
339 : :
340 : : // translate -VRP
341 [ + - ]: 555 : aOrientationMat.set(0, 3, -aVRP.getX());
342 [ + - ]: 555 : aOrientationMat.set(1, 3, -aVRP.getY());
343 [ + - ]: 555 : aOrientationMat.set(2, 3, -aVRP.getZ());
344 : :
345 : : // build rotation
346 [ + - ]: 555 : aVUV.normalize();
347 [ + - ]: 555 : aVPN.normalize();
348 : :
349 : : // build x-axis as peroendicular fron aVUV and aVPN
350 [ + - ]: 555 : B3DVector aRx(aVUV.getPerpendicular(aVPN));
351 [ + - ]: 555 : aRx.normalize();
352 : :
353 : : // y-axis perpendicular to that
354 [ + - ]: 555 : B3DVector aRy(aVPN.getPerpendicular(aRx));
355 [ + - ]: 555 : aRy.normalize();
356 : :
357 : : // the calculated normals are the line vectors of the rotation matrix,
358 : : // set them to create rotation
359 [ + - ]: 555 : aOrientationMat.set(0, 0, aRx.getX());
360 [ + - ]: 555 : aOrientationMat.set(0, 1, aRx.getY());
361 [ + - ]: 555 : aOrientationMat.set(0, 2, aRx.getZ());
362 [ + - ]: 555 : aOrientationMat.set(1, 0, aRy.getX());
363 [ + - ]: 555 : aOrientationMat.set(1, 1, aRy.getY());
364 [ + - ]: 555 : aOrientationMat.set(1, 2, aRy.getZ());
365 [ + - ]: 555 : aOrientationMat.set(2, 0, aVPN.getX());
366 [ + - ]: 555 : aOrientationMat.set(2, 1, aVPN.getY());
367 [ + - ]: 555 : aOrientationMat.set(2, 2, aVPN.getZ());
368 : :
369 [ + - ][ + - ]: 555 : mpImpl->doMulMatrix(aOrientationMat);
[ + - ]
370 : 555 : }
371 : :
372 : 1277 : bool B3DHomMatrix::decompose(B3DTuple& rScale, B3DTuple& rTranslate, B3DTuple& rRotate, B3DTuple& rShear) const
373 : : {
374 : : // when perspective is used, decompose is not made here
375 [ + - ][ - + ]: 1277 : if(!mpImpl->isLastLineDefault())
376 : 0 : return false;
377 : :
378 : : // If determinant is zero, decomposition is not possible
379 [ + - ][ - + ]: 1277 : if(0.0 == determinant())
380 : 0 : return false;
381 : :
382 : : // isolate translation
383 [ + - ]: 1277 : rTranslate.setX(mpImpl->get(0, 3));
384 [ + - ]: 1277 : rTranslate.setY(mpImpl->get(1, 3));
385 [ + - ]: 1277 : rTranslate.setZ(mpImpl->get(2, 3));
386 : :
387 : : // correct translate values
388 : 1277 : rTranslate.correctValues();
389 : :
390 : : // get scale and shear
391 [ + - ][ + - ]: 1277 : B3DVector aCol0(mpImpl->get(0, 0), mpImpl->get(1, 0), mpImpl->get(2, 0));
[ + - ]
392 [ + - ][ + - ]: 1277 : B3DVector aCol1(mpImpl->get(0, 1), mpImpl->get(1, 1), mpImpl->get(2, 1));
[ + - ]
393 [ + - ][ + - ]: 1277 : B3DVector aCol2(mpImpl->get(0, 2), mpImpl->get(1, 2), mpImpl->get(2, 2));
[ + - ]
394 : 1277 : B3DVector aTemp;
395 : :
396 : : // get ScaleX
397 [ + - ]: 1277 : rScale.setX(aCol0.getLength());
398 [ + - ]: 1277 : aCol0.normalize();
399 : :
400 : : // get ShearXY
401 : 1277 : rShear.setX(aCol0.scalar(aCol1));
402 : :
403 [ + - ]: 1277 : if(fTools::equalZero(rShear.getX()))
404 : : {
405 : 1277 : rShear.setX(0.0);
406 : : }
407 : : else
408 : : {
409 : 0 : aTemp.setX(aCol1.getX() - rShear.getX() * aCol0.getX());
410 : 0 : aTemp.setY(aCol1.getY() - rShear.getX() * aCol0.getY());
411 : 0 : aTemp.setZ(aCol1.getZ() - rShear.getX() * aCol0.getZ());
412 [ # # ]: 0 : aCol1 = aTemp;
413 : : }
414 : :
415 : : // get ScaleY
416 [ + - ]: 1277 : rScale.setY(aCol1.getLength());
417 [ + - ]: 1277 : aCol1.normalize();
418 : :
419 : 1277 : const double fShearX(rShear.getX());
420 : :
421 [ - + ]: 1277 : if(!fTools::equalZero(fShearX))
422 : : {
423 : 0 : rShear.setX(rShear.getX() / rScale.getY());
424 : : }
425 : :
426 : : // get ShearXZ
427 : 1277 : rShear.setY(aCol0.scalar(aCol2));
428 : :
429 [ + - ]: 1277 : if(fTools::equalZero(rShear.getY()))
430 : : {
431 : 1277 : rShear.setY(0.0);
432 : : }
433 : : else
434 : : {
435 : 0 : aTemp.setX(aCol2.getX() - rShear.getY() * aCol0.getX());
436 : 0 : aTemp.setY(aCol2.getY() - rShear.getY() * aCol0.getY());
437 : 0 : aTemp.setZ(aCol2.getZ() - rShear.getY() * aCol0.getZ());
438 [ # # ]: 0 : aCol2 = aTemp;
439 : : }
440 : :
441 : : // get ShearYZ
442 : 1277 : rShear.setZ(aCol1.scalar(aCol2));
443 : :
444 [ + - ]: 1277 : if(fTools::equalZero(rShear.getZ()))
445 : : {
446 : 1277 : rShear.setZ(0.0);
447 : : }
448 : : else
449 : : {
450 : 0 : aTemp.setX(aCol2.getX() - rShear.getZ() * aCol1.getX());
451 : 0 : aTemp.setY(aCol2.getY() - rShear.getZ() * aCol1.getY());
452 : 0 : aTemp.setZ(aCol2.getZ() - rShear.getZ() * aCol1.getZ());
453 [ # # ]: 0 : aCol2 = aTemp;
454 : : }
455 : :
456 : : // get ScaleZ
457 [ + - ]: 1277 : rScale.setZ(aCol2.getLength());
458 [ + - ]: 1277 : aCol2.normalize();
459 : :
460 : 1277 : const double fShearY(rShear.getY());
461 : :
462 [ - + ]: 1277 : if(!fTools::equalZero(fShearY))
463 : : {
464 : 0 : rShear.setY(rShear.getY() / rScale.getZ());
465 : : }
466 : :
467 : 1277 : const double fShearZ(rShear.getZ());
468 : :
469 [ - + ]: 1277 : if(!fTools::equalZero(fShearZ))
470 : : {
471 : 0 : rShear.setZ(rShear.getZ() / rScale.getZ());
472 : : }
473 : :
474 : : // correct shear values
475 : 1277 : rShear.correctValues();
476 : :
477 : : // Coordinate system flip?
478 [ + + ][ + - ]: 1277 : if(0.0 > aCol0.scalar(aCol1.getPerpendicular(aCol2)))
479 : : {
480 : 983 : rScale = -rScale;
481 : 983 : aCol0 = -aCol0;
482 : 983 : aCol1 = -aCol1;
483 : 983 : aCol2 = -aCol2;
484 : : }
485 : :
486 : : // correct scale values
487 : 1277 : rScale.correctValues(1.0);
488 : :
489 : : // Get rotations
490 : : {
491 : 1277 : double fy=0;
492 : 1277 : double cy=0;
493 : :
494 [ + - ][ + - ]: 2554 : if( ::basegfx::fTools::equal( aCol0.getZ(), 1.0 )
[ - + ]
[ + - - + ]
495 : 1277 : || aCol0.getZ() > 1.0 )
496 : : {
497 : 0 : fy = -F_PI/2.0;
498 : 0 : cy = 0.0;
499 : : }
500 [ + - - + ]: 2554 : else if( ::basegfx::fTools::equal( aCol0.getZ(), -1.0 )
[ + - ][ + - ]
[ - + ]
501 : 1277 : || aCol0.getZ() < -1.0 )
502 : : {
503 : 0 : fy = F_PI/2.0;
504 : 0 : cy = 0.0;
505 : : }
506 : : else
507 : : {
508 : 1277 : fy = asin( -aCol0.getZ() );
509 : 1277 : cy = cos(fy);
510 : : }
511 : :
512 : 1277 : rRotate.setY(fy);
513 [ - + ]: 1277 : if( ::basegfx::fTools::equalZero( cy ) )
514 : : {
515 [ # # ]: 0 : if( aCol0.getZ() > 0.0 )
516 : 0 : rRotate.setX(atan2(-1.0*aCol1.getX(), aCol1.getY()));
517 : : else
518 : 0 : rRotate.setX(atan2(aCol1.getX(), aCol1.getY()));
519 : 0 : rRotate.setZ(0.0);
520 : : }
521 : : else
522 : : {
523 : 1277 : rRotate.setX(atan2(aCol1.getZ(), aCol2.getZ()));
524 : 1277 : rRotate.setZ(atan2(aCol0.getY(), aCol0.getX()));
525 : : }
526 : :
527 : : // corrcet rotate values
528 : 1277 : rRotate.correctValues();
529 : : }
530 : :
531 : 1277 : return true;
532 : : }
533 : : } // end of namespace basegfx
534 : :
535 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|