31#include <com/sun/star/drawing/LineStyle.hpp>
32#include <com/sun/star/drawing/ShadeMode.hpp>
35#include <rtl/math.hxx>
42using ::com::sun::star::uno::Reference;
43using ::rtl::math::cos;
44using ::rtl::math::sin;
45using ::rtl::math::tan;
54 bool bRightAngledAxes =
false;
55 xDiagram->getPropertyValue(
"RightAngledAxes") >>= bRightAngledAxes;
59 xDiagram->getChartTypeByIndex( 0 ) ) )
73 drawing::Position3D vrp(17634.6218373783, 10271.4823817647, 24594.8639082739);
75 drawing::Direction3D vpn(0.416199821709347, 0.173649045905254, 0.892537795986984);
78 drawing::Direction3D vup(-0.0733876362771618, 0.984807599917971, -0.157379306090273);
82 vrp = drawing::Position3D( 0.0, 0.0, 87591.2408759124 );
83 vpn = drawing::Direction3D( 0.0, 0.0, 1.0 );
84 vup = drawing::Direction3D( 0.0, 1.0, 0.0 );
87 return drawing::CameraGeometry( vrp, vpn, vup );
92void lcl_ensureIntervalMinus1To1(
double& rSinOrCos )
96 else if (rSinOrCos > 1.0)
100bool lcl_isSinZero(
double fAngleRad )
102 return ::basegfx::fTools::equalZero( sin(fAngleRad), 0.0000001 );
104bool lcl_isCosZero(
double fAngleRad )
106 return ::basegfx::fTools::equalZero( cos(fAngleRad), 0.0000001 );
112 sal_Int32 nElevationDeg, sal_Int32 nRotationDeg,
113 double& rfXAngleRad,
double& rfYAngleRad,
double& rfZAngleRad)
122 double&
x = rfXAngleRad;
123 double&
y = rfYAngleRad;
124 double&
z = rfZAngleRad;
129 if( (nRotationDeg == 0 || nRotationDeg == 180 )
130 && ( nElevationDeg == 90 || nElevationDeg == 270 ) )
135 double f23 = cos(
R)*sin(
E);
142 else if( ( nRotationDeg == 90 || nRotationDeg == 270 )
143 && ( nElevationDeg == 90 || nElevationDeg == 270 ) )
152 if( (sin(
R)*sin(
E))>0 )
157 else if( (nRotationDeg == 0 || nRotationDeg == 180 )
158 && ( nElevationDeg == 0 || nElevationDeg == 180 ) )
165 else if( ( nRotationDeg == 90 || nRotationDeg == 270 )
166 && ( nElevationDeg == 0 || nElevationDeg == 180 ) )
171 if( (sin(
R)/cos(
E))>0 )
181 else if ( nElevationDeg == 0 || nElevationDeg == 180 )
188 if((cos(
x)*sin(
y)*sin(
R))<0.0)
191 else if ( nElevationDeg == 90 || nElevationDeg == 270 )
196 z = atan(sin(
R)/(cos(
R)*sin(
E)));
198 if( (sin(
R)*sin(
z))>0.0 )
203 if( (sin(
R)*sin(
E)*sin(
z))>0.0)
208 else if ( nRotationDeg == 0 || nRotationDeg == 180 )
214 double f23 = cos(
R)*sin(
E);
215 if( (f23 * sin(
x)) < 0.0 )
218 else if (nRotationDeg == 90 || nRotationDeg == 270)
230 double cy = sR*sin(
E)/sin(
z);
231 lcl_ensureIntervalMinus1To1(cy);
235 if( (sin(
x)*sin(
y)*sin(
z)*cos(
E))<0.0)
240 z = atan(tan(
R) * sin(
E));
243 OSL_FAIL(
"calculation error in ThreeDHelper::convertElevationRotationDegToXYZAngleRad");
246 double cy = cos(
R)/cos(
z);
247 lcl_ensureIntervalMinus1To1(cy);
251 double fDenominator = cos(
z)*(1.0-pow(sin(
y),2));
252 if(fDenominator==0.0)
254 OSL_FAIL(
"calculation error in ThreeDHelper::convertElevationRotationDegToXYZAngleRad");
257 double sx = cos(
R)*sin(
E)/fDenominator;
258 lcl_ensureIntervalMinus1To1(sx);
262 double f13a = cos(
x)*cos(
z)*sin(
y);
263 double f13b = sin(
R)-sx*sin(
z);
264 if( (f13b*f13a)<0.0 )
270 double f22a = cos(
x)*cos(
z);
271 double f22b = cos(
E)-(sx*sin(
y)*sin(
z));
272 if( (f22a*f22b)<0.0 )
282 double f22a = cos(
x)*cos(
z);
283 double f22b = cos(
E)-(sx*sin(
y)*sin(
z));
284 if( (f22a*f22b)<0.0 )
294 sal_Int32& rnElevationDeg, sal_Int32& rnRotationDeg,
295 double fXRad,
double fYRad,
double fZRad)
308 double f11 = cos(
y)*cos(
z);
310 if( lcl_isSinZero(
y) )
314 if( lcl_isCosZero(
x) )
318 if( lcl_isSinZero(
z) )
330 double f23 = cos(
z)*sin(
x) / cos(
R);
336 else if( lcl_isCosZero(
z) )
341 double f13 = sin(
x)*sin(
z);
349 double f21 = cos(
y)*sin(
z) / sin(
R);
359 double f13 = sin(
x)*sin(
z);
366 double f23 = cos(
z)*sin(
x);
373 else if( lcl_isSinZero(
x) )
382 double f22 = cos(
x)*cos(
z);
388 else if( lcl_isSinZero(
z) )
398 double f22 = cos(
x)*cos(
z);
399 double f23 = cos(
z)*sin(
x);
400 E = atan( f23/(f22*cos(
R)) );
404 else if( lcl_isCosZero(
z) )
407 double f13 = sin(
x)*sin(
z);
415 double f21 = cos(
y)*sin(
z);
424 double f13 = sin(
x)*sin(
z);
426 if( (f11*cos(
R))<0.0 )
429 double f22 = cos(
x)*cos(
z);
430 if( !lcl_isCosZero(
R) )
431 E = atan( cos(
z)*sin(
x) /( f22*cos(
R) ) );
433 E = atan( cos(
y)*sin(
z) /( f22*sin(
R) ) );
438 else if( lcl_isCosZero(
y) )
442 double f13 = sin(
x)*sin(
z)+cos(
x)*cos(
z)*sin(
y);
448 double f22 = cos(
x)*cos(
z)+sin(
x)*sin(
y)*sin(
z);
454 else if( lcl_isSinZero(
x) )
457 if( lcl_isSinZero(
z) )
460 double f13 = cos(
x)*cos(
z)*sin(
y);
466 double f22 = cos(
x)*cos(
z);
472 else if( lcl_isCosZero(
z) )
478 double f23 = -1.0*cos(
x)*sin(
y)*sin(
z);
479 if( (f23*cos(
R)*sin(
E))<0.0 )
488 double f13 = cos(
x)*cos(
z)*sin(
y);
494 double f21 = cos(
y)*sin(
z);
495 double f22 = cos(
x)*cos(
z);
496 E = atan(f21/(f22*sin(
R)) );
498 if( (f22*cos(
E))<0.0 )
502 else if( lcl_isCosZero(
x) )
506 if( lcl_isSinZero(
z) )
514 double f23 = cos(
z)*sin(
x);
515 if( (f11*f23*sin(
E))<0.0 )
518 else if( lcl_isCosZero(
z) )
522 if( (sin(
x)*sin(
z))>0.0 )
527 E=acos( sin(
x)*sin(
y)*sin(
z));
529 if( (cos(
y)*sin(
z)*sin(
R)*sin(
E))<0.0 )
536 R = atan( sin(
x)*sin(
z)/(cos(
y)*cos(
z)) );
538 if( (sin(
x)*sin(
z))<0.0 )
541 E = acos(sin(
x)*sin(
y)*sin(
z) );
543 if( (cos(
y)*sin(
z)*sin(
R)*sin(
E))<0.0 )
547 else if( lcl_isSinZero(
z) )
553 if( (cos(
x)*cos(
z)*sin(
y)*sin(
R))<0.0 )
556 E = acos( cos(
x)*cos(
z) );
558 if( (cos(
z)*sin(
x)*cos(
R)*sin(
E))<0.0 )
561 else if( lcl_isCosZero(
z) )
565 R=atan(-cos(
y)/(cos(
x)*sin(
y)));
567 if( (sin(
x)*sin(
z)*sin(
R))<0.0 )
570 E=atan( cos(
y)*sin(
z)/(sin(
R)*sin(
x)*sin(
y)*sin(
z)) );
572 if( (-cos(
x)*sin(
y)*sin(
z)*cos(
R)*sin(
E))<0.0 )
579 double f13 = sin(
x)*sin(
z)+cos(
x)*cos(
z)*sin(
y);
580 R = atan( f13/ f11 );
583 double f22 = cos(
x)*cos(
z)+sin(
x)*sin(
y)*sin(
z);
584 double f23 = cos(
x)*sin(
y)*sin(
z)-cos(
z)*sin(
x);
586 E = atan( -1.0*f23/(f22*cos(
R)) );
597 if( fAngle<-1*fPositivLimit )
598 fAngle=-1*fPositivLimit;
599 else if( fAngle>fPositivLimit )
600 fAngle=fPositivLimit;
621 if( rfCameraDistance < fMin )
622 rfCameraDistance = fMin;
623 if( rfCameraDistance > fMax )
624 rfCameraDistance = fMax;
633 double a = 100.0*fMax*fMin/(fMax-fMin);
636 double fRet =
a/fCameraDistance + b;
647 double a = 100.0*fMax*fMin/(fMax-fMin);
650 double fRet =
a/(fPerspective - b);
657 , sal_Int32& rnRoundedEdges, sal_Int32& rnObjectLines )
663 bool bDifferentRoundedEdges =
false;
664 bool bDifferentObjectLines =
false;
666 drawing::LineStyle aLineStyle( drawing::LineStyle_SOLID );
668 std::vector< rtl::Reference< DataSeries > > aSeriesList =
669 xDiagram->getDataSeries();
670 sal_Int32 nSeriesCount =
static_cast<sal_Int32
>( aSeriesList.size() );
672 OUString aPercentDiagonalPropertyName(
"PercentDiagonal" );
673 OUString aBorderStylePropertyName(
"BorderStyle" );
675 for( sal_Int32 nS = 0; nS < nSeriesCount; ++nS )
683 sal_Int16 nPercentDiagonal = 0;
685 xSeries->getPropertyValue( aPercentDiagonalPropertyName ) >>= nPercentDiagonal;
686 rnRoundedEdges =
static_cast< sal_Int32
>( nPercentDiagonal );
689 , aPercentDiagonalPropertyName,
uno::Any(nPercentDiagonal) ) )
690 bDifferentRoundedEdges =
true;
692 catch(
const uno::Exception& )
695 bDifferentRoundedEdges =
true;
699 xSeries->getPropertyValue( aBorderStylePropertyName ) >>= aLineStyle;
702 , aBorderStylePropertyName,
uno::Any(aLineStyle) ) )
703 bDifferentObjectLines =
true;
705 catch(
const uno::Exception& )
708 bDifferentObjectLines =
true;
713 if( !bDifferentRoundedEdges )
715 sal_Int16 nPercentDiagonal = 0;
716 xSeries->getPropertyValue( aPercentDiagonalPropertyName ) >>= nPercentDiagonal;
717 sal_Int32 nCurrentRoundedEdges =
static_cast< sal_Int32
>( nPercentDiagonal );
718 if(nCurrentRoundedEdges!=rnRoundedEdges
720 , aPercentDiagonalPropertyName,
uno::Any(
static_cast< sal_Int16
>(rnRoundedEdges) ) ) )
722 bDifferentRoundedEdges =
true;
726 if( !bDifferentObjectLines )
728 drawing::LineStyle aCurrentLineStyle;
729 xSeries->getPropertyValue( aBorderStylePropertyName ) >>= aCurrentLineStyle;
730 if(aCurrentLineStyle!=aLineStyle
732 , aBorderStylePropertyName,
uno::Any(aLineStyle) ) )
733 bDifferentObjectLines =
true;
736 if( bDifferentRoundedEdges && bDifferentObjectLines )
742 if( bDifferentObjectLines )
744 else if( aLineStyle == drawing::LineStyle_SOLID )
747 catch(
const uno::Exception& )
755 , sal_Int32 nRoundedEdges, sal_Int32 nObjectLines )
757 if( (nRoundedEdges<0||nRoundedEdges>100) && nObjectLines!=0 && nObjectLines!=1 )
760 drawing::LineStyle aLineStyle( drawing::LineStyle_NONE );
762 aLineStyle = drawing::LineStyle_SOLID;
765 uno::Any aARoundedEdges(
static_cast< sal_Int16
>( nRoundedEdges ));
767 std::vector< rtl::Reference< DataSeries > > aSeriesList =
768 xDiagram->getDataSeries();
769 for(
auto const& xSeries : aSeriesList)
771 if( nRoundedEdges>=0 && nRoundedEdges<=100 )
774 if( nObjectLines==0 || nObjectLines==1 )
783 double fXAngleRad=0.0;
double fYAngleRad=0.0;
double fZAngleRad=0.0;
784 xDiagram->getRotationAngle( fXAngleRad, fYAngleRad, fZAngleRad );
789 if( sin(fYAngleRad)>0.0 )
798 double fXAngleRad=0.0;
double fYAngleRad=0.0;
double fZAngleRad=0.0;
799 xDiagram->getRotationAngle( fXAngleRad, fYAngleRad, fZAngleRad );
804 if( cos(fXAngleRad)*cos(fYAngleRad)<0.0 )
813 double fXAngleRad=0.0;
double fYAngleRad=0.0;
double fZAngleRad=0.0;
814 xDiagram->getRotationAngle( fXAngleRad, fYAngleRad, fZAngleRad );
819 if( sin(fXAngleRad)*cos(fYAngleRad)<0.0 )
static bool isSupportingRightAngledAxes(const rtl::Reference< ::chart::ChartType > &xChartType)
static SAL_DLLPRIVATE void getCameraDistanceRange(double &rfMinimumDistance, double &rfMaximumDistance)
static void setRoundedEdgesAndObjectLines(const rtl::Reference< ::chart::Diagram > &xDiagram, sal_Int32 nRoundedEdges, sal_Int32 nObjectLines)
static double getValueClippedToRange(double fValue, const double &fPositivLimit)
static void getRoundedEdgesAndObjectLines(const rtl::Reference< ::chart::Diagram > &xDiagram, sal_Int32 &rnRoundedEdges, sal_Int32 &rnObjectLines)
static css::drawing::CameraGeometry getDefaultCameraGeometry(bool bPie=false)
Returns the default camera geometry that is set in the Diagram CTOR.
static void adaptRadAnglesForRightAngledAxes(double &rfXAngleRad, double &rfYAngleRad)
static double getYDegreeAngleLimitForRightAngledAxes()
static double CameraDistanceToPerspective(double fCameraDistance)
static CuboidPlanePosition getAutomaticCuboidPlanePositionForStandardBackWall(const rtl::Reference< ::chart::Diagram > &xDiagram)
static double PerspectiveToCameraDistance(double fPerspective)
static SAL_DLLPRIVATE void convertXYZAngleRadToElevationRotationDeg(sal_Int32 &rnElevationDeg, sal_Int32 &rnRotationDeg, double fXRad, double fYRad, double fZRad)
static double getXDegreeAngleLimitForRightAngledAxes()
static CuboidPlanePosition getAutomaticCuboidPlanePositionForStandardLeftWall(const rtl::Reference< ::chart::Diagram > &xDiagram)
static CuboidPlanePosition getAutomaticCuboidPlanePositionForStandardBottom(const rtl::Reference< ::chart::Diagram > &xDiagram)
static void convertElevationRotationDegToXYZAngleRad(sal_Int32 nElevationDeg, sal_Int32 nRotationDeg, double &rfXAngleRad, double &rfYAngleRad, double &rfZAngleRad)
static SAL_DLLPRIVATE void ensureCameraDistanceRange(double &rfCameraDistance)
constexpr double FIXED_SIZE_FOR_3D_CHART_VOLUME
#define TOOLS_WARN_EXCEPTION(area, stream)
constexpr double rad2deg(double v)
B2IRange fround(const B2DRange &rRange)
constexpr double deg2rad(double v)
OOO_DLLPUBLIC_CHARTTOOLS void setPropertyAlsoToAllAttributedDataPoints(const rtl::Reference< ::chart::DataSeries > &xSeries, const OUString &rPropertyName, const css::uno::Any &rPropertyValue)
OOO_DLLPUBLIC_CHARTTOOLS bool hasAttributedDataPointDifferentValue(const rtl::Reference< ::chart::DataSeries > &xSeries, const OUString &rPropertyName, const css::uno::Any &rPropertyValue)
static bool lcl_isRightAngledAxesSetAndSupported(Diagram &rDiagram)
@ CuboidPlanePosition_Left
@ CuboidPlanePosition_Back
@ CuboidPlanePosition_Right
@ CuboidPlanePosition_Front
@ CuboidPlanePosition_Top
@ CuboidPlanePosition_Bottom