From 69ce62d8f8cc26d9f9b94e7cc99adab8be736daf Mon Sep 17 00:00:00 2001 From: Vladimir Glazounov Date: Tue, 22 May 2007 18:25:05 +0000 Subject: INTEGRATION: CWS chart2mst3 (1.9.4); FILE MERGED 2006/11/28 17:51:34 iha 1.9.4.24: use ::basegfx::B3DPoint instead of B3DVector to get correct translation 2006/11/23 18:36:06 iha 1.9.4.23: replace DoubleRectangle with B2DRectangle and DoublePoint with B2DTuple 2006/11/22 17:26:45 iha 1.9.4.22: RESYNC: (1.11-1.12); FILE MERGED 2006/11/09 15:28:25 iha 1.9.4.21: #i16280# better performance for charts with many data (bar,column,line,area,xy,net charts) 2006/10/18 17:23:52 bm 1.9.4.20: RESYNC: (1.10-1.11); FILE MERGED 2006/10/11 12:16:55 iha 1.9.4.19: correct donut radius position for reverse orientation 2006/10/06 19:05:07 iha 1.9.4.18: corrected transformation for ring radius 2006/09/24 09:12:58 iha 1.9.4.17: #i61970# correct implementation of axis at 2006/06/09 16:13:19 iha 1.9.4.16: correct fllor position in pie chart 2005/12/03 18:58:40 iha 1.9.4.15: added transformSceneToScreenPosition to enable pie segment dragging 2005/10/24 11:07:15 iha 1.9.4.14: coordinate system restructure 2005/10/07 12:25:55 bm 1.9.4.13: RESYNC: (1.9-1.10); FILE MERGED 2005/09/16 16:50:23 iha 1.9.4.12: no creation of dummy categories in model - instead trigger generation of missing labels and categories in view 2005/08/19 16:12:57 iha 1.9.4.11: implement percent stacking 2004/05/08 17:54:57 iha 1.9.4.10: polartransformation fixes and pie offset implementation 2004/04/14 09:29:49 iha 1.9.4.9: removed unused variable 2004/04/14 08:28:50 iha 1.9.4.8: corrected polar position helper (swapxy-probelms) 2004/03/24 17:23:28 iha 1.9.4.7: added method getLabelAlignmentForDimension 2004/03/23 18:36:08 iha 1.9.4.6: fixed logarithmic polar scale 2004/03/23 14:32:36 iha 1.9.4.5: added mehtod clipScaledLogicValues + renamed getTransformation/Scaled/LogicToScene 2004/03/22 19:31:01 iha 1.9.4.4: transport information bSwapXAndYAxis over method setScales not constructor; m_bRadiusAxisMapsToFirstDimension-->bSwapXAndY 2004/03/22 17:30:35 iha 1.9.4.3: added and used parameter SwapXAndYAxis for horizontal bar chart 2004/03/22 15:37:02 iha 1.9.4.2: added parameter and member SwapXAndYAxis for horizontal bar chart 2004/03/11 11:57:39 iha 1.9.4.1: added method getScaledLogicWidth() --- chart2/source/view/main/PlottingPositionHelper.cxx | 434 +++++++++++++++++---- 1 file changed, 353 insertions(+), 81 deletions(-) (limited to 'chart2/source/view/main/PlottingPositionHelper.cxx') diff --git a/chart2/source/view/main/PlottingPositionHelper.cxx b/chart2/source/view/main/PlottingPositionHelper.cxx index 2aef86893106..bc633485199e 100644 --- a/chart2/source/view/main/PlottingPositionHelper.cxx +++ b/chart2/source/view/main/PlottingPositionHelper.cxx @@ -4,9 +4,9 @@ * * $RCSfile: PlottingPositionHelper.cxx,v $ * - * $Revision: 1.12 $ + * $Revision: 1.13 $ * - * last change: $Author: ihi $ $Date: 2006-11-14 15:36:10 $ + * last change: $Author: vg $ $Date: 2007-05-22 19:25:05 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -39,6 +39,10 @@ #include "CommonConverters.hxx" #include "ViewDefines.hxx" #include "Linear3DTransformation.hxx" +#include "VPolarTransformation.hxx" + +#include "ShapeFactory.hxx" +#include "PropertyMapper.hxx" #ifndef _COM_SUN_STAR_DRAWING_DOUBLESEQUENCE_HPP_ #include @@ -46,6 +50,11 @@ #ifndef _COM_SUN_STAR_DRAWING_POSITION3D_HPP_ #include #endif +#ifndef _COM_SUN_STAR_CHART2_AXISTYPE_HPP_ +#include +#endif + +#include //............................................................................. namespace chart @@ -58,7 +67,20 @@ PlottingPositionHelper::PlottingPositionHelper() : m_aScales() , m_aMatrixScreenToScene() , m_xTransformationLogicToScene(NULL) - + , m_bSwapXAndY( false ) + , m_nXResolution( 1000 ) + , m_nYResolution( 1000 ) + , m_nZResolution( 1000 ) +{ +} +PlottingPositionHelper::PlottingPositionHelper( const PlottingPositionHelper& rSource ) + : m_aScales( rSource.m_aScales ) + , m_aMatrixScreenToScene( rSource.m_aMatrixScreenToScene ) + , m_xTransformationLogicToScene( NULL ) //should be recalculated + , m_bSwapXAndY( rSource.m_bSwapXAndY ) + , m_nXResolution( rSource.m_nXResolution ) + , m_nYResolution( rSource.m_nYResolution ) + , m_nZResolution( rSource.m_nZResolution ) { } @@ -67,15 +89,29 @@ PlottingPositionHelper::~PlottingPositionHelper() } +PlottingPositionHelper* PlottingPositionHelper::clone() const +{ + PlottingPositionHelper* pRet = new PlottingPositionHelper(*this); + return pRet; +} + +PlottingPositionHelper* PlottingPositionHelper::createSecondaryPosHelper( const ExplicitScaleData& rSecondaryScale ) +{ + PlottingPositionHelper* pRet = this->clone(); + pRet->m_aScales[1]=rSecondaryScale; + return pRet; +} + void PlottingPositionHelper::setTransformationSceneToScreen( const drawing::HomogenMatrix& rMatrix) { - m_aMatrixScreenToScene = HomogenMatrixToMatrix4D(rMatrix); + m_aMatrixScreenToScene = HomogenMatrixToB3DHomMatrix(rMatrix); m_xTransformationLogicToScene = NULL; } -void PlottingPositionHelper::setScales( const uno::Sequence< ExplicitScaleData >& rScales ) +void PlottingPositionHelper::setScales( const uno::Sequence< ExplicitScaleData >& rScales, sal_Bool bSwapXAndYAxis ) { m_aScales = rScales; + m_bSwapXAndY = bSwapXAndYAxis; m_xTransformationLogicToScene = NULL; } const uno::Sequence< ExplicitScaleData >& PlottingPositionHelper::getScales() const @@ -83,7 +119,7 @@ const uno::Sequence< ExplicitScaleData >& PlottingPositionHelper::getScales() co return m_aScales; } -uno::Reference< XTransformation > PlottingPositionHelper::getTransformationLogicToScene() const +uno::Reference< XTransformation > PlottingPositionHelper::getTransformationScaledLogicToScene() const { //this is a standard transformation for a cartesian coordinate system @@ -101,19 +137,30 @@ uno::Reference< XTransformation > PlottingPositionHelper::getTransformationLogic double MaxY = getLogicMaxY(); double MaxZ = getLogicMaxZ(); + AxisOrientation nXAxisOrientation = m_aScales[0].Orientation; + AxisOrientation nYAxisOrientation = m_aScales[1].Orientation; + AxisOrientation nZAxisOrientation = m_aScales[2].Orientation; + //apply scaling doLogicScaling( &MinX, &MinY, &MinZ ); doLogicScaling( &MaxX, &MaxY, &MaxZ); - if( AxisOrientation_MATHEMATICAL==m_aScales[0].Orientation ) + if(m_bSwapXAndY) + { + std::swap(MinX,MinY); + std::swap(MaxX,MaxY); + std::swap(nXAxisOrientation,nYAxisOrientation); + } + + if( AxisOrientation_MATHEMATICAL==nXAxisOrientation ) aMatrix.translate(-MinX, 0.0, 0.0); else aMatrix.translate(-MaxX, 0.0, 0.0); - if( AxisOrientation_MATHEMATICAL==m_aScales[1].Orientation ) + if( AxisOrientation_MATHEMATICAL==nYAxisOrientation ) aMatrix.translate(0.0, -MinY, 0.0); else aMatrix.translate(0.0, -MaxY, 0.0); - if( AxisOrientation_MATHEMATICAL==m_aScales[2].Orientation ) + if( AxisOrientation_MATHEMATICAL==nZAxisOrientation ) aMatrix.translate(0.0, 0.0, -MaxZ);//z direction in draw is reverse mathematical direction else aMatrix.translate(0.0, 0.0, -MinZ); @@ -122,9 +169,9 @@ uno::Reference< XTransformation > PlottingPositionHelper::getTransformationLogic double fWidthY = MaxY - MinY; double fWidthZ = MaxZ - MinZ; - double fScaleDirectionX = AxisOrientation_MATHEMATICAL==m_aScales[0].Orientation ? 1.0 : -1.0; - double fScaleDirectionY = AxisOrientation_MATHEMATICAL==m_aScales[1].Orientation ? 1.0 : -1.0; - double fScaleDirectionZ = AxisOrientation_MATHEMATICAL==m_aScales[2].Orientation ? -1.0 : 1.0; + double fScaleDirectionX = AxisOrientation_MATHEMATICAL==nXAxisOrientation ? 1.0 : -1.0; + double fScaleDirectionY = AxisOrientation_MATHEMATICAL==nYAxisOrientation ? 1.0 : -1.0; + double fScaleDirectionZ = AxisOrientation_MATHEMATICAL==nZAxisOrientation ? -1.0 : 1.0; aMatrix.scale(fScaleDirectionX*FIXED_SIZE_FOR_3D_CHART_VOLUME/fWidthX, fScaleDirectionY*FIXED_SIZE_FOR_3D_CHART_VOLUME/fWidthY, @@ -132,7 +179,7 @@ uno::Reference< XTransformation > PlottingPositionHelper::getTransformationLogic aMatrix = m_aMatrixScreenToScene*aMatrix; - m_xTransformationLogicToScene = new Linear3DTransformation(Matrix4DToHomogenMatrix( aMatrix )); + m_xTransformationLogicToScene = new Linear3DTransformation(B3DHomMatrixToHomogenMatrix( aMatrix ),m_bSwapXAndY); } return m_xTransformationLogicToScene; } @@ -143,15 +190,49 @@ drawing::Position3D PlottingPositionHelper::transformLogicToScene( if(bClip) this->clipLogicValues( &fX,&fY,&fZ ); this->doLogicScaling( &fX,&fY,&fZ ); + + return this->transformScaledLogicToScene( fX, fY, fZ, false ); +} + +drawing::Position3D PlottingPositionHelper::transformScaledLogicToScene( + double fX, double fY, double fZ, bool bClip ) const +{ + if( bClip ) + this->clipScaledLogicValues( &fX,&fY,&fZ ); + drawing::Position3D aPos( fX, fY, fZ); uno::Reference< XTransformation > xTransformation = - this->getTransformationLogicToScene(); + this->getTransformationScaledLogicToScene(); uno::Sequence< double > aSeq = xTransformation->transform( Position3DToSequence(aPos) ); return SequenceToPosition3D(aSeq); } +//static +awt::Point PlottingPositionHelper::transformSceneToScreenPosition( const drawing::Position3D& rScenePosition3D + , const uno::Reference< drawing::XShapes >& xSceneTarget + , ShapeFactory* pShapeFactory + , sal_Int32 nDimensionCount ) +{ + //@todo would like to have a cheaper method to do this transformation + awt::Point aScreenPoint( static_cast(rScenePosition3D.PositionX), static_cast(rScenePosition3D.PositionY) ); + + //transformation from scene to screen (only neccessary for 3D): + if(3==nDimensionCount) + { + //create 3D anchor shape + tPropertyNameMap aDummyPropertyNameMap; + uno::Reference< drawing::XShape > xShape3DAnchor = pShapeFactory->createCube( xSceneTarget + , rScenePosition3D,drawing::Direction3D(1,1,1) + , 0, 0, aDummyPropertyNameMap); + //get 2D position from xShape3DAnchor + aScreenPoint = xShape3DAnchor->getPosition(); + xSceneTarget->remove(xShape3DAnchor); + } + return aScreenPoint; +} + void PlottingPositionHelper::transformScaledLogicToScene( drawing::PolyPolygonShape3D& rPolygon ) const { drawing::Position3D aScenePosition; @@ -165,7 +246,7 @@ void PlottingPositionHelper::transformScaledLogicToScene( drawing::PolyPolygonSh double& fX = xValues[nP]; double& fY = yValues[nP]; double& fZ = zValues[nP]; - aScenePosition = this->transformLogicToScene( fX,fY,fZ,true ); + aScenePosition = this->transformScaledLogicToScene( fX,fY,fZ,true ); fX = aScenePosition.PositionX; fY = aScenePosition.PositionY; fZ = aScenePosition.PositionZ; @@ -173,7 +254,8 @@ void PlottingPositionHelper::transformScaledLogicToScene( drawing::PolyPolygonSh } } -DoubleRectangle PlottingPositionHelper::getScaledLogicClipDoubleRect() const + +void PlottingPositionHelper::clipScaledLogicValues( double* pX, double* pY, double* pZ ) const { //get logic clip values: double MinX = getLogicMinX(); @@ -187,7 +269,78 @@ DoubleRectangle PlottingPositionHelper::getScaledLogicClipDoubleRect() const doLogicScaling( &MinX, &MinY, &MinZ ); doLogicScaling( &MaxX, &MaxY, &MaxZ); - DoubleRectangle aRet( MinX, MaxY, MaxX, MinY ); + if(pX) + { + if( *pX < MinX ) + *pX = MinX; + else if( *pX > MaxX ) + *pX = MaxX; + } + if(pY) + { + if( *pY < MinY ) + *pY = MinY; + else if( *pY > MaxY ) + *pY = MaxY; + } + if(pZ) + { + if( *pZ < MinZ ) + *pZ = MinZ; + else if( *pZ > MaxZ ) + *pZ = MaxZ; + } +} + +basegfx::B2DRectangle PlottingPositionHelper::getScaledLogicClipDoubleRect() const +{ + //get logic clip values: + double MinX = getLogicMinX(); + double MinY = getLogicMinY(); + double MinZ = getLogicMinZ(); + double MaxX = getLogicMaxX(); + double MaxY = getLogicMaxY(); + double MaxZ = getLogicMaxZ(); + + //apply scaling + doLogicScaling( &MinX, &MinY, &MinZ ); + doLogicScaling( &MaxX, &MaxY, &MaxZ); + + basegfx::B2DRectangle aRet( MinX, MaxY, MaxX, MinY ); + return aRet; +} + +drawing::Direction3D PlottingPositionHelper::getScaledLogicWidth() const +{ + drawing::Direction3D aRet; + + double MinX = getLogicMinX(); + double MinY = getLogicMinY(); + double MinZ = getLogicMinZ(); + double MaxX = getLogicMaxX(); + double MaxY = getLogicMaxY(); + double MaxZ = getLogicMaxZ(); + + doLogicScaling( &MinX, &MinY, &MinZ ); + doLogicScaling( &MaxX, &MaxY, &MaxZ); + + aRet.DirectionX = MaxX - MinX; + aRet.DirectionY = MaxY - MinY; + aRet.DirectionZ = MaxZ - MinZ; + return aRet; +} + +LabelAlignment PlottingPositionHelper::getLabelAlignmentForDimension( sal_Int32 nDimensionIndex ) const +{ + LabelAlignment aRet(LABEL_ALIGN_CENTER); + if( nDimensionIndex==0 && !m_bSwapXAndY ) + aRet = LABEL_ALIGN_RIGHT; + else if( nDimensionIndex==1 && m_bSwapXAndY ) + aRet = LABEL_ALIGN_RIGHT; + else if( nDimensionIndex==1 && !m_bSwapXAndY ) + aRet = LABEL_ALIGN_TOP; + else if( nDimensionIndex==0 && m_bSwapXAndY ) + aRet = LABEL_ALIGN_TOP; return aRet; } @@ -195,10 +348,20 @@ DoubleRectangle PlottingPositionHelper::getScaledLogicClipDoubleRect() const //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -PolarPlottingPositionHelper::PolarPlottingPositionHelper( bool bRadiusAxisMapsToFirstDimension ) +PolarPlottingPositionHelper::PolarPlottingPositionHelper( NormalAxis eNormalAxis ) : m_fRadiusOffset(0.0) , m_fAngleDegreeOffset(90.0) - , m_bRadiusAxisMapsToFirstDimension(bRadiusAxisMapsToFirstDimension) + , m_aUnitCartesianToScene() + , m_eNormalAxis(eNormalAxis) +{ +} + +PolarPlottingPositionHelper::PolarPlottingPositionHelper( const PolarPlottingPositionHelper& rSource ) + : PlottingPositionHelper(rSource) + , m_fRadiusOffset( rSource.m_fRadiusOffset ) + , m_fAngleDegreeOffset( rSource.m_fAngleDegreeOffset ) + , m_aUnitCartesianToScene( rSource.m_aUnitCartesianToScene ) + , m_eNormalAxis( rSource.m_eNormalAxis ) { } @@ -206,48 +369,103 @@ PolarPlottingPositionHelper::~PolarPlottingPositionHelper() { } -uno::Reference< XTransformation > PolarPlottingPositionHelper::getTransformationLogicToScene() const +PlottingPositionHelper* PolarPlottingPositionHelper::clone() const { - //transformation from 2) to 4) //@todo 2) and 4) need a ink to a document + PolarPlottingPositionHelper* pRet = new PolarPlottingPositionHelper(*this); + return pRet; +} + +void PolarPlottingPositionHelper::setTransformationSceneToScreen( const drawing::HomogenMatrix& rMatrix) +{ + PlottingPositionHelper::setTransformationSceneToScreen( rMatrix); + m_aUnitCartesianToScene =impl_calculateMatrixUnitCartesianToScene( m_aMatrixScreenToScene ); +} +void PolarPlottingPositionHelper::setScales( const uno::Sequence< ExplicitScaleData >& rScales, sal_Bool bSwapXAndYAxis ) +{ + PlottingPositionHelper::setScales( rScales, bSwapXAndYAxis ); + m_aUnitCartesianToScene =impl_calculateMatrixUnitCartesianToScene( m_aMatrixScreenToScene ); +} - //?? need to apply this transformation to each geometric object, or would group be sufficient?? +::basegfx::B3DHomMatrix PolarPlottingPositionHelper::impl_calculateMatrixUnitCartesianToScene( const ::basegfx::B3DHomMatrix& rMatrixScreenToScene ) const +{ + ::basegfx::B3DHomMatrix aRet; - if( !m_xTransformationLogicToScene.is() ) + if( !m_aScales.getLength() ) + return aRet; + + double fTranslate =1.0; + double fScale =FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0; + + double fTranslateLogicZ =fTranslate; + double fScaleLogicZ =fScale; { - double MinX = getLogicMinX(); - double MinY = getLogicMinY(); + double fScaleDirectionZ = AxisOrientation_MATHEMATICAL==m_aScales[2].Orientation ? 1.0 : -1.0; double MinZ = getLogicMinZ(); - double MaxX = getLogicMaxX(); - double MaxY = getLogicMaxY(); double MaxZ = getLogicMaxZ(); + doLogicScaling( 0, 0, &MinZ ); + doLogicScaling( 0, 0, &MaxZ ); + double fWidthZ = MaxZ - MinZ; - //apply scaling - doLogicScaling( &MinX, &MinY, &MinZ ); - doLogicScaling( &MaxX, &MaxY, &MaxZ); + if( AxisOrientation_MATHEMATICAL==m_aScales[2].Orientation ) + fTranslateLogicZ=MinZ; + else + fTranslateLogicZ=MaxZ; + fScaleLogicZ = fScaleDirectionZ*FIXED_SIZE_FOR_3D_CHART_VOLUME/fWidthZ; + } - double fLogicDiameter = 2*(fabs(MaxY - MinY) + m_fRadiusOffset); - if( m_bRadiusAxisMapsToFirstDimension ) - fLogicDiameter = 2*(fabs(MaxX - MinX) + m_fRadiusOffset); + double fTranslateX = fTranslate; + double fTranslateY = fTranslate; + double fTranslateZ = fTranslate; - double fScaleDirectionZ = AxisOrientation_MATHEMATICAL==m_aScales[2].Orientation ? 1.0 : -1.0; + double fScaleX = fScale; + double fScaleY = fScale; + double fScaleZ = fScale; - ::basegfx::B3DHomMatrix aMatrix; - //the middle of the pie circle is the middle of the diagram - aMatrix.translate(fLogicDiameter/2.0, 0.0, 0.0); - aMatrix.scale(FIXED_SIZE_FOR_3D_CHART_VOLUME/fLogicDiameter, 1.0, 1.0); + switch(m_eNormalAxis) + { + case NormalAxis_X: + { + fTranslateX = fTranslateLogicZ; + fScaleX = fScaleLogicZ; + } + break; + case NormalAxis_Y: + { + fTranslateY = fTranslateLogicZ; + fScaleY = fScaleLogicZ; + } + break; + default: //NormalAxis_Z: + { + fTranslateZ = fTranslateLogicZ; + fScaleZ = fScaleLogicZ; + } + break; + } - aMatrix.translate(0.0, fLogicDiameter/2.0, 0.0); - aMatrix.scale(1.0, FIXED_SIZE_FOR_3D_CHART_VOLUME/fLogicDiameter, fScaleDirectionZ*FIXED_SIZE_FOR_3D_CHART_VOLUME); - aMatrix = m_aMatrixScreenToScene*aMatrix; + aRet.translate(fTranslateX, fTranslateY, fTranslateZ);//x first + aRet.scale(fScaleX, fScaleY, fScaleZ);//x first - m_xTransformationLogicToScene = new Linear3DTransformation(Matrix4DToHomogenMatrix( aMatrix )); - } + aRet = rMatrixScreenToScene * aRet; + return aRet; +} + +::basegfx::B3DHomMatrix PolarPlottingPositionHelper::getUnitCartesianToScene() const +{ + return m_aUnitCartesianToScene; +} + +uno::Reference< XTransformation > PolarPlottingPositionHelper::getTransformationScaledLogicToScene() const +{ + if( !m_xTransformationLogicToScene.is() ) + m_xTransformationLogicToScene = new VPolarTransformation(*this); return m_xTransformationLogicToScene; } double PolarPlottingPositionHelper::getWidthAngleDegree( double& fStartLogicValueOnAngleAxis, double& fEndLogicValueOnAngleAxis ) const { - if( !this->isMathematicalOrientationY() ) + const ExplicitScaleData& rAngleScale = m_bSwapXAndY ? m_aScales[1] : m_aScales[0]; + if( AxisOrientation_MATHEMATICAL != rAngleScale.Orientation ) { double fHelp = fEndLogicValueOnAngleAxis; fEndLogicValueOnAngleAxis = fStartLogicValueOnAngleAxis; @@ -266,13 +484,13 @@ double PolarPlottingPositionHelper::getWidthAngleDegree( double& fStartLogicValu return fWidthAngleDegree; } -double PolarPlottingPositionHelper::transformToAngleDegree( double fLogicValueOnAngleAxis ) const +double PolarPlottingPositionHelper::transformToAngleDegree( double fLogicValueOnAngleAxis, bool bDoScaling ) const { double fRet=0.0; double fAxisAngleScaleDirection = 1.0; { - const ExplicitScaleData& rScale = m_bRadiusAxisMapsToFirstDimension ? m_aScales[1] : m_aScales[0]; + const ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[1] : m_aScales[0]; if(AxisOrientation_MATHEMATICAL != rScale.Orientation) fAxisAngleScaleDirection *= -1.0; } @@ -290,19 +508,22 @@ double PolarPlottingPositionHelper::transformToAngleDegree( double fLogicValueOn doLogicScaling( &MinX, &MinY, &MinZ ); doLogicScaling( &MaxX, &MaxY, &MaxZ); - MinAngleValue = m_bRadiusAxisMapsToFirstDimension ? MinY : MinX; - MaxAngleValue = m_bRadiusAxisMapsToFirstDimension ? MaxY : MaxX; + MinAngleValue = m_bSwapXAndY ? MinY : MinX; + MaxAngleValue = m_bSwapXAndY ? MaxY : MaxX; } double fScaledLogicAngleValue = 0.0; + if(bDoScaling) { - double fX = m_bRadiusAxisMapsToFirstDimension ? getLogicMaxX() : fLogicValueOnAngleAxis; - double fY = m_bRadiusAxisMapsToFirstDimension ? fLogicValueOnAngleAxis : getLogicMaxY(); + double fX = m_bSwapXAndY ? getLogicMaxX() : fLogicValueOnAngleAxis; + double fY = m_bSwapXAndY ? fLogicValueOnAngleAxis : getLogicMaxY(); double fZ = getLogicMaxZ(); clipLogicValues( &fX, &fY, &fZ ); doLogicScaling( &fX, &fY, &fZ ); - fScaledLogicAngleValue = m_bRadiusAxisMapsToFirstDimension ? fY : fX; + fScaledLogicAngleValue = m_bSwapXAndY ? fY : fX; } + else + fScaledLogicAngleValue = fLogicValueOnAngleAxis; fRet = m_fAngleDegreeOffset + fAxisAngleScaleDirection*(fScaledLogicAngleValue-MinAngleValue)*360.0 @@ -314,64 +535,105 @@ double PolarPlottingPositionHelper::transformToAngleDegree( double fLogicValueOn return fRet; } -double PolarPlottingPositionHelper::transformToRadius( double fLogicValueOnRadiusAxis ) const +double PolarPlottingPositionHelper::transformToRadius( double fLogicValueOnRadiusAxis, bool bDoScaling ) const { - double fRet=0.0; - - double fScaledLogicRadiusValue = 0.0; + double fNormalRadius = 0.0; { - double fX = m_bRadiusAxisMapsToFirstDimension ? fLogicValueOnRadiusAxis: getLogicMaxX(); - double fY = m_bRadiusAxisMapsToFirstDimension ? getLogicMaxY() : fLogicValueOnRadiusAxis; - doLogicScaling( &fX, &fY, 0 ); + double fScaledLogicRadiusValue = 0.0; + double fX = m_bSwapXAndY ? fLogicValueOnRadiusAxis: getLogicMaxX(); + double fY = m_bSwapXAndY ? getLogicMaxY() : fLogicValueOnRadiusAxis; + if(bDoScaling) + doLogicScaling( &fX, &fY, 0 ); - fScaledLogicRadiusValue = m_fRadiusOffset + ( m_bRadiusAxisMapsToFirstDimension ? fX : fY ); + fScaledLogicRadiusValue = m_bSwapXAndY ? fX : fY; bool bMinIsInnerRadius = true; - const ExplicitScaleData& rScale = m_bRadiusAxisMapsToFirstDimension ? m_aScales[0] : m_aScales[1]; + const ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[0] : m_aScales[1]; if(AxisOrientation_MATHEMATICAL != rScale.Orientation) bMinIsInnerRadius = false; - if(bMinIsInnerRadius) + + double fInnerScaledLogicRadius=0.0; + double fOuterScaledLogicRadius=0.0; { double MinX = getLogicMinX(); double MinY = getLogicMinY(); doLogicScaling( &MinX, &MinY, 0 ); - fScaledLogicRadiusValue -= ( m_bRadiusAxisMapsToFirstDimension ? MinX : MinY ); - } - else - { double MaxX = getLogicMaxX(); double MaxY = getLogicMaxY(); doLogicScaling( &MaxX, &MaxY, 0 ); - fScaledLogicRadiusValue -= ( m_bRadiusAxisMapsToFirstDimension ? MaxX : MaxY ); + + double fMin = m_bSwapXAndY ? MinX : MinY; + double fMax = m_bSwapXAndY ? MaxX : MaxY; + + fInnerScaledLogicRadius = bMinIsInnerRadius ? fMin : fMax; + fOuterScaledLogicRadius = bMinIsInnerRadius ? fMax : fMin; } + + if( bMinIsInnerRadius ) + fInnerScaledLogicRadius -= abs(m_fRadiusOffset); + else + fInnerScaledLogicRadius += abs(m_fRadiusOffset); + fNormalRadius = (fScaledLogicRadiusValue-fInnerScaledLogicRadius)/(fOuterScaledLogicRadius-fInnerScaledLogicRadius); } - return fScaledLogicRadiusValue; + return fNormalRadius; } drawing::Position3D PolarPlottingPositionHelper::transformLogicToScene( double fX, double fY, double fZ, bool bClip ) const { if(bClip) this->clipLogicValues( &fX,&fY,&fZ ); - double fLogicValueOnAngleAxis = m_bRadiusAxisMapsToFirstDimension ? fY : fX; - double fLogicValueOnRadiusAxis = m_bRadiusAxisMapsToFirstDimension ? fX : fY; - return this->transformLogicToScene( fLogicValueOnAngleAxis, fLogicValueOnRadiusAxis, fZ ); + double fLogicValueOnAngleAxis = m_bSwapXAndY ? fY : fX; + double fLogicValueOnRadiusAxis = m_bSwapXAndY ? fX : fY; + return this->transformAngleRadiusToScene( fLogicValueOnAngleAxis, fLogicValueOnRadiusAxis, fZ, true ); +} + +drawing::Position3D PolarPlottingPositionHelper::transformScaledLogicToScene( double fX, double fY, double fZ, bool bClip ) const +{ + if(bClip) + this->clipScaledLogicValues( &fX,&fY,&fZ ); + double fLogicValueOnAngleAxis = m_bSwapXAndY ? fY : fX; + double fLogicValueOnRadiusAxis = m_bSwapXAndY ? fX : fY; + return this->transformAngleRadiusToScene( fLogicValueOnAngleAxis, fLogicValueOnRadiusAxis, fZ, false ); } +drawing::Position3D PolarPlottingPositionHelper::transformUnitCircleToScene( double fUnitAngleDegree, double fUnitRadius + , double fLogicZ, bool bDoScaling ) const +{ + double fAnglePi = fUnitAngleDegree*F_PI/180.0; + + double fX=fUnitRadius*rtl::math::cos(fAnglePi); + double fY=fUnitRadius*rtl::math::sin(fAnglePi); + double fZ=fLogicZ; -drawing::Position3D PolarPlottingPositionHelper::transformLogicToScene( double fLogicValueOnAngleAxis, double fLogicValueOnRadiusAxis, double fLogicZ ) const + switch(m_eNormalAxis) + { + case NormalAxis_X: + std::swap(fX,fZ); + break; + case NormalAxis_Y: + std::swap(fY,fZ); + fZ*=-1; + break; + default: //NormalAxis_Z + break; + } + + //!! applying matrix to vector does ignore translation, so it is important to use a B3DPoint here instead of B3DVector + ::basegfx::B3DPoint aPoint(fX,fY,fZ); + ::basegfx::B3DPoint aRet = m_aUnitCartesianToScene * aPoint; + return B3DPointToPosition3D(aRet); +} + +drawing::Position3D PolarPlottingPositionHelper::transformAngleRadiusToScene( double fLogicValueOnAngleAxis, double fLogicValueOnRadiusAxis, double fLogicZ, bool bDoScaling ) const { - double fAngleDegree = this->transformToAngleDegree(fLogicValueOnAngleAxis); - double fAnglePi = fAngleDegree*F_PI/180.0; - double fRadius = this->transformToRadius(fLogicValueOnRadiusAxis); - drawing::Position3D aLogicPos(fRadius*cos(fAnglePi),fRadius*sin(fAnglePi),fLogicZ+0.5); - drawing::Position3D aScenePosition3D( SequenceToPosition3D( - this->getTransformationLogicToScene()->transform( - Position3DToSequence(aLogicPos) ) ) ); - return aScenePosition3D; + double fUnitAngleDegree = this->transformToAngleDegree(fLogicValueOnAngleAxis,bDoScaling); + double fUnitRadius = this->transformToRadius(fLogicValueOnRadiusAxis,bDoScaling); + + return transformUnitCircleToScene( fUnitAngleDegree, fUnitRadius, fLogicZ, bDoScaling ); } double PolarPlottingPositionHelper::getInnerLogicRadius() const { - const ExplicitScaleData& rScale = m_bRadiusAxisMapsToFirstDimension ? m_aScales[0] : m_aScales[1]; + const ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[0] : m_aScales[1]; if( AxisOrientation_MATHEMATICAL==rScale.Orientation ) return rScale.Minimum; else @@ -380,13 +642,23 @@ double PolarPlottingPositionHelper::getInnerLogicRadius() const double PolarPlottingPositionHelper::getOuterLogicRadius() const { - const ExplicitScaleData& rScale = m_bRadiusAxisMapsToFirstDimension ? m_aScales[0] : m_aScales[1]; + const ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[0] : m_aScales[1]; if( AxisOrientation_MATHEMATICAL==rScale.Orientation ) return rScale.Maximum; else return rScale.Minimum; } +bool PlottingPositionHelper::isPercentY() const +{ + return m_aScales[1].AxisType==AxisType::PERCENT; +} + +double PlottingPositionHelper::getBaseValueY() const +{ + return m_aScales[1].Origin; +} + /* // ____ XTransformation ____ uno::Sequence< double > SAL_CALL PolarPlottingPositionHelper::transform( -- cgit