Cloned library of VTK-5.0.0 with extra build files for internal package management.
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.
 
 
 
 
 
 

224 lines
6.6 KiB

/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkSpherePuzzleArrows.cxx,v $
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 "vtkSpherePuzzleArrows.h"
#include "vtkCellArray.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkMath.h"
#include "vtkObjectFactory.h"
#include "vtkPolyData.h"
#include "vtkSpherePuzzle.h"
#include <math.h>
vtkCxxRevisionMacro(vtkSpherePuzzleArrows, "$Revision: 1.13 $");
vtkStandardNewMacro(vtkSpherePuzzleArrows);
//----------------------------------------------------------------------------
// Construct a new puzzle.
vtkSpherePuzzleArrows::vtkSpherePuzzleArrows()
{
int idx;
for (idx = 0; idx < 32; ++idx)
{
this->Permutation[idx] = idx;
}
this->Radius = 0.51;
this->SetNumberOfInputPorts(0);
}
//----------------------------------------------------------------------------
// Destruct the puzzle.
vtkSpherePuzzleArrows::~vtkSpherePuzzleArrows()
{
}
//----------------------------------------------------------------------------
void vtkSpherePuzzleArrows::SetPermutationComponent(int comp, int val)
{
if (this->Permutation[comp] == val)
{
return;
}
this->Permutation[comp] = val;
this->Modified();
}
//----------------------------------------------------------------------------
int vtkSpherePuzzleArrows::RequestData(
vtkInformation *vtkNotUsed(request),
vtkInformationVector **vtkNotUsed(inputVector),
vtkInformationVector *outputVector)
{
// get the info object
vtkInformation *outInfo = outputVector->GetInformationObject(0);
// get the ouptut
vtkPolyData *output = vtkPolyData::SafeDownCast(
outInfo->Get(vtkDataObject::DATA_OBJECT()));
vtkPoints *pts = vtkPoints::New();
vtkCellArray *polys = vtkCellArray::New();
int idx;
for (idx = 0; idx < 32; ++idx)
{
if (this->Permutation[idx] != idx)
{
//this->AppendArrow(idx, this->Permutation[idx], pts, polys);
this->AppendArrow(this->Permutation[idx], idx, pts, polys);
}
}
output->SetPoints(pts);
output->SetPolys(polys);
pts->Delete();
polys->Delete();
return 1;
}
//----------------------------------------------------------------------------
// Draw an arrow for piece with id1 to piece with id2.
void vtkSpherePuzzleArrows::AppendArrow(int id1, int id2,
vtkPoints *pts, vtkCellArray *polys)
{
double phi1, phi2, dPhi;
double theta1, theta2, dTheta;
double phi=0, theta=0, phiOff, thetaOff;
double length;
double x, y, z;
int num, idx;
vtkIdType ptId1, ptId2, ptId3, ptId4, ptId5;
// Convert the start and end piece ids into sphere coordinates.
phi1 = vtkMath::Pi() * ((id1 / 8)+0.5) / 4.0;
theta1 = vtkMath::Pi() * ((id1 % 8)+0.5) / 4.0;
phi2 = vtkMath::Pi() * ((id2 / 8)+0.5) / 4.0;
theta2 = vtkMath::Pi() * ((id2 % 8)+0.5) / 4.0;
dPhi = phi2 - phi1;
dTheta = theta2 - theta1;
// Take the short way around.
while (dPhi > vtkMath::Pi())
{
dPhi -= 2*vtkMath::Pi();
}
while (dPhi < -vtkMath::Pi())
{
dPhi += 2*vtkMath::Pi();
}
while (dTheta > vtkMath::Pi())
{
dTheta -= 2*vtkMath::Pi();
}
while (dTheta < -vtkMath::Pi())
{
dTheta += 2*vtkMath::Pi();
}
theta2 = theta1 + dTheta;
phi2 = phi1 + dPhi;
// Compute the length (world coords).
length = dTheta * sin(0.5*(phi1+phi2));
length = sqrt(length*length + dPhi*dPhi);
// How many division do we need.
num = (int)(length / 0.1);
// Compute the perpendicular phi theta step.
thetaOff = dPhi;
phiOff = -dTheta;
// Normalize (sphere coords).
length = sqrt(thetaOff*thetaOff + phiOff*phiOff);
phiOff = 0.08 * phiOff / length;
thetaOff = 0.08 * thetaOff / length;
// First point.
x = cos(theta1+thetaOff)*sin(phi1+phiOff);
y = sin(theta1+thetaOff)*sin(phi1+phiOff);
z = cos(phi1+phiOff);
ptId1 = pts->InsertNextPoint(this->Radius*x, this->Radius*y, this->Radius*z);
x = cos(theta1+2*thetaOff)*sin(phi1+2*phiOff);
y = sin(theta1+2*thetaOff)*sin(phi1+2*phiOff);
z = cos(phi1+2*phiOff);
ptId2 = pts->InsertNextPoint(this->Radius*x, this->Radius*y, this->Radius*z);
for (idx = 1; idx < num; ++idx)
{
// Interpolate angles.
theta = theta1 + ((double)(idx)/(double)(num)) * dTheta;
phi = phi1 + ((double)(idx)/(double)(num)) * (phi2-phi1);
x = cos(theta+thetaOff)*sin(phi+phiOff);
y = sin(theta+thetaOff)*sin(phi+phiOff);
z = cos(phi+phiOff);
ptId3 =
pts->InsertNextPoint(this->Radius*x, this->Radius*y, this->Radius*z);
x = cos(theta+2*thetaOff)*sin(phi+2*phiOff);
y = sin(theta+2*thetaOff)*sin(phi+2*phiOff);
z = cos(phi+2*phiOff);
ptId4 =
pts->InsertNextPoint(this->Radius*x, this->Radius*y, this->Radius*z);
// Create the rectangle.
polys->InsertNextCell(4);
polys->InsertCellPoint(ptId1);
polys->InsertCellPoint(ptId2);
polys->InsertCellPoint(ptId4);
polys->InsertCellPoint(ptId3);
// Initialize the next step.
ptId1 = ptId3;
ptId2 = ptId4;
}
// Now create the arrow.
x = cos(theta)*sin(phi);
y = sin(theta)*sin(phi);
z = cos(phi);
ptId3 = pts->InsertNextPoint(this->Radius*x, this->Radius*y, this->Radius*z);
x = cos(theta+3*thetaOff)*sin(phi+3*phiOff);
y = sin(theta+3*thetaOff)*sin(phi+3*phiOff);
z = cos(phi+3*phiOff);
ptId4 = pts->InsertNextPoint(this->Radius*x, this->Radius*y, this->Radius*z);
x = cos(theta2+1.5*thetaOff)*sin(phi2+1.5*phiOff);
y = sin(theta2+1.5*thetaOff)*sin(phi2+1.5*phiOff);
z = cos(phi2+1.5*phiOff);
ptId5 = pts->InsertNextPoint(this->Radius*x, this->Radius*y, this->Radius*z);
polys->InsertNextCell(5);
polys->InsertCellPoint(ptId5);
polys->InsertCellPoint(ptId4);
polys->InsertCellPoint(ptId2);
polys->InsertCellPoint(ptId1);
polys->InsertCellPoint(ptId3);
}
//----------------------------------------------------------------------------
void vtkSpherePuzzleArrows::SetPermutation(vtkSpherePuzzle *puz)
{
this->SetPermutation(puz->GetState());
}
//----------------------------------------------------------------------------
void vtkSpherePuzzleArrows::PrintSelf(ostream& os, vtkIndent indent)
{
int i;
this->Superclass::PrintSelf(os,indent);
os << indent << "Permutation: ";
for (i = 0; i < 32; ++i)
{
os << this->Permutation[i] << " ";
}
os << endl;
}