1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: PlottingPositionHelper.hxx,v $
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 ************************************************************************/
30 #ifndef _CHART2_PLOTTINGPOSITIONHELPER_HXX
31 #define _CHART2_PLOTTINGPOSITIONHELPER_HXX
33 #include "LabelAlignment.hxx"
34 #include <basegfx/range/b2drectangle.hxx>
35 #include <rtl/math.hxx>
36 #include <com/sun/star/chart2/ExplicitScaleData.hpp>
37 #include <com/sun/star/chart2/XTransformation.hpp>
38 #include <com/sun/star/drawing/Direction3D.hpp>
39 #include <com/sun/star/drawing/HomogenMatrix.hpp>
40 #include <com/sun/star/drawing/PolyPolygonShape3D.hpp>
41 #include <com/sun/star/drawing/Position3D.hpp>
42 #include <com/sun/star/drawing/XShapes.hpp>
43 #include <basegfx/matrix/b3dhommatrix.hxx>
47 #include <cppuhelper/implbase1.hxx>
49 //.............................................................................
52 //.............................................................................
56 //-----------------------------------------------------------------------------
60 class PlottingPositionHelper
63 PlottingPositionHelper();
64 PlottingPositionHelper( const PlottingPositionHelper
& rSource
);
65 virtual ~PlottingPositionHelper();
67 virtual PlottingPositionHelper
* clone() const;
68 virtual PlottingPositionHelper
* createSecondaryPosHelper( const ::com::sun::star::chart2::ExplicitScaleData
& rSecondaryScale
);
70 virtual void setTransformationSceneToScreen( const ::com::sun::star::drawing::HomogenMatrix
& rMatrix
);
72 virtual void setScales( const ::com::sun::star::uno::Sequence
<
73 ::com::sun::star::chart2::ExplicitScaleData
>& rScales
74 , sal_Bool bSwapXAndYAxis
);
75 const ::com::sun::star::uno::Sequence
<
76 ::com::sun::star::chart2::ExplicitScaleData
>& getScales() const;
78 //better performance for big data
79 inline void setCoordinateSystemResolution( const ::com::sun::star::uno::Sequence
< sal_Int32
>& rCoordinateSystemResolution
);
80 inline bool isSameForGivenResolution( double fX
, double fY
, double fZ
81 , double fX2
, double fY2
, double fZ2
);
83 inline bool isLogicVisible( double fX
, double fY
, double fZ
) const;
84 inline void doLogicScaling( double* pX
, double* pY
, double* pZ
, bool bClip
=false ) const;
85 inline void clipLogicValues( double* pX
, double* pY
, double* pZ
) const;
86 void clipScaledLogicValues( double* pX
, double* pY
, double* pZ
) const;
87 inline bool clipYRange( double& rMin
, double& rMax
) const;
89 inline void doLogicScaling( ::com::sun::star::drawing::Position3D
& rPos
, bool bClip
=false ) const;
91 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::chart2::XTransformation
>
92 getTransformationScaledLogicToScene() const;
94 virtual ::com::sun::star::drawing::Position3D
95 transformLogicToScene( double fX
, double fY
, double fZ
, bool bClip
) const;
97 virtual ::com::sun::star::drawing::Position3D
98 transformScaledLogicToScene( double fX
, double fY
, double fZ
, bool bClip
) const;
100 void transformScaledLogicToScene( ::com::sun::star::drawing::PolyPolygonShape3D
& rPoly
) const;
102 static com::sun::star::awt::Point
transformSceneToScreenPosition(
103 const com::sun::star::drawing::Position3D
& rScenePosition3D
104 , const com::sun::star::uno::Reference
< com::sun::star::drawing::XShapes
>& xSceneTarget
105 , ShapeFactory
* pShapeFactory
, sal_Int32 nDimensionCount
);
107 inline double getLogicMinX() const;
108 inline double getLogicMinY() const;
109 inline double getLogicMinZ() const;
110 inline double getLogicMaxX() const;
111 inline double getLogicMaxY() const;
112 inline double getLogicMaxZ() const;
114 inline bool isMathematicalOrientationX() const;
115 inline bool isMathematicalOrientationY() const;
116 inline bool isMathematicalOrientationZ() const;
118 ::basegfx::B2DRectangle
getScaledLogicClipDoubleRect() const;
119 ::com::sun::star::drawing::Direction3D
getScaledLogicWidth() const;
121 inline bool isSwapXAndY() const;
123 bool isPercentY() const;
125 double getBaseValueY() const;
127 inline bool maySkipPointsInRegressionCalculation() const;
130 ::com::sun::star::uno::Sequence
<
131 ::com::sun::star::chart2::ExplicitScaleData
> m_aScales
;
132 ::basegfx::B3DHomMatrix m_aMatrixScreenToScene
;
134 //this is calculated based on m_aScales and m_aMatrixScreenToScene
135 mutable ::com::sun::star::uno::Reference
<
136 ::com::sun::star::chart2::XTransformation
> m_xTransformationLogicToScene
;
138 bool m_bSwapXAndY
;//e.g. true for bar chart and false for column chart
140 sal_Int32 m_nXResolution
;
141 sal_Int32 m_nYResolution
;
142 sal_Int32 m_nZResolution
;
144 bool m_bMaySkipPointsInRegressionCalculation
;
147 //describes wich axis of the drawinglayer scene or sreen axis are the normal axis
155 class PolarPlottingPositionHelper
: public PlottingPositionHelper
157 , public ::cppu::WeakImplHelper1<
158 ::com::sun::star::chart2::XTransformation >
162 PolarPlottingPositionHelper( NormalAxis eNormalAxis
=NormalAxis_Z
);
163 PolarPlottingPositionHelper( const PolarPlottingPositionHelper
& rSource
);
164 virtual ~PolarPlottingPositionHelper();
166 virtual PlottingPositionHelper
* clone() const;
168 virtual void setTransformationSceneToScreen( const ::com::sun::star::drawing::HomogenMatrix
& rMatrix
);
169 virtual void setScales( const ::com::sun::star::uno::Sequence
<
170 ::com::sun::star::chart2::ExplicitScaleData
>& rScales
171 , sal_Bool bSwapXAndYAxis
);
173 ::basegfx::B3DHomMatrix
getUnitCartesianToScene() const;
175 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::chart2::XTransformation
>
176 getTransformationScaledLogicToScene() const;
178 //the resulting values should be used for input to the transformation
179 //received with 'getTransformationScaledLogicToScene'
180 double transformToRadius( double fLogicValueOnRadiusAxis
, bool bDoScaling
=true ) const;
181 double transformToAngleDegree( double fLogicValueOnAngleAxis
, bool bDoScaling
=true ) const;
182 double getWidthAngleDegree( double& fStartLogicValueOnAngleAxis
, double& fEndLogicValueOnAngleAxis
) const;
185 virtual ::com::sun::star::drawing::Position3D
186 transformLogicToScene( double fX
, double fY
, double fZ
, bool bClip
) const;
187 virtual ::com::sun::star::drawing::Position3D
188 transformScaledLogicToScene( double fX
, double fY
, double fZ
, bool bClip
) const;
189 ::com::sun::star::drawing::Position3D
190 transformAngleRadiusToScene( double fLogicValueOnAngleAxis
, double fLogicValueOnRadiusAxis
, double fLogicZ
, bool bDoScaling
=true ) const;
191 ::com::sun::star::drawing::Position3D
192 transformUnitCircleToScene( double fUnitAngleDegree
, double fUnitRadius
, double fLogicZ
, bool bDoScaling
=true ) const;
194 using PlottingPositionHelper::transformScaledLogicToScene
;
197 double getInnerLogicRadius() const;
199 double getOuterLogicRadius() const;
201 inline bool isMathematicalOrientationAngle() const;
202 inline bool isMathematicalOrientationRadius() const;
205 // ____ XTransformation ____
206 /// @see ::com::sun::star::chart2::XTransformation
207 virtual ::com::sun::star::uno::Sequence< double > SAL_CALL transform(
208 const ::com::sun::star::uno::Sequence< double >& rSourceValues )
209 throw (::com::sun::star::lang::IllegalArgumentException,
210 ::com::sun::star::uno::RuntimeException);
211 /// @see ::com::sun::star::chart2::XTransformation
212 virtual sal_Int32 SAL_CALL getSourceDimension()
213 throw (::com::sun::star::uno::RuntimeException);
214 /// @see ::com::sun::star::chart2::XTransformation
215 virtual sal_Int32 SAL_CALL getTargetDimension()
216 throw (::com::sun::star::uno::RuntimeException);
219 //Offset for radius axis in absolute logic scaled values (1.0 == 1 category)
220 double m_fRadiusOffset
;
221 //Offset for angle axis in real degree
222 double m_fAngleDegreeOffset
;
225 ::basegfx::B3DHomMatrix m_aUnitCartesianToScene
;
226 NormalAxis m_eNormalAxis
;
228 ::basegfx::B3DHomMatrix
impl_calculateMatrixUnitCartesianToScene( const ::basegfx::B3DHomMatrix
& rMatrixScreenToScene
) const;
231 bool PolarPlottingPositionHelper::isMathematicalOrientationAngle() const
233 const ::com::sun::star::chart2::ExplicitScaleData
& rScale
= m_bSwapXAndY
? m_aScales
[1] : m_aScales
[2];
234 if( ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL
==rScale
.Orientation
)
238 bool PolarPlottingPositionHelper::isMathematicalOrientationRadius() const
240 const ::com::sun::star::chart2::ExplicitScaleData
& rScale
= m_bSwapXAndY
? m_aScales
[0] : m_aScales
[1];
241 if( ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL
==rScale
.Orientation
)
246 //better performance for big data
247 void PlottingPositionHelper::setCoordinateSystemResolution( const ::com::sun::star::uno::Sequence
< sal_Int32
>& rCoordinateSystemResolution
)
249 m_nXResolution
= 1000;
250 m_nYResolution
= 1000;
251 m_nZResolution
= 1000;
252 if( rCoordinateSystemResolution
.getLength() > 0 )
253 m_nXResolution
= rCoordinateSystemResolution
[0];
254 if( rCoordinateSystemResolution
.getLength() > 1 )
255 m_nYResolution
= rCoordinateSystemResolution
[1];
256 if( rCoordinateSystemResolution
.getLength() > 2 )
257 m_nZResolution
= rCoordinateSystemResolution
[2];
260 bool PlottingPositionHelper::isSameForGivenResolution( double fX
, double fY
, double fZ
261 , double fX2
, double fY2
, double fZ2
/*these values are all expected tp be scaled already*/ )
263 if( !::rtl::math::isFinite(fX
) || !::rtl::math::isFinite(fY
) || !::rtl::math::isFinite(fZ
)
264 || !::rtl::math::isFinite(fX2
) || !::rtl::math::isFinite(fY2
) || !::rtl::math::isFinite(fZ2
) )
267 double fScaledMinX
= getLogicMinX();
268 double fScaledMinY
= getLogicMinY();
269 double fScaledMinZ
= getLogicMinZ();
270 double fScaledMaxX
= getLogicMaxX();
271 double fScaledMaxY
= getLogicMaxY();
272 double fScaledMaxZ
= getLogicMaxZ();
274 doLogicScaling( &fScaledMinX
, &fScaledMinY
, &fScaledMinZ
);
275 doLogicScaling( &fScaledMaxX
, &fScaledMaxY
, &fScaledMaxZ
);
277 bool bSameX
= ( static_cast<sal_Int32
>(m_nXResolution
*(fX
- fScaledMinX
)/(fScaledMaxX
-fScaledMinX
))
278 == static_cast<sal_Int32
>(m_nXResolution
*(fX2
- fScaledMinX
)/(fScaledMaxX
-fScaledMinX
)) );
280 bool bSameY
= ( static_cast<sal_Int32
>(m_nYResolution
*(fY
- fScaledMinY
)/(fScaledMaxY
-fScaledMinY
))
281 == static_cast<sal_Int32
>(m_nYResolution
*(fY2
- fScaledMinY
)/(fScaledMaxY
-fScaledMinY
)) );
283 bool bSameZ
= ( static_cast<sal_Int32
>(m_nZResolution
*(fZ
- fScaledMinZ
)/(fScaledMaxZ
-fScaledMinZ
))
284 == static_cast<sal_Int32
>(m_nZResolution
*(fZ2
- fScaledMinZ
)/(fScaledMaxZ
-fScaledMinZ
)) );
286 return (bSameX
&& bSameY
&& bSameZ
);
289 bool PlottingPositionHelper::isLogicVisible(
290 double fX
, double fY
, double fZ
) const
292 return fX
>= m_aScales
[0].Minimum
&& fX
<= m_aScales
[0].Maximum
293 && fY
>= m_aScales
[1].Minimum
&& fY
<= m_aScales
[1].Maximum
294 && fZ
>= m_aScales
[2].Minimum
&& fZ
<= m_aScales
[2].Maximum
;
297 void PlottingPositionHelper::doLogicScaling( double* pX
, double* pY
, double* pZ
, bool bClip
) const
300 this->clipLogicValues( pX
,pY
,pZ
);
302 if(pX
&& m_aScales
[0].Scaling
.is())
303 *pX
= m_aScales
[0].Scaling
->doScaling(*pX
);
304 if(pY
&& m_aScales
[1].Scaling
.is())
305 *pY
= m_aScales
[1].Scaling
->doScaling(*pY
);
306 if(pZ
&& m_aScales
[2].Scaling
.is())
307 *pZ
= m_aScales
[2].Scaling
->doScaling(*pZ
);
310 void PlottingPositionHelper::doLogicScaling( ::com::sun::star::drawing::Position3D
& rPos
, bool bClip
) const
312 doLogicScaling( &rPos
.PositionX
, &rPos
.PositionY
, &rPos
.PositionZ
, bClip
);
315 void PlottingPositionHelper::clipLogicValues( double* pX
, double* pY
, double* pZ
) const
319 if( *pX
< m_aScales
[0].Minimum
)
320 *pX
= m_aScales
[0].Minimum
;
321 else if( *pX
> m_aScales
[0].Maximum
)
322 *pX
= m_aScales
[0].Maximum
;
326 if( *pY
< m_aScales
[1].Minimum
)
327 *pY
= m_aScales
[1].Minimum
;
328 else if( *pY
> m_aScales
[1].Maximum
)
329 *pY
= m_aScales
[1].Maximum
;
333 if( *pZ
< m_aScales
[2].Minimum
)
334 *pZ
= m_aScales
[2].Minimum
;
335 else if( *pZ
> m_aScales
[2].Maximum
)
336 *pZ
= m_aScales
[2].Maximum
;
340 inline bool PlottingPositionHelper::clipYRange( double& rMin
, double& rMax
) const
342 //returns true if something remains
349 if( rMin
> getLogicMaxY() )
351 if( rMax
< getLogicMinY() )
353 if( rMin
< getLogicMinY() )
354 rMin
= getLogicMinY();
355 if( rMax
> getLogicMaxY() )
356 rMax
= getLogicMaxY();
360 inline double PlottingPositionHelper::getLogicMinX() const
362 return m_aScales
[0].Minimum
;
364 inline double PlottingPositionHelper::getLogicMinY() const
366 return m_aScales
[1].Minimum
;
368 inline double PlottingPositionHelper::getLogicMinZ() const
370 return m_aScales
[2].Minimum
;
373 inline double PlottingPositionHelper::getLogicMaxX() const
375 return m_aScales
[0].Maximum
;
377 inline double PlottingPositionHelper::getLogicMaxY() const
379 return m_aScales
[1].Maximum
;
381 inline double PlottingPositionHelper::getLogicMaxZ() const
383 return m_aScales
[2].Maximum
;
385 inline bool PlottingPositionHelper::isMathematicalOrientationX() const
387 return ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL
== m_aScales
[0].Orientation
;
389 inline bool PlottingPositionHelper::isMathematicalOrientationY() const
391 return ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL
== m_aScales
[1].Orientation
;
393 inline bool PlottingPositionHelper::isMathematicalOrientationZ() const
395 return ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL
== m_aScales
[2].Orientation
;
397 inline bool PlottingPositionHelper::isSwapXAndY() const
401 inline bool PlottingPositionHelper::maySkipPointsInRegressionCalculation() const
403 return m_bMaySkipPointsInRegressionCalculation
;
406 //.............................................................................
408 //.............................................................................