office-gobmx/chart2/source/view/inc/PlottingPositionHelper.hxx

406 lines
16 KiB
C++

/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2010 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
#ifndef _CHART2_PLOTTINGPOSITIONHELPER_HXX
#define _CHART2_PLOTTINGPOSITIONHELPER_HXX
#include "LabelAlignment.hxx"
#include <basegfx/range/b2drectangle.hxx>
#include <rtl/math.hxx>
#include <com/sun/star/chart2/ExplicitScaleData.hpp>
#include <com/sun/star/chart2/XTransformation.hpp>
#include <com/sun/star/drawing/Direction3D.hpp>
#include <com/sun/star/drawing/HomogenMatrix.hpp>
#include <com/sun/star/drawing/PolyPolygonShape3D.hpp>
#include <com/sun/star/drawing/Position3D.hpp>
#include <com/sun/star/drawing/XShapes.hpp>
#include <basegfx/matrix/b3dhommatrix.hxx>
/*
//for WeakImplHelper1
#include <cppuhelper/implbase1.hxx>
*/
//.............................................................................
namespace chart
{
//.............................................................................
class ShapeFactory;
//-----------------------------------------------------------------------------
/**
*/
class PlottingPositionHelper
{
public:
PlottingPositionHelper();
PlottingPositionHelper( const PlottingPositionHelper& rSource );
virtual ~PlottingPositionHelper();
virtual PlottingPositionHelper* clone() const;
virtual PlottingPositionHelper* createSecondaryPosHelper( const ::com::sun::star::chart2::ExplicitScaleData& rSecondaryScale );
virtual void setTransformationSceneToScreen( const ::com::sun::star::drawing::HomogenMatrix& rMatrix);
virtual void setScales( const ::com::sun::star::uno::Sequence<
::com::sun::star::chart2::ExplicitScaleData >& rScales
, sal_Bool bSwapXAndYAxis );
const ::com::sun::star::uno::Sequence<
::com::sun::star::chart2::ExplicitScaleData >& getScales() const;
//better performance for big data
inline void setCoordinateSystemResolution( const ::com::sun::star::uno::Sequence< sal_Int32 >& rCoordinateSystemResolution );
inline bool isSameForGivenResolution( double fX, double fY, double fZ
, double fX2, double fY2, double fZ2 );
inline bool isLogicVisible( double fX, double fY, double fZ ) const;
inline void doLogicScaling( double* pX, double* pY, double* pZ, bool bClip=false ) const;
inline void clipLogicValues( double* pX, double* pY, double* pZ ) const;
void clipScaledLogicValues( double* pX, double* pY, double* pZ ) const;
inline bool clipYRange( double& rMin, double& rMax ) const;
inline void doLogicScaling( ::com::sun::star::drawing::Position3D& rPos, bool bClip=false ) const;
virtual ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XTransformation >
getTransformationScaledLogicToScene() const;
virtual ::com::sun::star::drawing::Position3D
transformLogicToScene( double fX, double fY, double fZ, bool bClip ) const;
virtual ::com::sun::star::drawing::Position3D
transformScaledLogicToScene( double fX, double fY, double fZ, bool bClip ) const;
void transformScaledLogicToScene( ::com::sun::star::drawing::PolyPolygonShape3D& rPoly ) const;
static com::sun::star::awt::Point transformSceneToScreenPosition(
const com::sun::star::drawing::Position3D& rScenePosition3D
, const com::sun::star::uno::Reference< com::sun::star::drawing::XShapes >& xSceneTarget
, ShapeFactory* pShapeFactory, sal_Int32 nDimensionCount );
inline double getLogicMinX() const;
inline double getLogicMinY() const;
inline double getLogicMinZ() const;
inline double getLogicMaxX() const;
inline double getLogicMaxY() const;
inline double getLogicMaxZ() const;
inline bool isMathematicalOrientationX() const;
inline bool isMathematicalOrientationY() const;
inline bool isMathematicalOrientationZ() const;
::basegfx::B2DRectangle getScaledLogicClipDoubleRect() const;
::com::sun::star::drawing::Direction3D getScaledLogicWidth() const;
inline bool isSwapXAndY() const;
bool isPercentY() const;
double getBaseValueY() const;
inline bool maySkipPointsInRegressionCalculation() const;
protected: //member
::com::sun::star::uno::Sequence<
::com::sun::star::chart2::ExplicitScaleData > m_aScales;
::basegfx::B3DHomMatrix m_aMatrixScreenToScene;
//this is calculated based on m_aScales and m_aMatrixScreenToScene
mutable ::com::sun::star::uno::Reference<
::com::sun::star::chart2::XTransformation > m_xTransformationLogicToScene;
bool m_bSwapXAndY;//e.g. true for bar chart and false for column chart
sal_Int32 m_nXResolution;
sal_Int32 m_nYResolution;
sal_Int32 m_nZResolution;
bool m_bMaySkipPointsInRegressionCalculation;
};
//describes wich axis of the drawinglayer scene or sreen axis are the normal axis
enum NormalAxis
{
NormalAxis_X
, NormalAxis_Y
, NormalAxis_Z
};
class PolarPlottingPositionHelper : public PlottingPositionHelper
/*
, public ::cppu::WeakImplHelper1<
::com::sun::star::chart2::XTransformation >
*/
{
public:
PolarPlottingPositionHelper( NormalAxis eNormalAxis=NormalAxis_Z );
PolarPlottingPositionHelper( const PolarPlottingPositionHelper& rSource );
virtual ~PolarPlottingPositionHelper();
virtual PlottingPositionHelper* clone() const;
virtual void setTransformationSceneToScreen( const ::com::sun::star::drawing::HomogenMatrix& rMatrix);
virtual void setScales( const ::com::sun::star::uno::Sequence<
::com::sun::star::chart2::ExplicitScaleData >& rScales
, sal_Bool bSwapXAndYAxis );
::basegfx::B3DHomMatrix getUnitCartesianToScene() const;
virtual ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XTransformation >
getTransformationScaledLogicToScene() const;
//the resulting values should be used for input to the transformation
//received with 'getTransformationScaledLogicToScene'
double transformToRadius( double fLogicValueOnRadiusAxis, bool bDoScaling=true ) const;
double transformToAngleDegree( double fLogicValueOnAngleAxis, bool bDoScaling=true ) const;
double getWidthAngleDegree( double& fStartLogicValueOnAngleAxis, double& fEndLogicValueOnAngleAxis ) const;
//
virtual ::com::sun::star::drawing::Position3D
transformLogicToScene( double fX, double fY, double fZ, bool bClip ) const;
virtual ::com::sun::star::drawing::Position3D
transformScaledLogicToScene( double fX, double fY, double fZ, bool bClip ) const;
::com::sun::star::drawing::Position3D
transformAngleRadiusToScene( double fLogicValueOnAngleAxis, double fLogicValueOnRadiusAxis, double fLogicZ, bool bDoScaling=true ) const;
::com::sun::star::drawing::Position3D
transformUnitCircleToScene( double fUnitAngleDegree, double fUnitRadius, double fLogicZ, bool bDoScaling=true ) const;
using PlottingPositionHelper::transformScaledLogicToScene;
#ifdef NOTYET
double getInnerLogicRadius() const;
#endif
double getOuterLogicRadius() const;
inline bool isMathematicalOrientationAngle() const;
inline bool isMathematicalOrientationRadius() const;
/*
// ____ XTransformation ____
/// @see ::com::sun::star::chart2::XTransformation
virtual ::com::sun::star::uno::Sequence< double > SAL_CALL transform(
const ::com::sun::star::uno::Sequence< double >& rSourceValues )
throw (::com::sun::star::lang::IllegalArgumentException,
::com::sun::star::uno::RuntimeException);
/// @see ::com::sun::star::chart2::XTransformation
virtual sal_Int32 SAL_CALL getSourceDimension()
throw (::com::sun::star::uno::RuntimeException);
/// @see ::com::sun::star::chart2::XTransformation
virtual sal_Int32 SAL_CALL getTargetDimension()
throw (::com::sun::star::uno::RuntimeException);
*/
public:
//Offset for radius axis in absolute logic scaled values (1.0 == 1 category)
double m_fRadiusOffset;
//Offset for angle axis in real degree
double m_fAngleDegreeOffset;
private:
::basegfx::B3DHomMatrix m_aUnitCartesianToScene;
NormalAxis m_eNormalAxis;
::basegfx::B3DHomMatrix impl_calculateMatrixUnitCartesianToScene( const ::basegfx::B3DHomMatrix& rMatrixScreenToScene ) const;
};
bool PolarPlottingPositionHelper::isMathematicalOrientationAngle() const
{
const ::com::sun::star::chart2::ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[1] : m_aScales[2];
if( ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL==rScale.Orientation )
return true;
return false;
}
bool PolarPlottingPositionHelper::isMathematicalOrientationRadius() const
{
const ::com::sun::star::chart2::ExplicitScaleData& rScale = m_bSwapXAndY ? m_aScales[0] : m_aScales[1];
if( ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL==rScale.Orientation )
return true;
return false;
}
//better performance for big data
void PlottingPositionHelper::setCoordinateSystemResolution( const ::com::sun::star::uno::Sequence< sal_Int32 >& rCoordinateSystemResolution )
{
m_nXResolution = 1000;
m_nYResolution = 1000;
m_nZResolution = 1000;
if( rCoordinateSystemResolution.getLength() > 0 )
m_nXResolution = rCoordinateSystemResolution[0];
if( rCoordinateSystemResolution.getLength() > 1 )
m_nYResolution = rCoordinateSystemResolution[1];
if( rCoordinateSystemResolution.getLength() > 2 )
m_nZResolution = rCoordinateSystemResolution[2];
}
bool PlottingPositionHelper::isSameForGivenResolution( double fX, double fY, double fZ
, double fX2, double fY2, double fZ2 /*these values are all expected tp be scaled already*/ )
{
if( !::rtl::math::isFinite(fX) || !::rtl::math::isFinite(fY) || !::rtl::math::isFinite(fZ)
|| !::rtl::math::isFinite(fX2) || !::rtl::math::isFinite(fY2) || !::rtl::math::isFinite(fZ2) )
return false;
double fScaledMinX = getLogicMinX();
double fScaledMinY = getLogicMinY();
double fScaledMinZ = getLogicMinZ();
double fScaledMaxX = getLogicMaxX();
double fScaledMaxY = getLogicMaxY();
double fScaledMaxZ = getLogicMaxZ();
doLogicScaling( &fScaledMinX, &fScaledMinY, &fScaledMinZ );
doLogicScaling( &fScaledMaxX, &fScaledMaxY, &fScaledMaxZ);
bool bSameX = ( static_cast<sal_Int32>(m_nXResolution*(fX - fScaledMinX)/(fScaledMaxX-fScaledMinX))
== static_cast<sal_Int32>(m_nXResolution*(fX2 - fScaledMinX)/(fScaledMaxX-fScaledMinX)) );
bool bSameY = ( static_cast<sal_Int32>(m_nYResolution*(fY - fScaledMinY)/(fScaledMaxY-fScaledMinY))
== static_cast<sal_Int32>(m_nYResolution*(fY2 - fScaledMinY)/(fScaledMaxY-fScaledMinY)) );
bool bSameZ = ( static_cast<sal_Int32>(m_nZResolution*(fZ - fScaledMinZ)/(fScaledMaxZ-fScaledMinZ))
== static_cast<sal_Int32>(m_nZResolution*(fZ2 - fScaledMinZ)/(fScaledMaxZ-fScaledMinZ)) );
return (bSameX && bSameY && bSameZ);
}
bool PlottingPositionHelper::isLogicVisible(
double fX, double fY, double fZ ) const
{
return fX >= m_aScales[0].Minimum && fX <= m_aScales[0].Maximum
&& fY >= m_aScales[1].Minimum && fY <= m_aScales[1].Maximum
&& fZ >= m_aScales[2].Minimum && fZ <= m_aScales[2].Maximum;
}
void PlottingPositionHelper::doLogicScaling( double* pX, double* pY, double* pZ, bool bClip ) const
{
if(bClip)
this->clipLogicValues( pX,pY,pZ );
if(pX && m_aScales[0].Scaling.is())
*pX = m_aScales[0].Scaling->doScaling(*pX);
if(pY && m_aScales[1].Scaling.is())
*pY = m_aScales[1].Scaling->doScaling(*pY);
if(pZ && m_aScales[2].Scaling.is())
*pZ = m_aScales[2].Scaling->doScaling(*pZ);
}
void PlottingPositionHelper::doLogicScaling( ::com::sun::star::drawing::Position3D& rPos, bool bClip ) const
{
doLogicScaling( &rPos.PositionX, &rPos.PositionY, &rPos.PositionZ, bClip );
}
void PlottingPositionHelper::clipLogicValues( double* pX, double* pY, double* pZ ) const
{
if(pX)
{
if( *pX < m_aScales[0].Minimum )
*pX = m_aScales[0].Minimum;
else if( *pX > m_aScales[0].Maximum )
*pX = m_aScales[0].Maximum;
}
if(pY)
{
if( *pY < m_aScales[1].Minimum )
*pY = m_aScales[1].Minimum;
else if( *pY > m_aScales[1].Maximum )
*pY = m_aScales[1].Maximum;
}
if(pZ)
{
if( *pZ < m_aScales[2].Minimum )
*pZ = m_aScales[2].Minimum;
else if( *pZ > m_aScales[2].Maximum )
*pZ = m_aScales[2].Maximum;
}
}
inline bool PlottingPositionHelper::clipYRange( double& rMin, double& rMax ) const
{
//returns true if something remains
if( rMin > rMax )
{
double fHelp = rMin;
rMin = rMax;
rMax = fHelp;
}
if( rMin > getLogicMaxY() )
return false;
if( rMax < getLogicMinY() )
return false;
if( rMin < getLogicMinY() )
rMin = getLogicMinY();
if( rMax > getLogicMaxY() )
rMax = getLogicMaxY();
return true;
}
inline double PlottingPositionHelper::getLogicMinX() const
{
return m_aScales[0].Minimum;
}
inline double PlottingPositionHelper::getLogicMinY() const
{
return m_aScales[1].Minimum;
}
inline double PlottingPositionHelper::getLogicMinZ() const
{
return m_aScales[2].Minimum;
}
inline double PlottingPositionHelper::getLogicMaxX() const
{
return m_aScales[0].Maximum;
}
inline double PlottingPositionHelper::getLogicMaxY() const
{
return m_aScales[1].Maximum;
}
inline double PlottingPositionHelper::getLogicMaxZ() const
{
return m_aScales[2].Maximum;
}
inline bool PlottingPositionHelper::isMathematicalOrientationX() const
{
return ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL == m_aScales[0].Orientation;
}
inline bool PlottingPositionHelper::isMathematicalOrientationY() const
{
return ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL == m_aScales[1].Orientation;
}
inline bool PlottingPositionHelper::isMathematicalOrientationZ() const
{
return ::com::sun::star::chart2::AxisOrientation_MATHEMATICAL == m_aScales[2].Orientation;
}
inline bool PlottingPositionHelper::isSwapXAndY() const
{
return m_bSwapXAndY;
}
inline bool PlottingPositionHelper::maySkipPointsInRegressionCalculation() const
{
return m_bMaySkipPointsInRegressionCalculation;
}
//.............................................................................
} //namespace chart
//.............................................................................
#endif