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