Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
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/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
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 .
18 : : */
19 : :
20 : : #include "PlottingPositionHelper.hxx"
21 : : #include "CommonConverters.hxx"
22 : : #include "ViewDefines.hxx"
23 : : #include "Linear3DTransformation.hxx"
24 : : #include "VPolarTransformation.hxx"
25 : : #include "ShapeFactory.hxx"
26 : : #include "PropertyMapper.hxx"
27 : : #include "DateHelper.hxx"
28 : :
29 : : #include <com/sun/star/chart/TimeUnit.hpp>
30 : : #include <com/sun/star/chart2/AxisType.hpp>
31 : : #include <com/sun/star/drawing/DoubleSequence.hpp>
32 : : #include <com/sun/star/drawing/Position3D.hpp>
33 : :
34 : : #include <rtl/math.hxx>
35 : :
36 : : //.............................................................................
37 : : namespace chart
38 : : {
39 : : //.............................................................................
40 : : using namespace ::com::sun::star;
41 : : using namespace ::com::sun::star::chart2;
42 : :
43 : 4857 : PlottingPositionHelper::PlottingPositionHelper()
44 : : : m_aScales()
45 : : , m_aMatrixScreenToScene()
46 : : , m_xTransformationLogicToScene(NULL)
47 : : , m_bSwapXAndY( false )
48 : : , m_nXResolution( 1000 )
49 : : , m_nYResolution( 1000 )
50 : : , m_nZResolution( 1000 )
51 : : , m_bMaySkipPointsInRegressionCalculation( true )
52 : : , m_bDateAxis(false)
53 : : , m_nTimeResolution( ::com::sun::star::chart::TimeUnit::DAY )
54 : : , m_aNullDate(30,12,1899)
55 : : , m_fScaledCategoryWidth(1.0)
56 : : , m_bAllowShiftXAxisPos(false)
57 [ + - ][ + - ]: 4857 : , m_bAllowShiftZAxisPos(false)
58 : : {
59 : 4857 : }
60 : 0 : PlottingPositionHelper::PlottingPositionHelper( const PlottingPositionHelper& rSource )
61 : : : m_aScales( rSource.m_aScales )
62 : : , m_aMatrixScreenToScene( rSource.m_aMatrixScreenToScene )
63 : : , m_xTransformationLogicToScene( NULL ) //should be recalculated
64 : : , m_bSwapXAndY( rSource.m_bSwapXAndY )
65 : : , m_nXResolution( rSource.m_nXResolution )
66 : : , m_nYResolution( rSource.m_nYResolution )
67 : : , m_nZResolution( rSource.m_nZResolution )
68 : : , m_bMaySkipPointsInRegressionCalculation( rSource.m_bMaySkipPointsInRegressionCalculation )
69 : : , m_bDateAxis( rSource.m_bDateAxis )
70 : : , m_nTimeResolution( rSource.m_nTimeResolution )
71 : : , m_aNullDate( rSource.m_aNullDate )
72 : : , m_fScaledCategoryWidth( rSource.m_fScaledCategoryWidth )
73 : : , m_bAllowShiftXAxisPos( rSource.m_bAllowShiftXAxisPos )
74 [ # # ][ # # ]: 0 : , m_bAllowShiftZAxisPos( rSource.m_bAllowShiftZAxisPos )
75 : : {
76 : 0 : }
77 : :
78 [ + - ]: 4857 : PlottingPositionHelper::~PlottingPositionHelper()
79 : : {
80 : :
81 [ - + ]: 8805 : }
82 : :
83 : 0 : PlottingPositionHelper* PlottingPositionHelper::clone() const
84 : : {
85 [ # # ]: 0 : PlottingPositionHelper* pRet = new PlottingPositionHelper(*this);
86 : 0 : return pRet;
87 : : }
88 : :
89 : 0 : PlottingPositionHelper* PlottingPositionHelper::createSecondaryPosHelper( const ExplicitScaleData& rSecondaryScale )
90 : : {
91 : 0 : PlottingPositionHelper* pRet = this->clone();
92 : 0 : pRet->m_aScales[1]=rSecondaryScale;
93 : 0 : return pRet;
94 : : }
95 : :
96 : 21106 : void PlottingPositionHelper::setTransformationSceneToScreen( const drawing::HomogenMatrix& rMatrix)
97 : : {
98 [ + - ]: 21106 : m_aMatrixScreenToScene = HomogenMatrixToB3DHomMatrix(rMatrix);
99 : 21106 : m_xTransformationLogicToScene = NULL;
100 : 21106 : }
101 : :
102 : 7757 : void PlottingPositionHelper::setScales( const std::vector< ExplicitScaleData >& rScales, bool bSwapXAndYAxis )
103 : : {
104 : 7757 : m_aScales = rScales;
105 : 7757 : m_bSwapXAndY = bSwapXAndYAxis;
106 : 7757 : m_xTransformationLogicToScene = NULL;
107 : 7757 : }
108 : 108 : const std::vector< ExplicitScaleData >& PlottingPositionHelper::getScales() const
109 : : {
110 : 108 : return m_aScales;
111 : : }
112 : :
113 : 112745 : uno::Reference< XTransformation > PlottingPositionHelper::getTransformationScaledLogicToScene() const
114 : : {
115 : : //this is a standard transformation for a cartesian coordinate system
116 : :
117 : : //transformation from 2) to 4) //@todo 2) and 4) need a ink to a document
118 : :
119 : : //we need to apply this transformation to each geometric object because of a bug/problem
120 : : //of the old drawing layer (the UNO_NAME_3D_EXTRUDE_DEPTH is an integer value instead of an double )
121 [ + + ]: 112745 : if(!m_xTransformationLogicToScene.is())
122 : : {
123 [ + - ]: 10512 : ::basegfx::B3DHomMatrix aMatrix;
124 [ + - ]: 10512 : double MinX = getLogicMinX();
125 [ + - ]: 10512 : double MinY = getLogicMinY();
126 [ + - ]: 10512 : double MinZ = getLogicMinZ();
127 [ + - ]: 10512 : double MaxX = getLogicMaxX();
128 [ + - ]: 10512 : double MaxY = getLogicMaxY();
129 [ + - ]: 10512 : double MaxZ = getLogicMaxZ();
130 : :
131 [ + - ]: 10512 : AxisOrientation nXAxisOrientation = m_aScales[0].Orientation;
132 [ + - ]: 10512 : AxisOrientation nYAxisOrientation = m_aScales[1].Orientation;
133 [ + - ]: 10512 : AxisOrientation nZAxisOrientation = m_aScales[2].Orientation;
134 : :
135 : : //apply scaling
136 [ + - ]: 10512 : doUnshiftedLogicScaling( &MinX, &MinY, &MinZ );
137 [ + - ]: 10512 : doUnshiftedLogicScaling( &MaxX, &MaxY, &MaxZ);
138 : :
139 [ + + ]: 10512 : if(m_bSwapXAndY)
140 : : {
141 : 28 : std::swap(MinX,MinY);
142 : 28 : std::swap(MaxX,MaxY);
143 : 28 : std::swap(nXAxisOrientation,nYAxisOrientation);
144 : : }
145 : :
146 : 10512 : double fWidthX = MaxX - MinX;
147 : 10512 : double fWidthY = MaxY - MinY;
148 : 10512 : double fWidthZ = MaxZ - MinZ;
149 : :
150 [ + - ]: 10512 : double fScaleDirectionX = AxisOrientation_MATHEMATICAL==nXAxisOrientation ? 1.0 : -1.0;
151 [ + + ]: 10512 : double fScaleDirectionY = AxisOrientation_MATHEMATICAL==nYAxisOrientation ? 1.0 : -1.0;
152 [ + - ]: 10512 : double fScaleDirectionZ = AxisOrientation_MATHEMATICAL==nZAxisOrientation ? -1.0 : 1.0;
153 : :
154 : 10512 : double fScaleX = fScaleDirectionX*FIXED_SIZE_FOR_3D_CHART_VOLUME/fWidthX;
155 : 10512 : double fScaleY = fScaleDirectionY*FIXED_SIZE_FOR_3D_CHART_VOLUME/fWidthY;
156 : 10512 : double fScaleZ = fScaleDirectionZ*FIXED_SIZE_FOR_3D_CHART_VOLUME/fWidthZ;
157 : :
158 [ + - ]: 10512 : aMatrix.scale(fScaleX, fScaleY, fScaleZ);
159 : :
160 [ + - ]: 10512 : if( AxisOrientation_MATHEMATICAL==nXAxisOrientation )
161 [ + - ]: 10512 : aMatrix.translate(-MinX*fScaleX, 0.0, 0.0);
162 : : else
163 [ # # ]: 0 : aMatrix.translate(-MaxX*fScaleX, 0.0, 0.0);
164 [ + + ]: 10512 : if( AxisOrientation_MATHEMATICAL==nYAxisOrientation )
165 [ + - ]: 9926 : aMatrix.translate(0.0, -MinY*fScaleY, 0.0);
166 : : else
167 [ + - ]: 586 : aMatrix.translate(0.0, -MaxY*fScaleY, 0.0);
168 [ + - ]: 10512 : if( AxisOrientation_MATHEMATICAL==nZAxisOrientation )
169 [ + - ]: 10512 : aMatrix.translate(0.0, 0.0, -MaxZ*fScaleZ);//z direction in draw is reverse mathematical direction
170 : : else
171 [ # # ]: 0 : aMatrix.translate(0.0, 0.0, -MinZ*fScaleZ);
172 : :
173 [ + - ][ + - ]: 10512 : aMatrix = m_aMatrixScreenToScene*aMatrix;
[ + - ]
174 : :
175 [ + - ][ + - ]: 10512 : m_xTransformationLogicToScene = new Linear3DTransformation(B3DHomMatrixToHomogenMatrix( aMatrix ),m_bSwapXAndY);
[ + - ][ + - ]
[ + - ]
176 : : }
177 : 112745 : return m_xTransformationLogicToScene;
178 : : }
179 : :
180 : 48302 : drawing::Position3D PlottingPositionHelper::transformLogicToScene(
181 : : double fX, double fY, double fZ, bool bClip ) const
182 : : {
183 : 48302 : this->doLogicScaling( &fX,&fY,&fZ );
184 [ + + ]: 48302 : if(bClip)
185 : 45764 : this->clipScaledLogicValues( &fX,&fY,&fZ );
186 : :
187 : 48302 : return this->transformScaledLogicToScene( fX, fY, fZ, false );
188 : : }
189 : :
190 : 108629 : drawing::Position3D PlottingPositionHelper::transformScaledLogicToScene(
191 : : double fX, double fY, double fZ, bool bClip ) const
192 : : {
193 [ + + ]: 108629 : if( bClip )
194 [ + - ]: 58845 : this->clipScaledLogicValues( &fX,&fY,&fZ );
195 : :
196 : 108629 : drawing::Position3D aPos( fX, fY, fZ);
197 : :
198 : : uno::Reference< XTransformation > xTransformation =
199 [ + - ]: 108629 : this->getTransformationScaledLogicToScene();
200 : : uno::Sequence< double > aSeq =
201 [ + - ][ + - ]: 108629 : xTransformation->transform( Position3DToSequence(aPos) );
[ + - ][ + - ]
202 [ + - ][ + - ]: 108629 : return SequenceToPosition3D(aSeq);
203 : : }
204 : :
205 : 2576 : awt::Point PlottingPositionHelper::transformSceneToScreenPosition( const drawing::Position3D& rScenePosition3D
206 : : , const uno::Reference< drawing::XShapes >& xSceneTarget
207 : : , ShapeFactory* pShapeFactory
208 : : , sal_Int32 nDimensionCount )
209 : : {
210 : : //@todo would like to have a cheaper method to do this transformation
211 : 2576 : awt::Point aScreenPoint( static_cast<sal_Int32>(rScenePosition3D.PositionX), static_cast<sal_Int32>(rScenePosition3D.PositionY) );
212 : :
213 : : //transformation from scene to screen (only neccessary for 3D):
214 [ + + ]: 2576 : if(3==nDimensionCount)
215 : : {
216 : : //create 3D anchor shape
217 [ + - ]: 429 : tPropertyNameMap aDummyPropertyNameMap;
218 : : uno::Reference< drawing::XShape > xShape3DAnchor = pShapeFactory->createCube( xSceneTarget
219 : : , rScenePosition3D,drawing::Direction3D(1,1,1)
220 [ + - ][ + - ]: 429 : , 0, 0, aDummyPropertyNameMap);
221 : : //get 2D position from xShape3DAnchor
222 [ + - ][ + - ]: 429 : aScreenPoint = xShape3DAnchor->getPosition();
223 [ + - ][ + - ]: 429 : xSceneTarget->remove(xShape3DAnchor);
224 : : }
225 : 2576 : return aScreenPoint;
226 : : }
227 : :
228 : 11319 : void PlottingPositionHelper::transformScaledLogicToScene( drawing::PolyPolygonShape3D& rPolygon ) const
229 : : {
230 : 11319 : drawing::Position3D aScenePosition;
231 [ + + ]: 22614 : for( sal_Int32 nS = rPolygon.SequenceX.getLength(); nS--;)
232 : : {
233 [ + - ]: 11295 : drawing::DoubleSequence& xValues = rPolygon.SequenceX[nS];
234 [ + - ]: 11295 : drawing::DoubleSequence& yValues = rPolygon.SequenceY[nS];
235 [ + - ]: 11295 : drawing::DoubleSequence& zValues = rPolygon.SequenceZ[nS];
236 [ + + ]: 69536 : for( sal_Int32 nP = xValues.getLength(); nP--; )
237 : : {
238 [ + - ]: 58241 : double& fX = xValues[nP];
239 [ + - ]: 58241 : double& fY = yValues[nP];
240 [ + - ]: 58241 : double& fZ = zValues[nP];
241 [ + - ]: 58241 : aScenePosition = this->transformScaledLogicToScene( fX,fY,fZ,true );
242 : 58241 : fX = aScenePosition.PositionX;
243 : 58241 : fY = aScenePosition.PositionY;
244 : 58241 : fZ = aScenePosition.PositionZ;
245 : : }
246 : : }
247 : 11319 : }
248 : :
249 : :
250 : 106091 : void PlottingPositionHelper::clipScaledLogicValues( double* pX, double* pY, double* pZ ) const
251 : : {
252 : : //get logic clip values:
253 [ + - ]: 106091 : double MinX = getLogicMinX();
254 [ + - ]: 106091 : double MinY = getLogicMinY();
255 [ + - ]: 106091 : double MinZ = getLogicMinZ();
256 [ + - ]: 106091 : double MaxX = getLogicMaxX();
257 [ + - ]: 106091 : double MaxY = getLogicMaxY();
258 [ + - ]: 106091 : double MaxZ = getLogicMaxZ();
259 : :
260 : : //apply scaling
261 [ + - ]: 106091 : doUnshiftedLogicScaling( &MinX, &MinY, &MinZ );
262 [ + - ]: 106091 : doUnshiftedLogicScaling( &MaxX, &MaxY, &MaxZ);
263 : :
264 [ + - ]: 106091 : if(pX)
265 : : {
266 [ - + ]: 106091 : if( *pX < MinX )
267 : 0 : *pX = MinX;
268 [ - + ]: 106091 : else if( *pX > MaxX )
269 : 0 : *pX = MaxX;
270 : : }
271 [ + - ]: 106091 : if(pY)
272 : : {
273 [ + + ]: 106091 : if( *pY < MinY )
274 : 158 : *pY = MinY;
275 [ + + ]: 105933 : else if( *pY > MaxY )
276 : 158 : *pY = MaxY;
277 : : }
278 [ + - ]: 106091 : if(pZ)
279 : : {
280 [ + + ]: 106091 : if( *pZ < MinZ )
281 : 1488 : *pZ = MinZ;
282 [ - + ]: 104603 : else if( *pZ > MaxZ )
283 : 0 : *pZ = MaxZ;
284 : : }
285 : 106091 : }
286 : :
287 : 404 : basegfx::B2DRectangle PlottingPositionHelper::getScaledLogicClipDoubleRect() const
288 : : {
289 : : //get logic clip values:
290 [ + - ]: 404 : double MinX = getLogicMinX();
291 [ + - ]: 404 : double MinY = getLogicMinY();
292 [ + - ]: 404 : double MinZ = getLogicMinZ();
293 [ + - ]: 404 : double MaxX = getLogicMaxX();
294 [ + - ]: 404 : double MaxY = getLogicMaxY();
295 [ + - ]: 404 : double MaxZ = getLogicMaxZ();
296 : :
297 : : //apply scaling
298 [ + - ]: 404 : doUnshiftedLogicScaling( &MinX, &MinY, &MinZ );
299 [ + - ]: 404 : doUnshiftedLogicScaling( &MaxX, &MaxY, &MaxZ);
300 : :
301 [ + - ]: 404 : basegfx::B2DRectangle aRet( MinX, MaxY, MaxX, MinY );
302 : 404 : return aRet;
303 : : }
304 : :
305 : 14 : drawing::Direction3D PlottingPositionHelper::getScaledLogicWidth() const
306 : : {
307 : 14 : drawing::Direction3D aRet;
308 : :
309 [ + - ]: 14 : double MinX = getLogicMinX();
310 [ + - ]: 14 : double MinY = getLogicMinY();
311 [ + - ]: 14 : double MinZ = getLogicMinZ();
312 [ + - ]: 14 : double MaxX = getLogicMaxX();
313 [ + - ]: 14 : double MaxY = getLogicMaxY();
314 [ + - ]: 14 : double MaxZ = getLogicMaxZ();
315 : :
316 [ + - ]: 14 : doLogicScaling( &MinX, &MinY, &MinZ );
317 [ + - ]: 14 : doLogicScaling( &MaxX, &MaxY, &MaxZ);
318 : :
319 : 14 : aRet.DirectionX = MaxX - MinX;
320 : 14 : aRet.DirectionY = MaxY - MinY;
321 : 14 : aRet.DirectionZ = MaxZ - MinZ;
322 : 14 : return aRet;
323 : : }
324 : :
325 : : //-----------------------------------------------------------------------------
326 : : //-----------------------------------------------------------------------------
327 : : //-----------------------------------------------------------------------------
328 : :
329 : 19 : PolarPlottingPositionHelper::PolarPlottingPositionHelper( NormalAxis eNormalAxis )
330 : : : m_fRadiusOffset(0.0)
331 : : , m_fAngleDegreeOffset(90.0)
332 : : , m_aUnitCartesianToScene()
333 [ + - ]: 19 : , m_eNormalAxis(eNormalAxis)
334 : : {
335 : 19 : m_bMaySkipPointsInRegressionCalculation = false;
336 : 19 : }
337 : :
338 : 0 : PolarPlottingPositionHelper::PolarPlottingPositionHelper( const PolarPlottingPositionHelper& rSource )
339 : : : PlottingPositionHelper(rSource)
340 : : , m_fRadiusOffset( rSource.m_fRadiusOffset )
341 : : , m_fAngleDegreeOffset( rSource.m_fAngleDegreeOffset )
342 : : , m_aUnitCartesianToScene( rSource.m_aUnitCartesianToScene )
343 [ # # ]: 0 : , m_eNormalAxis( rSource.m_eNormalAxis )
344 : : {
345 : 0 : }
346 : :
347 [ + - ]: 19 : PolarPlottingPositionHelper::~PolarPlottingPositionHelper()
348 : : {
349 [ - + ]: 19 : }
350 : :
351 : 0 : PlottingPositionHelper* PolarPlottingPositionHelper::clone() const
352 : : {
353 [ # # ]: 0 : PolarPlottingPositionHelper* pRet = new PolarPlottingPositionHelper(*this);
354 : 0 : return pRet;
355 : : }
356 : :
357 : 38 : void PolarPlottingPositionHelper::setTransformationSceneToScreen( const drawing::HomogenMatrix& rMatrix)
358 : : {
359 : 38 : PlottingPositionHelper::setTransformationSceneToScreen( rMatrix);
360 [ + - ]: 38 : m_aUnitCartesianToScene =impl_calculateMatrixUnitCartesianToScene( m_aMatrixScreenToScene );
361 : 38 : }
362 : 19 : void PolarPlottingPositionHelper::setScales( const std::vector< ExplicitScaleData >& rScales, bool bSwapXAndYAxis )
363 : : {
364 : 19 : PlottingPositionHelper::setScales( rScales, bSwapXAndYAxis );
365 [ + - ]: 19 : m_aUnitCartesianToScene =impl_calculateMatrixUnitCartesianToScene( m_aMatrixScreenToScene );
366 : 19 : }
367 : :
368 : 57 : ::basegfx::B3DHomMatrix PolarPlottingPositionHelper::impl_calculateMatrixUnitCartesianToScene( const ::basegfx::B3DHomMatrix& rMatrixScreenToScene ) const
369 : : {
370 : 57 : ::basegfx::B3DHomMatrix aRet;
371 : :
372 [ - + ]: 57 : if( m_aScales.empty() )
373 : 0 : return aRet;
374 : :
375 : 57 : double fTranslate =1.0;
376 : 57 : double fScale =FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0;
377 : :
378 : 57 : double fTranslateLogicZ =fTranslate;
379 : 57 : double fScaleLogicZ =fScale;
380 : : {
381 [ + - ][ + - ]: 57 : double fScaleDirectionZ = AxisOrientation_MATHEMATICAL==m_aScales[2].Orientation ? 1.0 : -1.0;
382 [ + - ]: 57 : double MinZ = getLogicMinZ();
383 [ + - ]: 57 : double MaxZ = getLogicMaxZ();
384 [ + - ]: 57 : doLogicScaling( 0, 0, &MinZ );
385 [ + - ]: 57 : doLogicScaling( 0, 0, &MaxZ );
386 : 57 : double fWidthZ = MaxZ - MinZ;
387 : :
388 [ + - ][ + - ]: 57 : if( AxisOrientation_MATHEMATICAL==m_aScales[2].Orientation )
389 : 57 : fTranslateLogicZ=MinZ;
390 : : else
391 : 0 : fTranslateLogicZ=MaxZ;
392 : 57 : fScaleLogicZ = fScaleDirectionZ*FIXED_SIZE_FOR_3D_CHART_VOLUME/fWidthZ;
393 : : }
394 : :
395 : 57 : double fTranslateX = fTranslate;
396 : 57 : double fTranslateY = fTranslate;
397 : 57 : double fTranslateZ = fTranslate;
398 : :
399 : 57 : double fScaleX = fScale;
400 : 57 : double fScaleY = fScale;
401 : 57 : double fScaleZ = fScale;
402 : :
403 [ - - + ]: 57 : switch(m_eNormalAxis)
404 : : {
405 : : case NormalAxis_X:
406 : : {
407 : 0 : fTranslateX = fTranslateLogicZ;
408 : 0 : fScaleX = fScaleLogicZ;
409 : : }
410 : 0 : break;
411 : : case NormalAxis_Y:
412 : : {
413 : 0 : fTranslateY = fTranslateLogicZ;
414 : 0 : fScaleY = fScaleLogicZ;
415 : : }
416 : 0 : break;
417 : : default: //NormalAxis_Z:
418 : : {
419 : 57 : fTranslateZ = fTranslateLogicZ;
420 : 57 : fScaleZ = fScaleLogicZ;
421 : : }
422 : 57 : break;
423 : : }
424 : :
425 [ + - ]: 57 : aRet.translate(fTranslateX, fTranslateY, fTranslateZ);//x first
426 [ + - ]: 57 : aRet.scale(fScaleX, fScaleY, fScaleZ);//x first
427 : :
428 [ + - ][ + - ]: 57 : aRet = rMatrixScreenToScene * aRet;
[ + - ]
429 : 57 : return aRet;
430 : : }
431 : :
432 : 152 : ::basegfx::B3DHomMatrix PolarPlottingPositionHelper::getUnitCartesianToScene() const
433 : : {
434 : 152 : return m_aUnitCartesianToScene;
435 : : }
436 : :
437 : 0 : uno::Reference< XTransformation > PolarPlottingPositionHelper::getTransformationScaledLogicToScene() const
438 : : {
439 [ # # ]: 0 : if( !m_xTransformationLogicToScene.is() )
440 [ # # ][ # # ]: 0 : m_xTransformationLogicToScene = new VPolarTransformation(*this);
441 : 0 : return m_xTransformationLogicToScene;
442 : : }
443 : :
444 : 152 : double PolarPlottingPositionHelper::getWidthAngleDegree( double& fStartLogicValueOnAngleAxis, double& fEndLogicValueOnAngleAxis ) const
445 : : {
446 [ + - ]: 152 : const ExplicitScaleData& rAngleScale = m_bSwapXAndY ? m_aScales[1] : m_aScales[0];
447 [ - + ]: 152 : if( AxisOrientation_MATHEMATICAL != rAngleScale.Orientation )
448 : : {
449 : 0 : double fHelp = fEndLogicValueOnAngleAxis;
450 : 0 : fEndLogicValueOnAngleAxis = fStartLogicValueOnAngleAxis;
451 : 0 : fStartLogicValueOnAngleAxis = fHelp;
452 : : }
453 : :
454 : 152 : double fStartAngleDegree = this->transformToAngleDegree( fStartLogicValueOnAngleAxis );
455 : 152 : double fEndAngleDegree = this->transformToAngleDegree( fEndLogicValueOnAngleAxis );
456 : 152 : double fWidthAngleDegree = fEndAngleDegree - fStartAngleDegree;
457 : :
458 [ - + ]: 152 : if( ::rtl::math::approxEqual( fStartAngleDegree, fEndAngleDegree )
[ - + # # ]
459 : 0 : && !::rtl::math::approxEqual( fStartLogicValueOnAngleAxis, fEndLogicValueOnAngleAxis ) )
460 : 0 : fWidthAngleDegree = 360.0;
461 : :
462 [ + + ]: 190 : while(fWidthAngleDegree<0.0)
463 : 38 : fWidthAngleDegree+=360.0;
464 [ - + ]: 152 : while(fWidthAngleDegree>360.0)
465 : 0 : fWidthAngleDegree-=360.0;
466 : :
467 : 152 : return fWidthAngleDegree;
468 : : }
469 : :
470 : 456 : double PolarPlottingPositionHelper::transformToAngleDegree( double fLogicValueOnAngleAxis, bool bDoScaling ) const
471 : : {
472 : 456 : double fRet=0.0;
473 : :
474 : 456 : double fAxisAngleScaleDirection = 1.0;
475 : : {
476 [ + - ]: 456 : const ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[1] : m_aScales[0];
477 [ - + ]: 456 : if(AxisOrientation_MATHEMATICAL != rScale.Orientation)
478 : 0 : fAxisAngleScaleDirection *= -1.0;
479 : : }
480 : :
481 : 456 : double MinAngleValue = 0.0;
482 : 456 : double MaxAngleValue = 0.0;
483 : : {
484 [ + - ]: 456 : double MinX = getLogicMinX();
485 [ + - ]: 456 : double MinY = getLogicMinY();
486 [ + - ]: 456 : double MaxX = getLogicMaxX();
487 [ + - ]: 456 : double MaxY = getLogicMaxY();
488 [ + - ]: 456 : double MinZ = getLogicMinZ();
489 [ + - ]: 456 : double MaxZ = getLogicMaxZ();
490 : :
491 [ + - ]: 456 : doLogicScaling( &MinX, &MinY, &MinZ );
492 [ + - ]: 456 : doLogicScaling( &MaxX, &MaxY, &MaxZ);
493 : :
494 [ + - ]: 456 : MinAngleValue = m_bSwapXAndY ? MinY : MinX;
495 [ + - ]: 456 : MaxAngleValue = m_bSwapXAndY ? MaxY : MaxX;
496 : : }
497 : :
498 : 456 : double fScaledLogicAngleValue = 0.0;
499 [ + - ]: 456 : if(bDoScaling)
500 : : {
501 [ + - ][ + - ]: 456 : double fX = m_bSwapXAndY ? getLogicMaxX() : fLogicValueOnAngleAxis;
502 [ + - ][ # # ]: 456 : double fY = m_bSwapXAndY ? fLogicValueOnAngleAxis : getLogicMaxY();
503 [ + - ]: 456 : double fZ = getLogicMaxZ();
504 [ + - ]: 456 : clipLogicValues( &fX, &fY, &fZ );
505 [ + - ]: 456 : doLogicScaling( &fX, &fY, &fZ );
506 [ + - ]: 456 : fScaledLogicAngleValue = m_bSwapXAndY ? fY : fX;
507 : : }
508 : : else
509 : 0 : fScaledLogicAngleValue = fLogicValueOnAngleAxis;
510 : :
511 : : fRet = m_fAngleDegreeOffset
512 : : + fAxisAngleScaleDirection*(fScaledLogicAngleValue-MinAngleValue)*360.0
513 : 456 : /fabs(MaxAngleValue-MinAngleValue);
514 [ + + ]: 608 : while(fRet>360.0)
515 : 152 : fRet-=360.0;
516 [ - + ]: 456 : while(fRet<0)
517 : 0 : fRet+=360.0;
518 : 456 : return fRet;
519 : : }
520 : :
521 : 304 : double PolarPlottingPositionHelper::transformToRadius( double fLogicValueOnRadiusAxis, bool bDoScaling ) const
522 : : {
523 : 304 : double fNormalRadius = 0.0;
524 : : {
525 : 304 : double fScaledLogicRadiusValue = 0.0;
526 [ + - ][ # # ]: 304 : double fX = m_bSwapXAndY ? fLogicValueOnRadiusAxis: getLogicMaxX();
527 [ + - ][ + - ]: 304 : double fY = m_bSwapXAndY ? getLogicMaxY() : fLogicValueOnRadiusAxis;
528 [ + - ]: 304 : if(bDoScaling)
529 [ + - ]: 304 : doLogicScaling( &fX, &fY, 0 );
530 : :
531 [ + - ]: 304 : fScaledLogicRadiusValue = m_bSwapXAndY ? fX : fY;
532 : :
533 : 304 : bool bMinIsInnerRadius = true;
534 [ + - ][ + - ]: 304 : const ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[0] : m_aScales[1];
[ # # ]
535 [ + - ]: 304 : if(AxisOrientation_MATHEMATICAL != rScale.Orientation)
536 : 304 : bMinIsInnerRadius = false;
537 : :
538 : 304 : double fInnerScaledLogicRadius=0.0;
539 : 304 : double fOuterScaledLogicRadius=0.0;
540 : : {
541 [ + - ]: 304 : double MinX = getLogicMinX();
542 [ + - ]: 304 : double MinY = getLogicMinY();
543 [ + - ]: 304 : doLogicScaling( &MinX, &MinY, 0 );
544 [ + - ]: 304 : double MaxX = getLogicMaxX();
545 [ + - ]: 304 : double MaxY = getLogicMaxY();
546 [ + - ]: 304 : doLogicScaling( &MaxX, &MaxY, 0 );
547 : :
548 [ + - ]: 304 : double fMin = m_bSwapXAndY ? MinX : MinY;
549 [ + - ]: 304 : double fMax = m_bSwapXAndY ? MaxX : MaxY;
550 : :
551 [ - + ]: 304 : fInnerScaledLogicRadius = bMinIsInnerRadius ? fMin : fMax;
552 [ - + ]: 304 : fOuterScaledLogicRadius = bMinIsInnerRadius ? fMax : fMin;
553 : : }
554 : :
555 [ - + ]: 304 : if( bMinIsInnerRadius )
556 : 0 : fInnerScaledLogicRadius -= fabs(m_fRadiusOffset);
557 : : else
558 : 304 : fInnerScaledLogicRadius += fabs(m_fRadiusOffset);
559 : 304 : fNormalRadius = (fScaledLogicRadiusValue-fInnerScaledLogicRadius)/(fOuterScaledLogicRadius-fInnerScaledLogicRadius);
560 : : }
561 : 304 : return fNormalRadius;
562 : : }
563 : :
564 : 0 : drawing::Position3D PolarPlottingPositionHelper::transformLogicToScene( double fX, double fY, double fZ, bool bClip ) const
565 : : {
566 [ # # ]: 0 : if(bClip)
567 : 0 : this->clipLogicValues( &fX,&fY,&fZ );
568 [ # # ]: 0 : double fLogicValueOnAngleAxis = m_bSwapXAndY ? fY : fX;
569 [ # # ]: 0 : double fLogicValueOnRadiusAxis = m_bSwapXAndY ? fX : fY;
570 : 0 : return this->transformAngleRadiusToScene( fLogicValueOnAngleAxis, fLogicValueOnRadiusAxis, fZ, true );
571 : : }
572 : :
573 : 0 : drawing::Position3D PolarPlottingPositionHelper::transformScaledLogicToScene( double fX, double fY, double fZ, bool bClip ) const
574 : : {
575 [ # # ]: 0 : if(bClip)
576 : 0 : this->clipScaledLogicValues( &fX,&fY,&fZ );
577 [ # # ]: 0 : double fLogicValueOnAngleAxis = m_bSwapXAndY ? fY : fX;
578 [ # # ]: 0 : double fLogicValueOnRadiusAxis = m_bSwapXAndY ? fX : fY;
579 : 0 : return this->transformAngleRadiusToScene( fLogicValueOnAngleAxis, fLogicValueOnRadiusAxis, fZ, false );
580 : : }
581 : 304 : drawing::Position3D PolarPlottingPositionHelper::transformUnitCircleToScene( double fUnitAngleDegree, double fUnitRadius
582 : : , double fLogicZ, bool /* bDoScaling */ ) const
583 : : {
584 : 304 : double fAnglePi = fUnitAngleDegree*F_PI/180.0;
585 : :
586 : 304 : double fX=fUnitRadius*rtl::math::cos(fAnglePi);
587 : 304 : double fY=fUnitRadius*rtl::math::sin(fAnglePi);
588 : 304 : double fZ=fLogicZ;
589 : :
590 [ - - + ]: 304 : switch(m_eNormalAxis)
591 : : {
592 : : case NormalAxis_X:
593 : 0 : std::swap(fX,fZ);
594 : 0 : break;
595 : : case NormalAxis_Y:
596 : 0 : std::swap(fY,fZ);
597 : 0 : fZ*=-1;
598 : 0 : break;
599 : : default: //NormalAxis_Z
600 : 304 : break;
601 : : }
602 : :
603 : : //!! applying matrix to vector does ignore translation, so it is important to use a B3DPoint here instead of B3DVector
604 : 304 : ::basegfx::B3DPoint aPoint(fX,fY,fZ);
605 [ + - ]: 304 : ::basegfx::B3DPoint aRet = m_aUnitCartesianToScene * aPoint;
606 [ + - ]: 304 : return B3DPointToPosition3D(aRet);
607 : : }
608 : :
609 : 0 : drawing::Position3D PolarPlottingPositionHelper::transformAngleRadiusToScene( double fLogicValueOnAngleAxis, double fLogicValueOnRadiusAxis, double fLogicZ, bool bDoScaling ) const
610 : : {
611 : 0 : double fUnitAngleDegree = this->transformToAngleDegree(fLogicValueOnAngleAxis,bDoScaling);
612 : 0 : double fUnitRadius = this->transformToRadius(fLogicValueOnRadiusAxis,bDoScaling);
613 : :
614 : 0 : return transformUnitCircleToScene( fUnitAngleDegree, fUnitRadius, fLogicZ, bDoScaling );
615 : : }
616 : :
617 : 0 : double PolarPlottingPositionHelper::getOuterLogicRadius() const
618 : : {
619 [ # # ]: 0 : const ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[0] : m_aScales[1];
620 [ # # ]: 0 : if( AxisOrientation_MATHEMATICAL==rScale.Orientation )
621 : 0 : return rScale.Maximum;
622 : : else
623 : 0 : return rScale.Minimum;
624 : : }
625 : :
626 : 46806 : bool PlottingPositionHelper::isPercentY() const
627 : : {
628 : 46806 : return m_aScales[1].AxisType==AxisType::PERCENT;
629 : : }
630 : :
631 : 11105 : double PlottingPositionHelper::getBaseValueY() const
632 : : {
633 : 11105 : return m_aScales[1].Origin;
634 : : }
635 : :
636 : 16492 : void PlottingPositionHelper::setTimeResolution( long nTimeResolution, const Date& rNullDate )
637 : : {
638 : 16492 : m_nTimeResolution = nTimeResolution;
639 : 16492 : m_aNullDate = rNullDate;
640 : :
641 : : //adapt category width
642 : 16492 : double fCategoryWidth = 1.0;
643 [ + - ]: 16492 : if( !m_aScales.empty() )
644 : : {
645 [ - + ]: 16492 : if( m_aScales[0].AxisType == ::com::sun::star::chart2::AxisType::DATE )
646 : : {
647 : 0 : m_bDateAxis = true;
648 [ # # ]: 0 : if( nTimeResolution == ::com::sun::star::chart::TimeUnit::YEAR )
649 : : {
650 : 0 : const double fMonthCount = 12.0;//todo: this depends on the DateScaling and must be adjusted in case we use more generic calendars in future
651 : 0 : fCategoryWidth = fMonthCount;
652 : : }
653 : : }
654 : : }
655 : 16492 : setScaledCategoryWidth(fCategoryWidth);
656 : 16492 : }
657 : :
658 : 5372 : void PlottingPositionHelper::setScaledCategoryWidth( double fScaledCategoryWidth )
659 : : {
660 : 5372 : m_fScaledCategoryWidth = fScaledCategoryWidth;
661 : 5372 : }
662 : 962 : void PlottingPositionHelper::AllowShiftXAxisPos( bool bAllowShift )
663 : : {
664 : 962 : m_bAllowShiftXAxisPos = bAllowShift;
665 : 962 : }
666 : 962 : void PlottingPositionHelper::AllowShiftZAxisPos( bool bAllowShift )
667 : : {
668 : 962 : m_bAllowShiftZAxisPos = bAllowShift;
669 : 962 : }
670 : :
671 : : }
672 : :
673 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|