You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdegraphics/kpovmodeler/pmjuliafractal.cpp

450 lines
13 KiB

/*
**************************************************************************
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 <klocale.h>
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;
}