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 205 : 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 205 : , m_bAllowShiftZAxisPos(false)
59 : {
60 205 : }
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 369 : PlottingPositionHelper::~PlottingPositionHelper()
80 : {
81 :
82 369 : }
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 943 : void PlottingPositionHelper::setTransformationSceneToScreen( const drawing::HomogenMatrix& rMatrix)
98 : {
99 943 : m_aMatrixScreenToScene = HomogenMatrixToB3DHomMatrix(rMatrix);
100 943 : m_xTransformationLogicToScene = NULL;
101 943 : }
102 :
103 328 : void PlottingPositionHelper::setScales( const std::vector< ExplicitScaleData >& rScales, bool bSwapXAndYAxis )
104 : {
105 328 : m_aScales = rScales;
106 328 : m_bSwapXAndY = bSwapXAndYAxis;
107 328 : m_xTransformationLogicToScene = NULL;
108 328 : }
109 0 : const std::vector< ExplicitScaleData >& PlottingPositionHelper::getScales() const
110 : {
111 0 : return m_aScales;
112 : }
113 :
114 4879 : 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 4879 : if(!m_xTransformationLogicToScene.is())
123 : {
124 492 : ::basegfx::B3DHomMatrix aMatrix;
125 492 : double MinX = getLogicMinX();
126 492 : double MinY = getLogicMinY();
127 492 : double MinZ = getLogicMinZ();
128 492 : double MaxX = getLogicMaxX();
129 492 : double MaxY = getLogicMaxY();
130 492 : double MaxZ = getLogicMaxZ();
131 :
132 492 : AxisOrientation nXAxisOrientation = m_aScales[0].Orientation;
133 492 : AxisOrientation nYAxisOrientation = m_aScales[1].Orientation;
134 492 : AxisOrientation nZAxisOrientation = m_aScales[2].Orientation;
135 :
136 : //apply scaling
137 492 : doUnshiftedLogicScaling( &MinX, &MinY, &MinZ );
138 492 : doUnshiftedLogicScaling( &MaxX, &MaxY, &MaxZ);
139 :
140 492 : if(m_bSwapXAndY)
141 : {
142 0 : std::swap(MinX,MinY);
143 0 : std::swap(MaxX,MaxY);
144 0 : std::swap(nXAxisOrientation,nYAxisOrientation);
145 : }
146 :
147 492 : double fWidthX = MaxX - MinX;
148 492 : double fWidthY = MaxY - MinY;
149 492 : double fWidthZ = MaxZ - MinZ;
150 :
151 492 : double fScaleDirectionX = AxisOrientation_MATHEMATICAL==nXAxisOrientation ? 1.0 : -1.0;
152 492 : double fScaleDirectionY = AxisOrientation_MATHEMATICAL==nYAxisOrientation ? 1.0 : -1.0;
153 492 : double fScaleDirectionZ = AxisOrientation_MATHEMATICAL==nZAxisOrientation ? -1.0 : 1.0;
154 :
155 492 : double fScaleX = fScaleDirectionX*FIXED_SIZE_FOR_3D_CHART_VOLUME/fWidthX;
156 492 : double fScaleY = fScaleDirectionY*FIXED_SIZE_FOR_3D_CHART_VOLUME/fWidthY;
157 492 : double fScaleZ = fScaleDirectionZ*FIXED_SIZE_FOR_3D_CHART_VOLUME/fWidthZ;
158 :
159 492 : aMatrix.scale(fScaleX, fScaleY, fScaleZ);
160 :
161 492 : if( AxisOrientation_MATHEMATICAL==nXAxisOrientation )
162 492 : aMatrix.translate(-MinX*fScaleX, 0.0, 0.0);
163 : else
164 0 : aMatrix.translate(-MaxX*fScaleX, 0.0, 0.0);
165 492 : if( AxisOrientation_MATHEMATICAL==nYAxisOrientation )
166 492 : aMatrix.translate(0.0, -MinY*fScaleY, 0.0);
167 : else
168 0 : aMatrix.translate(0.0, -MaxY*fScaleY, 0.0);
169 492 : if( AxisOrientation_MATHEMATICAL==nZAxisOrientation )
170 492 : 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 492 : aMatrix = m_aMatrixScreenToScene*aMatrix;
175 :
176 492 : m_xTransformationLogicToScene = new Linear3DTransformation(B3DHomMatrixToHomogenMatrix( aMatrix ),m_bSwapXAndY);
177 : }
178 4879 : return m_xTransformationLogicToScene;
179 : }
180 :
181 2132 : drawing::Position3D PlottingPositionHelper::transformLogicToScene(
182 : double fX, double fY, double fZ, bool bClip ) const
183 : {
184 2132 : this->doLogicScaling( &fX,&fY,&fZ );
185 2132 : if(bClip)
186 2132 : this->clipScaledLogicValues( &fX,&fY,&fZ );
187 :
188 2132 : return this->transformScaledLogicToScene( fX, fY, fZ, false );
189 : }
190 :
191 4592 : drawing::Position3D PlottingPositionHelper::transformScaledLogicToScene(
192 : double fX, double fY, double fZ, bool bClip ) const
193 : {
194 4592 : if( bClip )
195 2460 : this->clipScaledLogicValues( &fX,&fY,&fZ );
196 :
197 4592 : drawing::Position3D aPos( fX, fY, fZ);
198 :
199 : uno::Reference< XTransformation > xTransformation =
200 4592 : this->getTransformationScaledLogicToScene();
201 : uno::Sequence< double > aSeq =
202 4592 : xTransformation->transform( Position3DToSequence(aPos) );
203 4592 : return SequenceToPosition3D(aSeq);
204 : }
205 :
206 0 : 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 0 : awt::Point aScreenPoint( static_cast<sal_Int32>(rScenePosition3D.PositionX), static_cast<sal_Int32>(rScenePosition3D.PositionY) );
213 :
214 : //transformation from scene to screen (only neccessary for 3D):
215 0 : if(3==nDimensionCount)
216 : {
217 : //create 3D anchor shape
218 0 : tPropertyNameMap aDummyPropertyNameMap;
219 : uno::Reference< drawing::XShape > xShape3DAnchor = pShapeFactory->createCube( xSceneTarget
220 : , rScenePosition3D,drawing::Direction3D(1,1,1)
221 0 : , 0, 0, aDummyPropertyNameMap);
222 : //get 2D position from xShape3DAnchor
223 0 : aScreenPoint = xShape3DAnchor->getPosition();
224 0 : xSceneTarget->remove(xShape3DAnchor);
225 : }
226 0 : return aScreenPoint;
227 : }
228 :
229 492 : void PlottingPositionHelper::transformScaledLogicToScene( drawing::PolyPolygonShape3D& rPolygon ) const
230 : {
231 492 : drawing::Position3D aScenePosition;
232 1476 : for( sal_Int32 nS = rPolygon.SequenceX.getLength(); nS--;)
233 : {
234 492 : drawing::DoubleSequence& xValues = rPolygon.SequenceX[nS];
235 492 : drawing::DoubleSequence& yValues = rPolygon.SequenceY[nS];
236 492 : drawing::DoubleSequence& zValues = rPolygon.SequenceZ[nS];
237 3444 : for( sal_Int32 nP = xValues.getLength(); nP--; )
238 : {
239 2460 : double& fX = xValues[nP];
240 2460 : double& fY = yValues[nP];
241 2460 : double& fZ = zValues[nP];
242 2460 : aScenePosition = this->transformScaledLogicToScene( fX,fY,fZ,true );
243 2460 : fX = aScenePosition.PositionX;
244 2460 : fY = aScenePosition.PositionY;
245 2460 : fZ = aScenePosition.PositionZ;
246 : }
247 : }
248 492 : }
249 :
250 :
251 4592 : void PlottingPositionHelper::clipScaledLogicValues( double* pX, double* pY, double* pZ ) const
252 : {
253 : //get logic clip values:
254 4592 : double MinX = getLogicMinX();
255 4592 : double MinY = getLogicMinY();
256 4592 : double MinZ = getLogicMinZ();
257 4592 : double MaxX = getLogicMaxX();
258 4592 : double MaxY = getLogicMaxY();
259 4592 : double MaxZ = getLogicMaxZ();
260 :
261 : //apply scaling
262 4592 : doUnshiftedLogicScaling( &MinX, &MinY, &MinZ );
263 4592 : doUnshiftedLogicScaling( &MaxX, &MaxY, &MaxZ);
264 :
265 4592 : if(pX)
266 : {
267 4592 : if( *pX < MinX )
268 0 : *pX = MinX;
269 4592 : else if( *pX > MaxX )
270 0 : *pX = MaxX;
271 : }
272 4592 : if(pY)
273 : {
274 4592 : if( *pY < MinY )
275 0 : *pY = MinY;
276 4592 : else if( *pY > MaxY )
277 0 : *pY = MaxY;
278 : }
279 4592 : if(pZ)
280 : {
281 4592 : if( *pZ < MinZ )
282 0 : *pZ = MinZ;
283 4592 : else if( *pZ > MaxZ )
284 0 : *pZ = MaxZ;
285 : }
286 4592 : }
287 :
288 0 : basegfx::B2DRectangle PlottingPositionHelper::getScaledLogicClipDoubleRect() const
289 : {
290 : //get logic clip values:
291 0 : double MinX = getLogicMinX();
292 0 : double MinY = getLogicMinY();
293 0 : double MinZ = getLogicMinZ();
294 0 : double MaxX = getLogicMaxX();
295 0 : double MaxY = getLogicMaxY();
296 0 : double MaxZ = getLogicMaxZ();
297 :
298 : //apply scaling
299 0 : doUnshiftedLogicScaling( &MinX, &MinY, &MinZ );
300 0 : doUnshiftedLogicScaling( &MaxX, &MaxY, &MaxZ);
301 :
302 0 : basegfx::B2DRectangle aRet( MinX, MaxY, MaxX, MinY );
303 0 : return aRet;
304 : }
305 :
306 0 : drawing::Direction3D PlottingPositionHelper::getScaledLogicWidth() const
307 : {
308 0 : drawing::Direction3D aRet;
309 :
310 0 : double MinX = getLogicMinX();
311 0 : double MinY = getLogicMinY();
312 0 : double MinZ = getLogicMinZ();
313 0 : double MaxX = getLogicMaxX();
314 0 : double MaxY = getLogicMaxY();
315 0 : double MaxZ = getLogicMaxZ();
316 :
317 0 : doLogicScaling( &MinX, &MinY, &MinZ );
318 0 : doLogicScaling( &MaxX, &MaxY, &MaxZ);
319 :
320 0 : aRet.DirectionX = MaxX - MinX;
321 0 : aRet.DirectionY = MaxY - MinY;
322 0 : aRet.DirectionZ = MaxZ - MinZ;
323 0 : return aRet;
324 : }
325 :
326 : //-----------------------------------------------------------------------------
327 : //-----------------------------------------------------------------------------
328 : //-----------------------------------------------------------------------------
329 :
330 0 : PolarPlottingPositionHelper::PolarPlottingPositionHelper( NormalAxis eNormalAxis )
331 : : m_fRadiusOffset(0.0)
332 : , m_fAngleDegreeOffset(90.0)
333 : , m_aUnitCartesianToScene()
334 0 : , m_eNormalAxis(eNormalAxis)
335 : {
336 0 : m_bMaySkipPointsInRegressionCalculation = false;
337 0 : }
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 0 : PolarPlottingPositionHelper::~PolarPlottingPositionHelper()
349 : {
350 0 : }
351 :
352 0 : PlottingPositionHelper* PolarPlottingPositionHelper::clone() const
353 : {
354 0 : PolarPlottingPositionHelper* pRet = new PolarPlottingPositionHelper(*this);
355 0 : return pRet;
356 : }
357 :
358 0 : void PolarPlottingPositionHelper::setTransformationSceneToScreen( const drawing::HomogenMatrix& rMatrix)
359 : {
360 0 : PlottingPositionHelper::setTransformationSceneToScreen( rMatrix);
361 0 : m_aUnitCartesianToScene =impl_calculateMatrixUnitCartesianToScene( m_aMatrixScreenToScene );
362 0 : }
363 0 : void PolarPlottingPositionHelper::setScales( const std::vector< ExplicitScaleData >& rScales, bool bSwapXAndYAxis )
364 : {
365 0 : PlottingPositionHelper::setScales( rScales, bSwapXAndYAxis );
366 0 : m_aUnitCartesianToScene =impl_calculateMatrixUnitCartesianToScene( m_aMatrixScreenToScene );
367 0 : }
368 :
369 0 : ::basegfx::B3DHomMatrix PolarPlottingPositionHelper::impl_calculateMatrixUnitCartesianToScene( const ::basegfx::B3DHomMatrix& rMatrixScreenToScene ) const
370 : {
371 0 : ::basegfx::B3DHomMatrix aRet;
372 :
373 0 : if( m_aScales.empty() )
374 0 : return aRet;
375 :
376 0 : double fTranslate =1.0;
377 0 : double fScale =FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0;
378 :
379 0 : double fTranslateLogicZ =fTranslate;
380 0 : double fScaleLogicZ =fScale;
381 : {
382 0 : double fScaleDirectionZ = AxisOrientation_MATHEMATICAL==m_aScales[2].Orientation ? 1.0 : -1.0;
383 0 : double MinZ = getLogicMinZ();
384 0 : double MaxZ = getLogicMaxZ();
385 0 : doLogicScaling( 0, 0, &MinZ );
386 0 : doLogicScaling( 0, 0, &MaxZ );
387 0 : double fWidthZ = MaxZ - MinZ;
388 :
389 0 : if( AxisOrientation_MATHEMATICAL==m_aScales[2].Orientation )
390 0 : fTranslateLogicZ=MinZ;
391 : else
392 0 : fTranslateLogicZ=MaxZ;
393 0 : fScaleLogicZ = fScaleDirectionZ*FIXED_SIZE_FOR_3D_CHART_VOLUME/fWidthZ;
394 : }
395 :
396 0 : double fTranslateX = fTranslate;
397 0 : double fTranslateY = fTranslate;
398 0 : double fTranslateZ = fTranslate;
399 :
400 0 : double fScaleX = fScale;
401 0 : double fScaleY = fScale;
402 0 : double fScaleZ = fScale;
403 :
404 0 : 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 0 : fTranslateZ = fTranslateLogicZ;
421 0 : fScaleZ = fScaleLogicZ;
422 : }
423 0 : break;
424 : }
425 :
426 0 : aRet.translate(fTranslateX, fTranslateY, fTranslateZ);//x first
427 0 : aRet.scale(fScaleX, fScaleY, fScaleZ);//x first
428 :
429 0 : aRet = rMatrixScreenToScene * aRet;
430 0 : return aRet;
431 : }
432 :
433 0 : ::basegfx::B3DHomMatrix PolarPlottingPositionHelper::getUnitCartesianToScene() const
434 : {
435 0 : 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 0 : double PolarPlottingPositionHelper::getWidthAngleDegree( double& fStartLogicValueOnAngleAxis, double& fEndLogicValueOnAngleAxis ) const
446 : {
447 0 : const ExplicitScaleData& rAngleScale = m_bSwapXAndY ? m_aScales[1] : m_aScales[0];
448 0 : if( AxisOrientation_MATHEMATICAL != rAngleScale.Orientation )
449 : {
450 0 : double fHelp = fEndLogicValueOnAngleAxis;
451 0 : fEndLogicValueOnAngleAxis = fStartLogicValueOnAngleAxis;
452 0 : fStartLogicValueOnAngleAxis = fHelp;
453 : }
454 :
455 0 : double fStartAngleDegree = this->transformToAngleDegree( fStartLogicValueOnAngleAxis );
456 0 : double fEndAngleDegree = this->transformToAngleDegree( fEndLogicValueOnAngleAxis );
457 0 : double fWidthAngleDegree = fEndAngleDegree - fStartAngleDegree;
458 :
459 0 : if( ::rtl::math::approxEqual( fStartAngleDegree, fEndAngleDegree )
460 0 : && !::rtl::math::approxEqual( fStartLogicValueOnAngleAxis, fEndLogicValueOnAngleAxis ) )
461 0 : fWidthAngleDegree = 360.0;
462 :
463 0 : while(fWidthAngleDegree<0.0)
464 0 : fWidthAngleDegree+=360.0;
465 0 : while(fWidthAngleDegree>360.0)
466 0 : fWidthAngleDegree-=360.0;
467 :
468 0 : return fWidthAngleDegree;
469 : }
470 :
471 0 : double PolarPlottingPositionHelper::transformToAngleDegree( double fLogicValueOnAngleAxis, bool bDoScaling ) const
472 : {
473 0 : double fRet=0.0;
474 :
475 0 : double fAxisAngleScaleDirection = 1.0;
476 : {
477 0 : const ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[1] : m_aScales[0];
478 0 : if(AxisOrientation_MATHEMATICAL != rScale.Orientation)
479 0 : fAxisAngleScaleDirection *= -1.0;
480 : }
481 :
482 0 : double MinAngleValue = 0.0;
483 0 : double MaxAngleValue = 0.0;
484 : {
485 0 : double MinX = getLogicMinX();
486 0 : double MinY = getLogicMinY();
487 0 : double MaxX = getLogicMaxX();
488 0 : double MaxY = getLogicMaxY();
489 0 : double MinZ = getLogicMinZ();
490 0 : double MaxZ = getLogicMaxZ();
491 :
492 0 : doLogicScaling( &MinX, &MinY, &MinZ );
493 0 : doLogicScaling( &MaxX, &MaxY, &MaxZ);
494 :
495 0 : MinAngleValue = m_bSwapXAndY ? MinY : MinX;
496 0 : MaxAngleValue = m_bSwapXAndY ? MaxY : MaxX;
497 : }
498 :
499 0 : double fScaledLogicAngleValue = 0.0;
500 0 : if(bDoScaling)
501 : {
502 0 : double fX = m_bSwapXAndY ? getLogicMaxX() : fLogicValueOnAngleAxis;
503 0 : double fY = m_bSwapXAndY ? fLogicValueOnAngleAxis : getLogicMaxY();
504 0 : double fZ = getLogicMaxZ();
505 0 : clipLogicValues( &fX, &fY, &fZ );
506 0 : doLogicScaling( &fX, &fY, &fZ );
507 0 : fScaledLogicAngleValue = m_bSwapXAndY ? fY : fX;
508 : }
509 : else
510 0 : fScaledLogicAngleValue = fLogicValueOnAngleAxis;
511 :
512 : fRet = m_fAngleDegreeOffset
513 : + fAxisAngleScaleDirection*(fScaledLogicAngleValue-MinAngleValue)*360.0
514 0 : /fabs(MaxAngleValue-MinAngleValue);
515 0 : while(fRet>360.0)
516 0 : fRet-=360.0;
517 0 : while(fRet<0)
518 0 : fRet+=360.0;
519 0 : return fRet;
520 : }
521 :
522 0 : double PolarPlottingPositionHelper::transformToRadius( double fLogicValueOnRadiusAxis, bool bDoScaling ) const
523 : {
524 0 : double fNormalRadius = 0.0;
525 : {
526 0 : double fScaledLogicRadiusValue = 0.0;
527 0 : double fX = m_bSwapXAndY ? fLogicValueOnRadiusAxis: getLogicMaxX();
528 0 : double fY = m_bSwapXAndY ? getLogicMaxY() : fLogicValueOnRadiusAxis;
529 0 : if(bDoScaling)
530 0 : doLogicScaling( &fX, &fY, 0 );
531 :
532 0 : fScaledLogicRadiusValue = m_bSwapXAndY ? fX : fY;
533 :
534 0 : bool bMinIsInnerRadius = true;
535 0 : const ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[0] : m_aScales[1];
536 0 : if(AxisOrientation_MATHEMATICAL != rScale.Orientation)
537 0 : bMinIsInnerRadius = false;
538 :
539 0 : double fInnerScaledLogicRadius=0.0;
540 0 : double fOuterScaledLogicRadius=0.0;
541 : {
542 0 : double MinX = getLogicMinX();
543 0 : double MinY = getLogicMinY();
544 0 : doLogicScaling( &MinX, &MinY, 0 );
545 0 : double MaxX = getLogicMaxX();
546 0 : double MaxY = getLogicMaxY();
547 0 : doLogicScaling( &MaxX, &MaxY, 0 );
548 :
549 0 : double fMin = m_bSwapXAndY ? MinX : MinY;
550 0 : double fMax = m_bSwapXAndY ? MaxX : MaxY;
551 :
552 0 : fInnerScaledLogicRadius = bMinIsInnerRadius ? fMin : fMax;
553 0 : fOuterScaledLogicRadius = bMinIsInnerRadius ? fMax : fMin;
554 : }
555 :
556 0 : if( bMinIsInnerRadius )
557 0 : fInnerScaledLogicRadius -= fabs(m_fRadiusOffset);
558 : else
559 0 : fInnerScaledLogicRadius += fabs(m_fRadiusOffset);
560 0 : fNormalRadius = (fScaledLogicRadiusValue-fInnerScaledLogicRadius)/(fOuterScaledLogicRadius-fInnerScaledLogicRadius);
561 : }
562 0 : 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 0 : drawing::Position3D PolarPlottingPositionHelper::transformUnitCircleToScene( double fUnitAngleDegree, double fUnitRadius
583 : , double fLogicZ, bool /* bDoScaling */ ) const
584 : {
585 0 : double fAnglePi = fUnitAngleDegree*F_PI/180.0;
586 :
587 0 : double fX=fUnitRadius*rtl::math::cos(fAnglePi);
588 0 : double fY=fUnitRadius*rtl::math::sin(fAnglePi);
589 0 : double fZ=fLogicZ;
590 :
591 0 : 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 0 : break;
602 : }
603 :
604 : //!! applying matrix to vector does ignore translation, so it is important to use a B3DPoint here instead of B3DVector
605 0 : ::basegfx::B3DPoint aPoint(fX,fY,fZ);
606 0 : ::basegfx::B3DPoint aRet = m_aUnitCartesianToScene * aPoint;
607 0 : 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 1968 : bool PlottingPositionHelper::isPercentY() const
628 : {
629 1968 : return m_aScales[1].AxisType==AxisType::PERCENT;
630 : }
631 :
632 492 : double PlottingPositionHelper::getBaseValueY() const
633 : {
634 492 : return m_aScales[1].Origin;
635 : }
636 :
637 492 : void PlottingPositionHelper::setTimeResolution( long nTimeResolution, const Date& rNullDate )
638 : {
639 492 : m_nTimeResolution = nTimeResolution;
640 492 : m_aNullDate = rNullDate;
641 :
642 : //adapt category width
643 492 : double fCategoryWidth = 1.0;
644 492 : if( !m_aScales.empty() )
645 : {
646 492 : 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 492 : setScaledCategoryWidth(fCategoryWidth);
657 492 : }
658 :
659 0 : void PlottingPositionHelper::setScaledCategoryWidth( double fScaledCategoryWidth )
660 : {
661 0 : m_fScaledCategoryWidth = fScaledCategoryWidth;
662 0 : }
663 41 : void PlottingPositionHelper::AllowShiftXAxisPos( bool bAllowShift )
664 : {
665 41 : m_bAllowShiftXAxisPos = bAllowShift;
666 41 : }
667 41 : void PlottingPositionHelper::AllowShiftZAxisPos( bool bAllowShift )
668 : {
669 41 : m_bAllowShiftZAxisPos = bAllowShift;
670 41 : }
671 :
672 : }
673 :
674 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|