Commit 81520bce authored by Andrew Maclean's avatar Andrew Maclean
Browse files

ENH: - Added in Random Hills and Steiner's Roman Surface for the prametric functions.

parent 99567d03
......@@ -104,6 +104,8 @@ vtkParametricFigure8Klein.cxx
vtkParametricFunction.cxx
vtkParametricKlein.cxx
vtkParametricMobius.cxx
vtkParametricRandomHills.cxx
vtkParametricRoman.cxx
vtkParametricSuperEllipsoid.cxx
vtkParametricSuperToroid.cxx
vtkParametricTorus.cxx
......
/*=========================================================================
Program: Visualization Toolkit
Module: vtkParametricRandomHills.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkParametricRandomHills.h"
#include "vtkObjectFactory.h"
#include "vtkMath.h"
#include "vtkDoubleArray.h"
#include <time.h>
vtkCxxRevisionMacro(vtkParametricRandomHills, "1.1");
vtkStandardNewMacro(vtkParametricRandomHills);
vtkParametricRandomHills::vtkParametricRandomHills() :
NumberOfHills(30)
, HillXVariance(2.5)
, HillYVariance(2.5)
, HillAmplitude(2)
, RandomSeed(1)
, XVarianceScaleFactor(1.0/3.0)
, YVarianceScaleFactor(1.0/3.0)
, AmplitudeScaleFactor(1.0/3.0)
{
// Preset triangulation parameters
this->MinimumU = -10;
this->MinimumV = -10;
this->MaximumU = 10;
this->MaximumV = 10;
this->JoinU = 0;
this->JoinV = 0;
this->TwistU = 0;
this->TwistV = 0;
this->ClockwiseOrdering = 1;
this->DerivativesAvailable = 0;
this->hillData = vtkDoubleArray::New();
GenerateTheHills();
}
vtkParametricRandomHills::~vtkParametricRandomHills()
{
this->hillData->Delete();
}
//! Initialise the random number generator.
void vtkParametricRandomHills::InitSeed ( int RandomSeed )
{
if ( RandomSeed >= 0 )
srand( (unsigned int) RandomSeed );
else
srand( (unsigned)time( NULL ) );
}
//! Return a random number between 0 and 1.
double vtkParametricRandomHills::Rand ( void )
{
return double(rand())/double(RAND_MAX);
}
void vtkParametricRandomHills::Evaluate(double uvw[3], double Pt[3], double Duvw[9])
{
double u = uvw[0];
double v = uvw[1];
double *Du = Duvw;
double *Dv = Duvw + 3;
// Zero out the point and derivatives.
for ( int i = 0; i < 3; ++i )
Pt[i] = Du[i] = Dv[i] = 0;
// The point
// The height of the surface is made up from
// the contributions from all the Hills.
Pt[0] = u;
Pt[1] = this->MaximumV - v; // Texturing is oriented OK if we do this.
double hillTuple[5]; // 0: mX, 1: mY, 2: VarX, 3: VarY, 4: Amplitude
for ( int i = 0; i < NumberOfHills; ++i )
{
this->hillData->GetTuple(i,hillTuple);
double x = (Pt[0] - hillTuple[0])/hillTuple[2];
double y = (Pt[1] - hillTuple[1])/hillTuple[3];
Pt[2] += hillTuple[4] * exp( -(x*x+y*y) / 2.0 );
}
}
double vtkParametricRandomHills::EvaluateScalar(double* vtkNotUsed(uv[3]),
double* vtkNotUsed(Pt[3]),
double* vtkNotUsed(Duv[9]))
{
return 0;
}
void vtkParametricRandomHills::GenerateTheHills( void )
{
double min_x = (MaximumU>MinimumU)?MinimumU:MaximumU;
double min_y = (MaximumV>MinimumV)?MinimumV:MaximumV;
this->hillData->Initialize();
this->hillData->SetNumberOfComponents(5);
this->hillData->SetNumberOfTuples(NumberOfHills);
double hillTuple[5]; // 0: mX, 1: mY, 2: VarX, 3: VarY, 4: Amplitude
// Generate the centers of the Hills, standard deviations and amplitudes.
InitSeed(this->RandomSeed);
for ( int i = 0; i < this->NumberOfHills; ++ i )
{
hillTuple[0] = min_x + Rand() * (MaximumU - MinimumU);
hillTuple[1] = min_y + Rand() * (MaximumV - MinimumV);
hillTuple[2] = this->HillXVariance * Rand() + this->HillXVariance * this->XVarianceScaleFactor;
hillTuple[3] = this->HillYVariance * Rand() + this->HillYVariance * this->YVarianceScaleFactor;
hillTuple[4] = this->HillAmplitude * Rand() + this->HillAmplitude * this->AmplitudeScaleFactor;
this->hillData->SetTuple(i,hillTuple);
}
this->Modified();
}
void vtkParametricRandomHills::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
os << indent << "Hills: " << this->NumberOfHills << "\n";
os << indent << "Hill variance x-direction: " << this->HillXVariance << "\n";
os << indent << "Hill variance x-direction scaling factor: " << this->XVarianceScaleFactor << "\n";
os << indent << "Hill variance y-direction: " << this->HillYVariance << "\n";
os << indent << "Hill variance y-direction scaling factor: " << this->YVarianceScaleFactor << "\n";
os << indent << "Hill amplitude (height): " << this->HillAmplitude << "\n";
os << indent << "Amplitude scaling factor: " << this->AmplitudeScaleFactor << "\n";
os << indent << "Random number generator seed: " << this->RandomSeed << "\n";
}
/*=========================================================================
Program: Visualization Toolkit
Module: vtkParametricRandomHills.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
// .NAME vtkParametricRandomHills - Generate a surface covered with randomly placed hills.
// .SECTION Description
// vtkParametricRandomHills generates a surface covered with randomly placed hills.
// .SECTION Thanks
// Andrew Maclean a.maclean@cas.edu.au for
// creating and contributing the class.
//
#ifndef __vtkParametricRandomHills_h
#define __vtkParametricRandomHills_h
#include "vtkParametricFunction.h"
class vtkDoubleArray;
class VTK_COMMON_EXPORT vtkParametricRandomHills : public vtkParametricFunction
{
public:
vtkTypeRevisionMacro(vtkParametricRandomHills,vtkParametricFunction);
void PrintSelf(ostream& os, vtkIndent indent);
// Description
// Return the parametric dimension of the class.
virtual int GetDimension() {return 2;}
// Description:
// Construct a surface of random hills with the following parameters:
// MinimumU = -10, MaximumU = 10,
// MinimumV = -10, MaximumV = 10,
// JoinU = 0, JoinV = 0,
// TwistU = 0, TwistV = 0;
// ClockwiseOrdering = 1,
// DerivativesAvailable = 0,
// Number of hills = 30,
// Variance of the hills 2.5 in both x- and y- directions,
// Scaling factor for the variances 1/3 in both x- and y- directions,
// Amplitude of each hill = 1,
// Scaling factor for the amplitude = 1/3,
// RandomSeed = 1.
static vtkParametricRandomHills *New();
// Description:
// Set/Get the number of hills.
// Default is 30.
vtkSetMacro(NumberOfHills,int);
vtkGetMacro(NumberOfHills,int);
// Description:
// Set/Get the hill variance in the x-direction.
// Default is 2.5.
vtkSetMacro(HillXVariance,double);
vtkGetMacro(HillXVariance,double);
// Description:
// Set/Get the hill variance in the y-direction.
// Default is 2.5.
vtkSetMacro(HillYVariance,double);
vtkGetMacro(HillYVariance,double);
// Description:
// Set/Get the hill amplitude (height).
// Default is 2.
vtkSetMacro(HillAmplitude,double);
vtkGetMacro(HillAmplitude,double);
// Description:
// Set/Get the Seed for the random number generator,
// a value of 1 will initialize the random number generator,
// a negative value will initialize it with the system time.
// Default is 1.
vtkSetMacro(RandomSeed,int);
vtkGetMacro(RandomSeed,int);
// Description:
// Set/Get the scaling factor for the variance in the x-direction.
// Default is 1/3.
vtkSetMacro(XVarianceScaleFactor,double);
vtkGetMacro(XVarianceScaleFactor,double);
// Description:
// Set/Get the scaling factor for the variance in the y-direction.
// Default is 1/3.
vtkSetMacro(YVarianceScaleFactor,double);
vtkGetMacro(YVarianceScaleFactor,double);
// Description:
// Set/Get the scaling factor for the amplitude.
// Default is 1/3.
vtkSetMacro(AmplitudeScaleFactor,double);
vtkGetMacro(AmplitudeScaleFactor,double);
// Description:
// Generate the centers of the hills, their standard deviations and
// their amplitudes. This function creates a series of vectors representing
// the u, v coordinates of each hill, its variance in the u, v directions and
// the amplitude.
//
//
// NOTE: This function must be called whenever any of the parameters are changed.
void GenerateTheHills( void );
// Description:
// Construct a terrain consisting of randomly placed hills on a surface.
// This function performs the mapping fn(u,v)->(x,y,x), returning it
// as Pt.
// It is assumed that the function GenerateTheHills() has been executed
// to build the vectors of coordinates required to generate the point Pt.
// Pt represents the sum of all the amplitudes over the space.
// This function performs the mapping fn(u,v)->(x,y,x), returning it
// as Pt. It also returns the partial derivatives Du and Dv.
// Pt = (x, y, z), Du = (dx/du, dy/du, dz/du), Dv = (dx/dv, dy/dv, dz/dv)
//</pre>
virtual void Evaluate(double uvw[3], double Pt[3], double Duvw[9]);
// Description:
// Calculate a user defined scalar using one or all of uvw,Pt,Duvw.
//
// uvw are the parameters with Pt being the the Cartesian point,
// Duvw are the derivatives of this point with respect to u, v and w.
// Pt, Duvw are obtained from Evaluate().
//
// This function is only called if the ScalarMode has the value
// vtkParametricFunctionSource::SCALAR_FUNCTION_DEFINED
//
// If the user does not need to calculate a scalar, then the
// instantiated function should return zero.
//
virtual double EvaluateScalar(double uvw[3], double Pt[3], double Duvw[9]);
protected:
vtkParametricRandomHills();
~vtkParametricRandomHills();
// Variables
int NumberOfHills;
double HillXVariance;
double HillYVariance;
double HillAmplitude;
int RandomSeed;
double XVarianceScaleFactor;
double YVarianceScaleFactor;
double AmplitudeScaleFactor;
private:
vtkParametricRandomHills(const vtkParametricRandomHills&); // Not implemented.
void operator=(const vtkParametricRandomHills&); // Not implemented.
// Description:
// Initialise the random number generator.
void InitSeed ( int RandomSeed );
// Description:
// Return a random number between 0 and 1.
double Rand ( void );
// Description:
// Center (x,y), variances (x,y) and amplitudes of the hills.
vtkDoubleArray * hillData;
};
#endif
/*=========================================================================
Program: Visualization Toolkit
Module: vtkParametricRoman.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkParametricRoman.h"
#include "vtkObjectFactory.h"
#include "vtkMath.h"
vtkCxxRevisionMacro(vtkParametricRoman, "1.1");
vtkStandardNewMacro(vtkParametricRoman);
vtkParametricRoman::vtkParametricRoman():
Radius(1)
{
this->MinimumU = 0;
this->MinimumV = 0;
this->MaximumU = vtkMath::Pi();
this->MaximumV = vtkMath::Pi();
this->JoinU = 1;
this->JoinV = 1;
this->TwistU = 1;
this->TwistV = 0;
this->ClockwiseOrdering = 1;
this->DerivativesAvailable = 1;
}
vtkParametricRoman::~vtkParametricRoman()
{
}
void vtkParametricRoman::Evaluate(double uvw[3], double Pt[3], double Duvw[9])
{
double u = uvw[0];
double v = uvw[1];
double *Du = Duvw;
double *Dv = Duvw + 3;
double cu = cos(u);
double c2u = cos(2.0*u);
double su = sin(u);
double s2u = sin(2.0*u);
double cv = cos(v);
double cv2 = cv*cv;
double c2v = cos(2.0*v);
double s2v = sin(2.0*v);
double sv = sin(v);
double a2 = this->Radius*this->Radius;
// The point
Pt[0] = a2*cv2*s2u/2.0;
Pt[1] = a2*su*s2v/2.0;
Pt[2] = a2*cu*s2v/2.0;
//The derivatives are:
Du[0] = a2*cv2*c2u;
Du[1] = a2*cu*s2v/2.0;
Du[2] = -a2*su*s2v/2.0;
Dv[0] = -a2*cv*s2u*sv;
Dv[1] = a2*su*c2v;
Dv[2] = a2*cu*c2v;
}
double vtkParametricRoman::EvaluateScalar(double* vtkNotUsed(uv[3]),
double* vtkNotUsed(Pt[3]),
double* vtkNotUsed(Duv[9]))
{
return 0;
}
void vtkParametricRoman::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
os << indent << "Radius: " << this->Radius << "\n";
}
/*=========================================================================
Program: Visualization Toolkit
Module: vtkParametricRoman.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
// .NAME vtkParametricRoman - Generate Steiner's Roman Surface.
// .SECTION Description
// vtkParametricRoman generates Steiner's Roman Surface.
// .SECTION Thanks
// Andrew Maclean a.maclean@cas.edu.au for
// creating and contributing the class.
//
#ifndef __vtkParametricRoman_h
#define __vtkParametricRoman_h
#include "vtkParametricFunction.h"
class VTK_COMMON_EXPORT vtkParametricRoman : public vtkParametricFunction
{
public:
vtkTypeRevisionMacro(vtkParametricRoman,vtkParametricFunction);
void PrintSelf(ostream& os, vtkIndent indent);
// Description
// Return the parametric dimension of the class.
virtual int GetDimension() {return 2;}
// Description:
// Construct Steiner's Roman Surface with the following parameters:
// MinimumU = 0, MaximumU = Pi,
// MinimumV = 0, MaximumV = Pi,
// JoinU = 1, JoinV = 1,
// TwistU = 1, TwistV = 0;
// ClockwiseOrdering = 1,
// DerivativesAvailable = 1,
// Radius = 1
static vtkParametricRoman *New();
// Description:
// Set/Get the radius.
vtkSetMacro(Radius,double);
vtkGetMacro(Radius,double);
// Description:
// Steiner's Roman Surface
//
// The parametric form of the equations for Steiner's Roman surface are:
//
// - 0 <= u <= PI, 0 <= v <= PI, a = Radius
//
// - x(u,v) = 1/2*a^2*cos(v)^2*sin(2*u)
//
// - y(u,v) = 1/2*a^2*sin(u)*sin(2*v)
//
// - z(u,v) = 1/2*a^2*cos(u)*sin(2*v)
//
// Derivatives are:
// - d(x(u,v))/du = a^2*cos(v)^2*cos(2*u)
//
// - d(x(u,v))/dv = -a^2*cos(v)*sin(2*u)*sin(v)
//
// - d(y(u,v))/du = 1/2*a^2*cos(u)*sin(2*v)
//
// - d(y(u,v))/dv = a^2*sin(u)*cos(2*v)
//
// - d(z(u,v))/du = -1/2*a^2*sin(u)*sin(2*v)
//
// - d(z(u,v))/dv = a^2*cos(u)*cos(2*v)
//
// Let Du = (dx/du, dy/du, dz/du)
//
// Let Dv = (dx/dv, dy/dv, dz/dv)
//
// Then the normal n = Du X Dv
//
// This function performs the mapping fn(u,v)->(x,y,x), returning it
// as Pt. It also returns the partial derivatives Du and Dv.
// Pt = (x, y, z), Du = (dx/du, dy/du, dz/du), Dv = (dx/dv, dy/dv, dz/dv)
virtual void Evaluate(double uvw[3], double Pt[3], double Duvw[9]);
// Description:
// Calculate a user defined scalar using one or all of uvw,Pt,Duvw.
//
// uvw are the parameters with Pt being the the Cartesian point,
// Duvw are the derivatives of this point with respect to u, v and w.
// Pt, Duvw are obtained from Evaluate().
//
// This function is only called if the ScalarMode has the value
// vtkParametricFunctionSource::SCALAR_FUNCTION_DEFINED
//
// If the user does not need to calculate a scalar, then the
// instantiated function should return zero.
//
virtual double EvaluateScalar(double uvw[3], double Pt[3], double Duvw[9]);
protected:
vtkParametricRoman();
~vtkParametricRoman();
// Variables
double Radius;
private:
vtkParametricRoman(const vtkParametricRoman&); // Not implemented.
void operator=(const vtkParametricRoman&); // Not implemented.
};
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment