You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
188 lines
6.0 KiB
Plaintext
188 lines
6.0 KiB
Plaintext
3 weeks ago
|
/*=========================================================================
|
||
|
|
||
|
Program: Visualization Toolkit
|
||
|
Module: vtkAngularPeriodicDataArray.txx
|
||
|
|
||
|
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 "vtkMath.h"
|
||
|
#include "vtkMatrix3x3.h"
|
||
|
#include "vtkObjectFactory.h"
|
||
|
|
||
|
#include <algorithm>
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
// Can't use vtkStandardNewMacro on a templated class.
|
||
|
template <class Scalar>
|
||
|
vtkAngularPeriodicDataArray<Scalar>* vtkAngularPeriodicDataArray<Scalar>::New()
|
||
|
{
|
||
|
VTK_STANDARD_NEW_BODY(vtkAngularPeriodicDataArray<Scalar>);
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
template <class Scalar>
|
||
|
void vtkAngularPeriodicDataArray<Scalar>::PrintSelf(ostream& os, vtkIndent indent)
|
||
|
{
|
||
|
this->vtkAngularPeriodicDataArray<Scalar>::Superclass::PrintSelf(os, indent);
|
||
|
os << indent << "Axis: " << this->Axis << "\n";
|
||
|
os << indent << "Angle: " << this->Angle << "\n";
|
||
|
os << indent << "Center: " << this->Center[0] << " " << this->Center[1] << " " << this->Center[2]
|
||
|
<< "\n";
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
template <class Scalar>
|
||
|
void vtkAngularPeriodicDataArray<Scalar>::InitializeArray(vtkAOSDataArrayTemplate<Scalar>* data)
|
||
|
{
|
||
|
this->Initialize();
|
||
|
if (!data)
|
||
|
{
|
||
|
vtkErrorMacro(<< "No original data provided.");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (data->GetNumberOfComponents() != 3 && data->GetNumberOfComponents() != 6 &&
|
||
|
data->GetNumberOfComponents() != 9)
|
||
|
{
|
||
|
vtkWarningMacro(<< "Original data has " << data->GetNumberOfComponents()
|
||
|
<< " components, Expecting 3 or 9.");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
this->Superclass::InitializeArray(data);
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
template <class Scalar>
|
||
|
void vtkAngularPeriodicDataArray<Scalar>::SetAngle(double angle)
|
||
|
{
|
||
|
if (this->Angle != angle)
|
||
|
{
|
||
|
this->Angle = angle;
|
||
|
this->AngleInRadians = vtkMath::RadiansFromDegrees(angle);
|
||
|
this->InvalidateRange();
|
||
|
this->UpdateRotationMatrix();
|
||
|
this->Modified();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
template <class Scalar>
|
||
|
void vtkAngularPeriodicDataArray<Scalar>::SetAxis(int axis)
|
||
|
{
|
||
|
if (this->Axis != axis)
|
||
|
{
|
||
|
this->Axis = axis;
|
||
|
this->InvalidateRange();
|
||
|
this->UpdateRotationMatrix();
|
||
|
this->Modified();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
template <class Scalar>
|
||
|
void vtkAngularPeriodicDataArray<Scalar>::SetCenter(double* center)
|
||
|
{
|
||
|
if (center)
|
||
|
{
|
||
|
bool diff = false;
|
||
|
for (int i = 0; i < 3; i++)
|
||
|
{
|
||
|
if (this->Center[i] != center[i])
|
||
|
{
|
||
|
this->Center[i] = center[i];
|
||
|
diff = true;
|
||
|
}
|
||
|
}
|
||
|
if (diff)
|
||
|
{
|
||
|
this->InvalidateRange();
|
||
|
this->Modified();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
template <class Scalar>
|
||
|
void vtkAngularPeriodicDataArray<Scalar>::Transform(Scalar* pos) const
|
||
|
{
|
||
|
if (this->NumberOfComponents == 3)
|
||
|
{
|
||
|
// Axis rotation
|
||
|
int axis0 = (this->Axis + 1) % this->NumberOfComponents;
|
||
|
int axis1 = (this->Axis + 2) % this->NumberOfComponents;
|
||
|
double posx = static_cast<double>(pos[axis0]) - this->Center[axis0];
|
||
|
double posy = static_cast<double>(pos[axis1]) - this->Center[axis1];
|
||
|
|
||
|
pos[axis0] = this->Center[axis0] +
|
||
|
static_cast<Scalar>(cos(this->AngleInRadians) * posx - sin(this->AngleInRadians) * posy);
|
||
|
pos[axis1] = this->Center[axis1] +
|
||
|
static_cast<Scalar>(sin(this->AngleInRadians) * posx + cos(this->AngleInRadians) * posy);
|
||
|
if (this->Normalize)
|
||
|
{
|
||
|
vtkMath::Normalize(pos);
|
||
|
}
|
||
|
}
|
||
|
else if (this->NumberOfComponents == 9 || this->NumberOfComponents == 6)
|
||
|
{
|
||
|
// Template type force a copy to a double array for tensor
|
||
|
double localPos[9];
|
||
|
double tmpMat[9];
|
||
|
double tmpMat2[9];
|
||
|
std::copy(pos, pos + this->NumberOfComponents, localPos);
|
||
|
if (this->NumberOfComponents == 6)
|
||
|
{
|
||
|
vtkMath::TensorFromSymmetricTensor(localPos);
|
||
|
}
|
||
|
|
||
|
vtkMatrix3x3::Transpose(this->RotationMatrix->GetData(), tmpMat);
|
||
|
vtkMatrix3x3::Multiply3x3(this->RotationMatrix->GetData(), localPos, tmpMat2);
|
||
|
vtkMatrix3x3::Multiply3x3(tmpMat2, tmpMat, localPos);
|
||
|
std::copy(localPos, localPos + this->NumberOfComponents, pos);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
template <class Scalar>
|
||
|
void vtkAngularPeriodicDataArray<Scalar>::UpdateRotationMatrix()
|
||
|
{
|
||
|
int axis0 = (this->Axis + 1) % 3;
|
||
|
int axis1 = (this->Axis + 2) % 3;
|
||
|
this->RotationMatrix->Identity();
|
||
|
this->RotationMatrix->SetElement(this->Axis, this->Axis, 1.);
|
||
|
this->RotationMatrix->SetElement(axis0, axis0, cos(this->AngleInRadians));
|
||
|
this->RotationMatrix->SetElement(axis0, axis1, -sin(this->AngleInRadians));
|
||
|
this->RotationMatrix->SetElement(axis1, axis0, sin(this->AngleInRadians));
|
||
|
this->RotationMatrix->SetElement(axis1, axis1, cos(this->AngleInRadians));
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
template <class Scalar>
|
||
|
vtkAngularPeriodicDataArray<Scalar>::vtkAngularPeriodicDataArray()
|
||
|
{
|
||
|
this->Axis = VTK_PERIODIC_ARRAY_AXIS_X;
|
||
|
this->Angle = 0.0;
|
||
|
this->AngleInRadians = 0.0;
|
||
|
this->Center[0] = 0.0;
|
||
|
this->Center[1] = 0.0;
|
||
|
this->Center[2] = 0.0;
|
||
|
|
||
|
this->RotationMatrix = vtkMatrix3x3::New();
|
||
|
this->RotationMatrix->Identity();
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
template <class Scalar>
|
||
|
vtkAngularPeriodicDataArray<Scalar>::~vtkAngularPeriodicDataArray()
|
||
|
{
|
||
|
this->RotationMatrix->Delete();
|
||
|
}
|