/* ************************************************************************** description -------------------- copyright : (C) 2002 by Andreas Zehender email : zehender@kde.org ************************************************************************** ************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * **************************************************************************/ #include "pmjuliafractal.h" #include "pmxmlhelper.h" #include "pmjuliafractaledit.h" #include "pmmemento.h" #include "pmviewstructure.h" #include "pm3dcontrolpoint.h" #include "pmenumproperty.h" #include const PMVector c_defaultJuliaParameter = PMVector( -0.083, 0.0, -0.83, -0.025 ); const PMVector c_defaultSliceNormal = PMVector( 0.0, 0.0, 0.0, 1.0 ); const double c_defaultSliceDistance = 0.0; const int c_defaultMaxIterations = 20; const PMJuliaFractal::AlgebraType c_defaultAlgebraType = PMJuliaFractal::Quaternion; const TQString c_defaultAlgebraString = "quaternion"; const PMJuliaFractal::FunctionType c_defaultFunctionType = PMJuliaFractal::FTsqr; const TQString c_defaultFunctionString = "sqr"; const PMVector c_defaultExponent = PMVector( 0.0, 0.0 ); const double c_defaultPrecision = 20.0; PMDefinePropertyClass( PMJuliaFractal, PMJuliaFractalProperty ); PMDefineEnumPropertyClass( PMJuliaFractal, PMJuliaFractal::AlgebraType, PMAlgebraTypeProperty ); PMDefineEnumPropertyClass( PMJuliaFractal, PMJuliaFractal::FunctionType, PMFunctionTypeProperty ); PMMetaObject* PMJuliaFractal::s_pMetaObject = 0; PMObject* createNewJuliaFractal( PMPart* part ) { return new PMJuliaFractal( part ); } PMJuliaFractal::PMJuliaFractal( PMPart* part ) : Base( part ) { m_juliaParameter = c_defaultJuliaParameter; m_algebraType = c_defaultAlgebraType; m_functionType = c_defaultFunctionType; m_maxIterations = c_defaultMaxIterations; m_precision = c_defaultPrecision; m_sliceNormal = c_defaultSliceNormal; m_sliceDistance = c_defaultSliceDistance; m_exponent = c_defaultExponent; } PMJuliaFractal::PMJuliaFractal( const PMJuliaFractal& f ) : Base( f ) { m_juliaParameter = f.m_juliaParameter; m_algebraType = f.m_algebraType; m_functionType = f.m_functionType; m_maxIterations = f.m_maxIterations; m_precision = f.m_precision; m_sliceNormal = f.m_sliceNormal; m_sliceDistance = f.m_sliceDistance; m_exponent = f.m_exponent; } PMJuliaFractal::~PMJuliaFractal( ) { } TQString PMJuliaFractal::description( ) const { return i18n( "julia fractal" ); } void PMJuliaFractal::serialize( TQDomElement& e, TQDomDocument& doc ) const { e.setAttribute( "julia_parameter", m_juliaParameter.serializeXML( ) ); e.setAttribute( "algebra_type", algebraTypeToString( m_algebraType ) ); e.setAttribute( "function_type", functionTypeToString( m_functionType ) ); e.setAttribute( "max_iterations", m_maxIterations ); e.setAttribute( "precision", m_precision ); e.setAttribute( "slice_normal", m_sliceNormal.serializeXML( ) ); e.setAttribute( "slice_distance", m_sliceDistance ); e.setAttribute( "exponent", m_exponent.serializeXML( ) ); Base::serialize( e, doc ); } void PMJuliaFractal::readAttributes( const PMXMLHelper& h ) { m_juliaParameter = h.vectorAttribute( "julia_parameter", c_defaultJuliaParameter ); m_algebraType = stringToAlgebraType( h.stringAttribute( "algebra_type", c_defaultAlgebraString ) ); m_functionType = stringToFunctionType( h.stringAttribute( "function_type", c_defaultFunctionString ) ); m_maxIterations = h.intAttribute( "max_iterations", c_defaultMaxIterations ); m_precision = h.doubleAttribute( "precision", c_defaultPrecision ); m_sliceNormal = h.vectorAttribute( "slice_normal", c_defaultSliceNormal ); m_sliceDistance = h.doubleAttribute( "slice_distance", c_defaultSliceDistance ); m_exponent = h.vectorAttribute( "exponent", c_defaultExponent ); Base::readAttributes( h ); } PMMetaObject* PMJuliaFractal::metaObject( ) const { if( !s_pMetaObject ) { s_pMetaObject = new PMMetaObject( "JuliaFractal", Base::metaObject( ), createNewJuliaFractal ); s_pMetaObject->addProperty( new PMJuliaFractalProperty( "juliaParameter", &PMJuliaFractal::setJuliaParameter, &PMJuliaFractal::juliaParameter ) ); s_pMetaObject->addProperty( new PMJuliaFractalProperty( "maximumIterations", &PMJuliaFractal::setMaximumIterations, &PMJuliaFractal::maximumIterations ) ); s_pMetaObject->addProperty( new PMJuliaFractalProperty( "precision", &PMJuliaFractal::setPrecision, &PMJuliaFractal::precision ) ); s_pMetaObject->addProperty( new PMJuliaFractalProperty( "sliceNormal", &PMJuliaFractal::setSliceNormal, &PMJuliaFractal::sliceNormal ) ); s_pMetaObject->addProperty( new PMJuliaFractalProperty( "sliceDistance", &PMJuliaFractal::setSliceDistance, &PMJuliaFractal::sliceDistance ) ); s_pMetaObject->addProperty( new PMJuliaFractalProperty( "exponent", &PMJuliaFractal::setExponent, &PMJuliaFractal::exponent ) ); PMAlgebraTypeProperty* ap = new PMAlgebraTypeProperty( "algebraType", &PMJuliaFractal::setAlgebraType, &PMJuliaFractal::algebraType ); ap->addEnumValue( "Quaternion", Quaternion ); ap->addEnumValue( "Hypercomplex", Hypercomplex ); s_pMetaObject->addProperty( ap ); PMFunctionTypeProperty* fp = new PMFunctionTypeProperty( "functionType", &PMJuliaFractal::setFunctionType, &PMJuliaFractal::functionType ); fp->addEnumValue( "sqr", FTsqr ); fp->addEnumValue( "cube", FTcube ); fp->addEnumValue( "exp", FTexp ); fp->addEnumValue( "reciprocal", FTreciprocal ); fp->addEnumValue( "sin", FTsin ); fp->addEnumValue( "asin", FTasin ); fp->addEnumValue( "sinh", FTsinh ); fp->addEnumValue( "asinh", FTasinh ); fp->addEnumValue( "cos", FTcos ); fp->addEnumValue( "acos", FTacos ); fp->addEnumValue( "cosh", FTcosh ); fp->addEnumValue( "acosh", FTacosh ); fp->addEnumValue( "tan", FTtan ); fp->addEnumValue( "atan", FTatan ); fp->addEnumValue( "tanh", FTtanh ); fp->addEnumValue( "atanh", FTatanh ); fp->addEnumValue( "log", FTlog ); fp->addEnumValue( "pwr", FTpwr ); s_pMetaObject->addProperty( fp ); } return s_pMetaObject; } void PMJuliaFractal::cleanUp( ) const { if( s_pMetaObject ) { delete s_pMetaObject; s_pMetaObject = 0; } Base::cleanUp( ); } void PMJuliaFractal::setJuliaParameter( const PMVector& p ) { if( p != m_juliaParameter ) { if( m_pMemento ) m_pMemento->addData( s_pMetaObject, PMJuliaParameterID, m_juliaParameter ); m_juliaParameter = p; m_juliaParameter.resize( 4 ); } } void PMJuliaFractal::setAlgebraType( PMJuliaFractal::AlgebraType t ) { if( m_algebraType != t ) { if( m_pMemento ) m_pMemento->addData( s_pMetaObject, PMAlgebraTypeID, m_algebraType ); m_algebraType = t; } } void PMJuliaFractal::setFunctionType( PMJuliaFractal::FunctionType t ) { if( m_functionType != t ) { if( m_pMemento ) m_pMemento->addData( s_pMetaObject, PMFunctionTypeID, m_functionType ); m_functionType = t; } } void PMJuliaFractal::setMaximumIterations( int max ) { if( max <= 0 ) { kdError( PMArea ) << "max <= 0 in PMJuliaFractal::setMaximumIterations\n"; max = 20; } if( m_maxIterations != max ) { if( m_pMemento ) m_pMemento->addData( s_pMetaObject, PMMaxIterationsID, m_maxIterations ); m_maxIterations = max; } } void PMJuliaFractal::setPrecision( double p ) { if( p < 1.0 ) { kdError( PMArea ) << "p < 1.0 in PMJuliaFractal::setPrecision\n"; p = 1.0; } if( m_precision != p ) { if( m_pMemento ) m_pMemento->addData( s_pMetaObject, PMPrecisionID, m_precision ); m_precision = p; } } void PMJuliaFractal::setSliceNormal( const PMVector& n ) { if( m_sliceNormal != n ) { if( m_pMemento ) m_pMemento->addData( s_pMetaObject, PMSliceNormalID, m_sliceNormal ); m_sliceNormal = n; m_sliceNormal.resize( 4 ); } } void PMJuliaFractal::setSliceDistance( double d ) { if( m_sliceDistance != d ) { if( m_pMemento ) m_pMemento->addData( s_pMetaObject, PMSliceDistanceID, m_sliceDistance ); m_sliceDistance = d; } } void PMJuliaFractal::setExponent( const PMVector& e ) { if( m_exponent != e ) { if( m_pMemento ) m_pMemento->addData( s_pMetaObject, PMExponentID, m_exponent ); m_exponent = e; m_exponent.resize( 2 ); } } PMDialogEditBase* PMJuliaFractal::editWidget( TQWidget* parent ) const { return new PMJuliaFractalEdit( parent ); } void PMJuliaFractal::restoreMemento( PMMemento* s ) { PMMementoDataIterator it( s ); PMMementoData* data; for( ; it.current( ); ++it ) { data = it.current( ); if( data->objectType( ) == s_pMetaObject ) { switch( data->valueID( ) ) { case PMJuliaParameterID: setJuliaParameter( data->vectorData( ) ); break; case PMAlgebraTypeID: setAlgebraType( ( AlgebraType ) data->intData( ) ); break; case PMFunctionTypeID: setFunctionType( ( FunctionType ) data->intData( ) ); break; case PMMaxIterationsID: setMaximumIterations( data->intData( ) ); break; case PMPrecisionID: setPrecision( data->doubleData( ) ); break; case PMSliceNormalID: setSliceNormal( data->vectorData( ) ); break; case PMSliceDistanceID: setSliceDistance( data->doubleData( ) ); break; case PMExponentID: setExponent( data->vectorData( ) ); break; default: kdError( PMArea ) << "Wrong ID in PMJuliaFractal::restoreMemento\n"; break; } } } Base::restoreMemento( s ); } TQString PMJuliaFractal::functionTypeToString( PMJuliaFractal::FunctionType t ) { TQString result = "sqr"; switch( t ) { case FTsqr: result = "sqr"; break; case FTcube: result = "cube"; break; case FTexp: result = "exp"; break; case FTreciprocal: result = "reciprocal"; break; case FTsin: result = "sin"; break; case FTasin: result = "asin"; break; case FTsinh: result = "sinh"; break; case FTasinh: result = "asinh"; break; case FTcos: result = "cos"; break; case FTacos: result = "acos"; break; case FTcosh: result = "cosh"; break; case FTacosh: result = "acosh"; break; case FTtan: result = "tan"; break; case FTatan: result = "atan"; break; case FTtanh: result = "tanh"; break; case FTatanh: result = "atanh"; break; case FTlog: result = "log"; break; case FTpwr: result = "pwr"; break; } return result; } PMJuliaFractal::FunctionType PMJuliaFractal::stringToFunctionType( const TQString& str ) { FunctionType t = c_defaultFunctionType; if( str == "sqr" ) t = FTsqr; else if( str == "cube" ) t = FTcube; else if( str == "exp" ) t = FTexp; else if( str == "reciprocal" ) t = FTreciprocal; else if( str == "sin" ) t = FTsin; else if( str == "asin" ) t = FTasin; else if( str == "sinh" ) t = FTsinh; else if( str == "asinh" ) t = FTasinh; else if( str == "cos" ) t = FTcos; else if( str == "acos" ) t = FTacos; else if( str == "cosh" ) t = FTcosh; else if( str == "acosh" ) t = FTacosh; else if( str == "tan" ) t = FTtan; else if( str == "atan" ) t = FTatan; else if( str == "tanh" ) t = FTtanh; else if( str == "atanh" ) t = FTatanh; else if( str == "log" ) t = FTlog; else if( str == "pwr" ) t = FTpwr; return t; } TQString PMJuliaFractal::algebraTypeToString( PMJuliaFractal::AlgebraType t ) { TQString result; if( t == Quaternion ) result = "quaternion"; else result = "hypercomplex"; return result; } PMJuliaFractal::AlgebraType PMJuliaFractal::stringToAlgebraType( const TQString& str ) { AlgebraType t = c_defaultAlgebraType; if( str == "quaternion" ) t = Quaternion; else if( str == "hypercomplex" ) t = Hypercomplex; return t; }