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