tdf#154285 Check upper bound of arguments in SbRtl_Minute function
[LibreOffice.git] / chart2 / source / tools / ThreeDHelper.cxx
blobdf3ab62d082ceceb78fe7c0d30dad096f2048f24
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <basegfx/numeric/ftools.hxx>
21 #include <ThreeDHelper.hxx>
22 #include <Diagram.hxx>
23 #include <ChartTypeHelper.hxx>
24 #include <DataSeries.hxx>
25 #include <DataSeriesHelper.hxx>
26 #include <defines.hxx>
28 #include <com/sun/star/drawing/LineStyle.hpp>
29 #include <comphelper/diagnose_ex.hxx>
30 #include <tools/helpers.hxx>
31 #include <rtl/math.hxx>
33 namespace chart
35 using namespace ::com::sun::star;
36 using namespace ::com::sun::star::chart2;
38 using ::com::sun::star::uno::Reference;
39 using ::rtl::math::cos;
40 using ::rtl::math::sin;
41 using ::rtl::math::tan;
43 namespace
46 bool lcl_isRightAngledAxesSetAndSupported( const rtl::Reference< Diagram >& xDiagram )
48 if( xDiagram.is() )
50 bool bRightAngledAxes = false;
51 xDiagram->getPropertyValue( u"RightAngledAxes"_ustr) >>= bRightAngledAxes;
52 if(bRightAngledAxes)
54 if( ChartTypeHelper::isSupportingRightAngledAxes(
55 xDiagram->getChartTypeByIndex( 0 ) ) )
57 return true;
61 return false;
64 } //end anonymous namespace
66 drawing::CameraGeometry ThreeDHelper::getDefaultCameraGeometry( bool bPie )
68 // ViewReferencePoint (Point on the View plane)
69 drawing::Position3D vrp(17634.6218373783, 10271.4823817647, 24594.8639082739);
70 // ViewPlaneNormal (Normal to the View Plane)
71 drawing::Direction3D vpn(0.416199821709347, 0.173649045905254, 0.892537795986984);
72 // ViewUpVector (determines the v-axis direction on the view plane as
73 // projection of VUP parallel to VPN onto th view pane)
74 drawing::Direction3D vup(-0.0733876362771618, 0.984807599917971, -0.157379306090273);
76 if( bPie )
78 vrp = drawing::Position3D( 0.0, 0.0, 87591.2408759124 );//--> 5 percent perspective
79 vpn = drawing::Direction3D( 0.0, 0.0, 1.0 );
80 vup = drawing::Direction3D( 0.0, 1.0, 0.0 );
83 return drawing::CameraGeometry( vrp, vpn, vup );
86 namespace
88 void lcl_ensureIntervalMinus1To1( double& rSinOrCos )
90 if (rSinOrCos < -1.0)
91 rSinOrCos = -1.0;
92 else if (rSinOrCos > 1.0)
93 rSinOrCos = 1.0;
96 bool lcl_isSinZero( double fAngleRad )
98 return ::basegfx::fTools::equalZero( sin(fAngleRad), 0.0000001 );
100 bool lcl_isCosZero( double fAngleRad )
102 return ::basegfx::fTools::equalZero( cos(fAngleRad), 0.0000001 );
107 void ThreeDHelper::convertElevationRotationDegToXYZAngleRad(
108 sal_Int32 nElevationDeg, sal_Int32 nRotationDeg,
109 double& rfXAngleRad, double& rfYAngleRad, double& rfZAngleRad)
111 // for a description of the algorithm see issue 72994
112 //https://bz.apache.org/ooo/show_bug.cgi?id=72994
113 //https://bz.apache.org/ooo/attachment.cgi?id=50608
115 nElevationDeg = NormAngle360(nElevationDeg);
116 nRotationDeg = NormAngle360(nRotationDeg);
118 double& x = rfXAngleRad;
119 double& y = rfYAngleRad;
120 double& z = rfZAngleRad;
122 double E = basegfx::deg2rad(nElevationDeg); //elevation in Rad
123 double R = basegfx::deg2rad(nRotationDeg); //rotation in Rad
125 if( (nRotationDeg == 0 || nRotationDeg == 180 )
126 && ( nElevationDeg == 90 || nElevationDeg == 270 ) )
128 //sR==0 && cE==0
129 z = 0.0;
130 //element 23
131 double f23 = cos(R)*sin(E);
132 if(f23>0)
133 x = M_PI_2;
134 else
135 x = -M_PI_2;
136 y = R;
138 else if( ( nRotationDeg == 90 || nRotationDeg == 270 )
139 && ( nElevationDeg == 90 || nElevationDeg == 270 ) )
141 //cR==0 && cE==0
142 z = M_PI_2;
143 if( sin(R)>0 )
144 x = M_PI_2;
145 else
146 x = -M_PI_2;
148 if( (sin(R)*sin(E))>0 )
149 y = 0.0;
150 else
151 y = M_PI;
153 else if( (nRotationDeg == 0 || nRotationDeg == 180 )
154 && ( nElevationDeg == 0 || nElevationDeg == 180 ) )
156 //sR==0 && sE==0
157 z = 0.0;
158 y = R;
159 x = E;
161 else if( ( nRotationDeg == 90 || nRotationDeg == 270 )
162 && ( nElevationDeg == 0 || nElevationDeg == 180 ) )
164 //cR==0 && sE==0
165 z = 0.0;
167 if( (sin(R)/cos(E))>0 )
168 y = M_PI_2;
169 else
170 y = -M_PI_2;
172 if( (cos(E))>0 )
173 x = 0;
174 else
175 x = M_PI;
177 else if ( nElevationDeg == 0 || nElevationDeg == 180 )
179 //sR!=0 cR!=0 sE==0
180 z = 0.0;
181 x = E;
182 y = R;
183 //use element 13 for sign
184 if((cos(x)*sin(y)*sin(R))<0.0)
185 y *= -1.0;
187 else if ( nElevationDeg == 90 || nElevationDeg == 270 )
189 //sR!=0 cR!=0 cE==0
190 //element 12 + 22 --> y=0 or M_PI and x=+-M_PI/2
191 //-->element 13/23:
192 z = atan(sin(R)/(cos(R)*sin(E)));
193 //use element 13 for sign for x
194 if( (sin(R)*sin(z))>0.0 )
195 x = M_PI_2;
196 else
197 x = -M_PI_2;
198 //use element 21 for y
199 if( (sin(R)*sin(E)*sin(z))>0.0)
200 y = 0.0;
201 else
202 y = M_PI;
204 else if ( nRotationDeg == 0 || nRotationDeg == 180 )
206 //sE!=0 cE!=0 sR==0
207 z = 0.0;
208 x = E;
209 y = R;
210 double f23 = cos(R)*sin(E);
211 if( (f23 * sin(x)) < 0.0 )
212 x *= -1.0; //todo ??
214 else if (nRotationDeg == 90 || nRotationDeg == 270)
216 //sE!=0 cE!=0 cR==0
217 //z = +- M_PI/2;
218 //x = +- M_PI/2;
219 z = M_PI_2;
220 x = M_PI_2;
221 double sR = sin(R);
222 if( sR<0.0 )
223 x *= -1.0; //different signs for x and z
225 //use element 21:
226 double cy = sR*sin(E)/sin(z);
227 lcl_ensureIntervalMinus1To1(cy);
228 y = acos(cy);
230 //use element 22 for sign:
231 if( (sin(x)*sin(y)*sin(z)*cos(E))<0.0)
232 y *= -1.0;
234 else
236 z = atan(tan(R) * sin(E));
237 if(cos(z)==0.0)
239 OSL_FAIL("calculation error in ThreeDHelper::convertElevationRotationDegToXYZAngleRad");
240 return;
242 double cy = cos(R)/cos(z);
243 lcl_ensureIntervalMinus1To1(cy);
244 y = acos(cy);
246 //element 12 in 23
247 double fDenominator = cos(z)*(1.0-pow(sin(y),2));
248 if(fDenominator==0.0)
250 OSL_FAIL("calculation error in ThreeDHelper::convertElevationRotationDegToXYZAngleRad");
251 return;
253 double sx = cos(R)*sin(E)/fDenominator;
254 lcl_ensureIntervalMinus1To1(sx);
255 x = asin( sx );
257 //use element 13 for sign:
258 double f13a = cos(x)*cos(z)*sin(y);
259 double f13b = sin(R)-sx*sin(z);
260 if( (f13b*f13a)<0.0 )
262 //change x or y
263 //use element 22 for further investigations:
264 //try
265 y *= -1;
266 double f22a = cos(x)*cos(z);
267 double f22b = cos(E)-(sx*sin(y)*sin(z));
268 if( (f22a*f22b)<0.0 )
270 y *= -1;
271 x=(M_PI-x);
274 else
276 //change nothing or both
277 //use element 22 for further investigations:
278 double f22a = cos(x)*cos(z);
279 double f22b = cos(E)-(sx*sin(y)*sin(z));
280 if( (f22a*f22b)<0.0 )
282 y *= -1;
283 x=(M_PI-x);
289 void ThreeDHelper::convertXYZAngleRadToElevationRotationDeg(
290 sal_Int32& rnElevationDeg, sal_Int32& rnRotationDeg,
291 double fXRad, double fYRad, double fZRad)
293 // for a description of the algorithm see issue 72994
294 //https://bz.apache.org/ooo/show_bug.cgi?id=72994
295 //https://bz.apache.org/ooo/attachment.cgi?id=50608
297 double R = 0.0; //Rotation in Rad
298 double E = 0.0; //Elevation in Rad
300 double& x = fXRad;
301 double& y = fYRad;
302 double& z = fZRad;
304 double f11 = cos(y)*cos(z);
306 if( lcl_isSinZero(y) )
308 //siny == 0
310 if( lcl_isCosZero(x) )
312 //siny == 0 && cosx == 0
314 if( lcl_isSinZero(z) )
316 //siny == 0 && cosx == 0 && sinz == 0
317 //example: x=+-90 y=0oder180 z=0(oder180)
319 //element 13+11
320 if( f11 > 0 )
321 R = 0.0;
322 else
323 R = M_PI;
325 //element 23
326 double f23 = cos(z)*sin(x) / cos(R);
327 if( f23 > 0 )
328 E = M_PI_2;
329 else
330 E = -M_PI_2;
332 else if( lcl_isCosZero(z) )
334 //siny == 0 && cosx == 0 && cosz == 0
335 //example: x=+-90 y=0oder180 z=+-90
337 double f13 = sin(x)*sin(z);
338 //element 13+11
339 if( f13 > 0 )
340 R = M_PI_2;
341 else
342 R = -M_PI_2;
344 //element 21
345 double f21 = cos(y)*sin(z) / sin(R);
346 if( f21 > 0 )
347 E = M_PI_2;
348 else
349 E = -M_PI_2;
351 else
353 //siny == 0 && cosx == 0 && cosz != 0 && sinz != 0
354 //element 11 && 13
355 double f13 = sin(x)*sin(z);
356 R = atan( f13/f11 );
358 if(f11<0)
359 R+=M_PI;
361 //element 23
362 double f23 = cos(z)*sin(x);
363 if( f23/cos(R) > 0 )
364 E = M_PI_2;
365 else
366 E = -M_PI_2;
369 else if( lcl_isSinZero(x) )
371 //sinY==0 sinX==0
372 //element 13+11
373 if( f11 > 0 )
374 R = 0.0;
375 else
376 R = M_PI;
378 double f22 = cos(x)*cos(z);
379 if( f22 > 0 )
380 E = 0.0;
381 else
382 E = M_PI;
384 else if( lcl_isSinZero(z) )
386 //sinY==0 sinZ==0 sinx!=0 cosx!=0
387 //element 13+11
388 if( f11 > 0 )
389 R = 0.0;
390 else
391 R = M_PI;
393 //element 22 && 23
394 double f22 = cos(x)*cos(z);
395 double f23 = cos(z)*sin(x);
396 E = atan( f23/(f22*cos(R)) );
397 if( (f22*cos(E))<0 )
398 E+=M_PI;
400 else if( lcl_isCosZero(z) )
402 //sinY == 0 && cosZ == 0 && cosx != 0 && sinx != 0
403 double f13 = sin(x)*sin(z);
404 //element 13+11
405 if( f13 > 0 )
406 R = M_PI_2;
407 else
408 R = -M_PI_2;
410 //element 21+22
411 double f21 = cos(y)*sin(z);
412 if( f21/sin(R) > 0 )
413 E = M_PI_2;
414 else
415 E = -M_PI_2;
417 else
419 //sinY == 0 && all other !=0
420 double f13 = sin(x)*sin(z);
421 R = atan( f13/f11 );
422 if( (f11*cos(R))<0.0 )
423 R+=M_PI;
425 double f22 = cos(x)*cos(z);
426 if( !lcl_isCosZero(R) )
427 E = atan( cos(z)*sin(x) /( f22*cos(R) ) );
428 else
429 E = atan( cos(y)*sin(z) /( f22*sin(R) ) );
430 if( (f22*cos(E))<0 )
431 E+=M_PI;
434 else if( lcl_isCosZero(y) )
436 //cosY==0
438 double f13 = sin(x)*sin(z)+cos(x)*cos(z)*sin(y);
439 if( f13 >= 0 )
440 R = M_PI_2;
441 else
442 R = -M_PI_2;
444 double f22 = cos(x)*cos(z)+sin(x)*sin(y)*sin(z);
445 if( f22 >= 0 )
446 E = 0.0;
447 else
448 E = M_PI;
450 else if( lcl_isSinZero(x) )
452 //cosY!=0 sinY!=0 sinX=0
453 if( lcl_isSinZero(z) )
455 //cosY!=0 sinY!=0 sinX=0 sinZ=0
456 double f13 = cos(x)*cos(z)*sin(y);
457 R = atan( f13/f11 );
458 //R = asin(f13);
459 if( f11<0 )
460 R+=M_PI;
462 double f22 = cos(x)*cos(z);
463 if( f22>0 )
464 E = 0.0;
465 else
466 E = M_PI;
468 else if( lcl_isCosZero(z) )
470 //cosY!=0 sinY!=0 sinX=0 cosZ=0
471 R = x;
472 E = y;//or -y
473 //use 23 for 'signs'
474 double f23 = -1.0*cos(x)*sin(y)*sin(z);
475 if( (f23*cos(R)*sin(E))<0.0 )
477 //change R or E
478 E = -y;
481 else
483 //cosY!=0 sinY!=0 sinX=0 sinZ!=0 cosZ!=0
484 double f13 = cos(x)*cos(z)*sin(y);
485 R = atan( f13/f11 );
487 if( f11<0 )
488 R+=M_PI;
490 double f21 = cos(y)*sin(z);
491 double f22 = cos(x)*cos(z);
492 E = atan(f21/(f22*sin(R)) );
494 if( (f22*cos(E))<0.0 )
495 E+=M_PI;
498 else if( lcl_isCosZero(x) )
500 //cosY!=0 sinY!=0 cosX=0
502 if( lcl_isSinZero(z) )
504 //cosY!=0 sinY!=0 cosX=0 sinZ=0
505 R=0;//13 -> R=0 or M_PI
506 if( f11<0.0 )
507 R=M_PI;
508 E=M_PI_2;//22 -> E=+-M_PI/2
509 //use element 11 and 23 for sign
510 double f23 = cos(z)*sin(x);
511 if( (f11*f23*sin(E))<0.0 )
512 E=-M_PI_2;
514 else if( lcl_isCosZero(z) )
516 //cosY!=0 sinY!=0 cosX=0 cosZ=0
517 //element 11 & 13:
518 if( (sin(x)*sin(z))>0.0 )
519 R=M_PI_2;
520 else
521 R=-M_PI_2;
522 //element 22:
523 E=acos( sin(x)*sin(y)*sin(z));
524 //use element 21 for sign:
525 if( (cos(y)*sin(z)*sin(R)*sin(E))<0.0 )
526 E*=-1.0;
528 else
530 //cosY!=0 sinY!=0 cosX=0 sinZ!=0 cosZ!=0
531 //element 13/11
532 R = atan( sin(x)*sin(z)/(cos(y)*cos(z)) );
533 //use 13 for 'sign'
534 if( (sin(x)*sin(z))<0.0 )
535 R += M_PI;
536 //element 22
537 E = acos(sin(x)*sin(y)*sin(z) );
538 //use 21 for sign
539 if( (cos(y)*sin(z)*sin(R)*sin(E))<0.0 )
540 E*=-1.0;
543 else if( lcl_isSinZero(z) )
545 //cosY!=0 sinY!=0 sinX!=0 cosX!=0 sinZ=0
546 //element 11
547 R=y;
548 //use element 13 for sign
549 if( (cos(x)*cos(z)*sin(y)*sin(R))<0.0 )
550 R*=-1.0;
551 //element 22
552 E = acos( cos(x)*cos(z) );
553 //use element 23 for sign
554 if( (cos(z)*sin(x)*cos(R)*sin(E))<0.0 )
555 E*=-1.0;
557 else if( lcl_isCosZero(z) )
559 //cosY!=0 sinY!=0 sinX!=0 cosX!=0 cosZ=0
560 //element 21/23
561 R=atan(-cos(y)/(cos(x)*sin(y)));
562 //use element 13 for 'sign'
563 if( (sin(x)*sin(z)*sin(R))<0.0 )
564 R+=M_PI;
565 //element 21/22
566 E=atan( cos(y)*sin(z)/(sin(R)*sin(x)*sin(y)*sin(z)) );
567 //use element 23 for 'sign'
568 if( (-cos(x)*sin(y)*sin(z)*cos(R)*sin(E))<0.0 )
569 E+=M_PI;
571 else
573 //cosY!=0 sinY!=0 sinX!=0 cosX!=0 sinZ!=0 cosZ!=0
574 //13/11:
575 double f13 = sin(x)*sin(z)+cos(x)*cos(z)*sin(y);
576 R = atan( f13/ f11 );
577 if(f11<0.0)
578 R+=M_PI;
579 double f22 = cos(x)*cos(z)+sin(x)*sin(y)*sin(z);
580 double f23 = cos(x)*sin(y)*sin(z)-cos(z)*sin(x);
581 //23/22:
582 E = atan( -1.0*f23/(f22*cos(R)) );
583 if(f22<0.0)
584 E+=M_PI;
587 rnElevationDeg = basegfx::fround(basegfx::rad2deg(E));
588 rnRotationDeg = basegfx::fround(basegfx::rad2deg(R));
591 double ThreeDHelper::getValueClippedToRange( double fAngle, const double& fPositivLimit )
593 if( fAngle<-1*fPositivLimit )
594 fAngle=-1*fPositivLimit;
595 else if( fAngle>fPositivLimit )
596 fAngle=fPositivLimit;
597 return fAngle;
600 void ThreeDHelper::adaptRadAnglesForRightAngledAxes( double& rfXAngleRad, double& rfYAngleRad )
602 rfXAngleRad = ThreeDHelper::getValueClippedToRange(rfXAngleRad, basegfx::deg2rad(ThreeDHelper::getXDegreeAngleLimitForRightAngledAxes()) );
603 rfYAngleRad = ThreeDHelper::getValueClippedToRange(rfYAngleRad, basegfx::deg2rad(ThreeDHelper::getYDegreeAngleLimitForRightAngledAxes()) );
607 void ThreeDHelper::getCameraDistanceRange( double& rfMinimumDistance, double& rfMaximumDistance )
609 rfMinimumDistance = 3.0/4.0*FIXED_SIZE_FOR_3D_CHART_VOLUME;//empiric value
610 rfMaximumDistance = 20.0*FIXED_SIZE_FOR_3D_CHART_VOLUME;//empiric value
613 void ThreeDHelper::ensureCameraDistanceRange( double& rfCameraDistance )
615 double fMin, fMax;
616 getCameraDistanceRange( fMin, fMax );
617 if( rfCameraDistance < fMin )
618 rfCameraDistance = fMin;
619 if( rfCameraDistance > fMax )
620 rfCameraDistance = fMax;
623 double ThreeDHelper::CameraDistanceToPerspective( double fCameraDistance )
625 double fMin, fMax;
626 ThreeDHelper::getCameraDistanceRange( fMin, fMax );
627 //fMax <-> 0; fMin <->100
628 //a/x + b = y
629 double a = 100.0*fMax*fMin/(fMax-fMin);
630 double b = -a/fMax;
632 double fRet = a/fCameraDistance + b;
634 return fRet;
637 double ThreeDHelper::PerspectiveToCameraDistance( double fPerspective )
639 double fMin, fMax;
640 ThreeDHelper::getCameraDistanceRange( fMin, fMax );
641 //fMax <-> 0; fMin <->100
642 //a/x + b = y
643 double a = 100.0*fMax*fMin/(fMax-fMin);
644 double b = -a/fMax;
646 double fRet = a/(fPerspective - b);
648 return fRet;
651 void ThreeDHelper::getRoundedEdgesAndObjectLines(
652 const rtl::Reference< Diagram > & xDiagram
653 , sal_Int32& rnRoundedEdges, sal_Int32& rnObjectLines )
655 rnRoundedEdges = -1;
656 rnObjectLines = -1;
659 bool bDifferentRoundedEdges = false;
660 bool bDifferentObjectLines = false;
662 drawing::LineStyle aLineStyle( drawing::LineStyle_SOLID );
664 std::vector< rtl::Reference< DataSeries > > aSeriesList =
665 xDiagram->getDataSeries();
666 sal_Int32 nSeriesCount = static_cast<sal_Int32>( aSeriesList.size() );
668 OUString aPercentDiagonalPropertyName( u"PercentDiagonal"_ustr );
669 OUString aBorderStylePropertyName( u"BorderStyle"_ustr );
671 for( sal_Int32 nS = 0; nS < nSeriesCount; ++nS )
673 const rtl::Reference< DataSeries >& xSeries( aSeriesList[nS] );
674 if(!nS)
676 rnRoundedEdges = 0;
679 sal_Int16 nPercentDiagonal = 0;
681 xSeries->getPropertyValue( aPercentDiagonalPropertyName ) >>= nPercentDiagonal;
682 rnRoundedEdges = static_cast< sal_Int32 >( nPercentDiagonal );
684 if( DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
685 , aPercentDiagonalPropertyName, uno::Any(nPercentDiagonal) ) )
686 bDifferentRoundedEdges = true;
688 catch( const uno::Exception& )
690 TOOLS_WARN_EXCEPTION("chart2", "" );
691 bDifferentRoundedEdges = true;
695 xSeries->getPropertyValue( aBorderStylePropertyName ) >>= aLineStyle;
697 if( DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
698 , aBorderStylePropertyName, uno::Any(aLineStyle) ) )
699 bDifferentObjectLines = true;
701 catch( const uno::Exception& )
703 TOOLS_WARN_EXCEPTION("chart2", "" );
704 bDifferentObjectLines = true;
707 else
709 if( !bDifferentRoundedEdges )
711 sal_Int16 nPercentDiagonal = 0;
712 xSeries->getPropertyValue( aPercentDiagonalPropertyName ) >>= nPercentDiagonal;
713 sal_Int32 nCurrentRoundedEdges = static_cast< sal_Int32 >( nPercentDiagonal );
714 if(nCurrentRoundedEdges!=rnRoundedEdges
715 || DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
716 , aPercentDiagonalPropertyName, uno::Any( static_cast< sal_Int16 >(rnRoundedEdges) ) ) )
718 bDifferentRoundedEdges = true;
722 if( !bDifferentObjectLines )
724 drawing::LineStyle aCurrentLineStyle;
725 xSeries->getPropertyValue( aBorderStylePropertyName ) >>= aCurrentLineStyle;
726 if(aCurrentLineStyle!=aLineStyle
727 || DataSeriesHelper::hasAttributedDataPointDifferentValue( xSeries
728 , aBorderStylePropertyName, uno::Any(aLineStyle) ) )
729 bDifferentObjectLines = true;
732 if( bDifferentRoundedEdges && bDifferentObjectLines )
733 break;
736 //set rnObjectLines
737 rnObjectLines = 0;
738 if( bDifferentObjectLines )
739 rnObjectLines = -1;
740 else if( aLineStyle == drawing::LineStyle_SOLID )
741 rnObjectLines = 1;
743 catch( const uno::Exception& )
745 TOOLS_WARN_EXCEPTION("chart2", "" );
749 void ThreeDHelper::setRoundedEdgesAndObjectLines(
750 const rtl::Reference< Diagram > & xDiagram
751 , sal_Int32 nRoundedEdges, sal_Int32 nObjectLines )
753 if( (nRoundedEdges<0||nRoundedEdges>100) && nObjectLines!=0 && nObjectLines!=1 )
754 return;
756 drawing::LineStyle aLineStyle( drawing::LineStyle_NONE );
757 if(nObjectLines==1)
758 aLineStyle = drawing::LineStyle_SOLID;
760 uno::Any aALineStyle( aLineStyle);
761 uno::Any aARoundedEdges( static_cast< sal_Int16 >( nRoundedEdges ));
763 std::vector< rtl::Reference< DataSeries > > aSeriesList =
764 xDiagram->getDataSeries();
765 for( auto const& xSeries : aSeriesList)
767 if( nRoundedEdges>=0 && nRoundedEdges<=100 )
768 DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, u"PercentDiagonal"_ustr, aARoundedEdges );
770 if( nObjectLines==0 || nObjectLines==1 )
771 DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, u"BorderStyle"_ustr, aALineStyle );
775 CuboidPlanePosition ThreeDHelper::getAutomaticCuboidPlanePositionForStandardLeftWall( const rtl::Reference< ::chart::Diagram >& xDiagram )
777 CuboidPlanePosition eRet(CuboidPlanePosition_Left);
779 double fXAngleRad=0.0; double fYAngleRad=0.0; double fZAngleRad=0.0;
780 xDiagram->getRotationAngle( fXAngleRad, fYAngleRad, fZAngleRad );
781 if( lcl_isRightAngledAxesSetAndSupported( xDiagram ) )
783 ThreeDHelper::adaptRadAnglesForRightAngledAxes( fXAngleRad, fYAngleRad );
785 if( sin(fYAngleRad)>0.0 )
786 eRet = CuboidPlanePosition_Right;
787 return eRet;
790 CuboidPlanePosition ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBackWall( const rtl::Reference< Diagram >& xDiagram )
792 CuboidPlanePosition eRet(CuboidPlanePosition_Back);
794 double fXAngleRad=0.0; double fYAngleRad=0.0; double fZAngleRad=0.0;
795 xDiagram->getRotationAngle( fXAngleRad, fYAngleRad, fZAngleRad );
796 if( lcl_isRightAngledAxesSetAndSupported( xDiagram ) )
798 ThreeDHelper::adaptRadAnglesForRightAngledAxes( fXAngleRad, fYAngleRad );
800 if( cos(fXAngleRad)*cos(fYAngleRad)<0.0 )
801 eRet = CuboidPlanePosition_Front;
802 return eRet;
805 CuboidPlanePosition ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBottom( const rtl::Reference< Diagram >& xDiagram )
807 CuboidPlanePosition eRet(CuboidPlanePosition_Bottom);
809 double fXAngleRad=0.0; double fYAngleRad=0.0; double fZAngleRad=0.0;
810 xDiagram->getRotationAngle( fXAngleRad, fYAngleRad, fZAngleRad );
811 if( lcl_isRightAngledAxesSetAndSupported( xDiagram ) )
813 ThreeDHelper::adaptRadAnglesForRightAngledAxes( fXAngleRad, fYAngleRad );
815 if( sin(fXAngleRad)*cos(fYAngleRad)<0.0 )
816 eRet = CuboidPlanePosition_Top;
817 return eRet;
820 } //namespace chart
822 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */