/*========================================================================= Program: ShapeWorks: Particle-based Shape Correspondence & Visualization Date: $Date: 2014/03/24 01:17:40 $ Version: $Revision: 1.2 $ Author: $Author: elhabian $ Copyright (c) 2009 Scientific Computing and Imaging Institute. See ShapeWorksLicense.txt 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 notices for more information.=========================================================================*/#ifndef UTILS_H#define UTILS_H#ifdef _WIN32#ifndef _USE_MATH_DEFINES#define _USE_MATH_DEFINES#endif#endif#include<math.h>#include<iostream>#include<map>#include<string>#include<vector>#include<sstream> // std::istringstream#include<itkMath.h>#include<cmath>#include<algorithm> // std::sort#include<vtkSmartPointer.h>#include<vtkPoints.h>#include<itkImage.h>#include<itkPoint.h>#include<vnl/vnl_matrix.h>namespaceutils//TODO: -> namespace shapeworks (need to change everywhere it's used{#define twopi_inv 0.5/M_PI#define twopi 2.0*M_PI#define RANDU ((double) rand()/RAND_MAX)#define RANDN2(mu, sigma) (mu + (rand()%2 ? -1.0 : 1.0)*sigma*pow(-log(0.99999*RANDU), 0.5))#define RANDN RANDN2(0, 1.0)}classUtils{public:staticstd::vector<int>randperm(intn);//--------------------------- IO-----------------------------------staticvoidreadSparseShape(vtkSmartPointer<vtkPoints>&points,char*filename,intnumber_of_particles=-1);staticvoidwriteSparseShape(char*filename,vtkSmartPointer<vtkPoints>particles);staticvoidreadSparseShape(std::vector<itk::Point<double>>&points,char*filename,intnumber_of_particles=-1);staticvoidwriteSparseShape(char*filename,std::vector<itk::Point<double,3>>points);staticstd::vector<int>readParticleIds(char*filename);staticvoidwriteParticleIds(char*filename,std::vector<int>ids);//--------------- point cloud queries --------------------------------staticvoidcomputeCenterOfMassForShapeEnsemble(std::vector<std::vector<itk::Point<double,3>>>points_list,itk::Point<double,3>¢er);staticvoidcomputeCenterOfMassForShape(std::vector<itk::Point<double,3>>points,itk::Point<double,3>¢er);staticvoidupdateMin(doublecurVal,double&minVal);staticvoidupdateMax(doublecurVal,double&maxVal);staticvoidgetBoundingBoxForShapeEnsemble(std::vector<std::vector<itk::Point<double,3>>>points_list,double&min_x,double&min_y,double&min_z,double&max_x,double&max_y,double&max_z);staticvoidgetBoundingBoxForShape(std::vector<itk::Point<double,3>>points,double&min_x,double&min_y,double&min_z,double&max_x,double&max_y,double&max_z);//--------------- coordinates transformations --------------------------------staticvoidspherical2cartesian(constdoubleinPoint[3],doubleoutPoint[3]);staticvoidcartesian2spherical(constdoubleinPoint[3],doubleoutPoint[3]);staticvtkSmartPointer<vtkPoints>convertToPhysicalCoordinates(vtkSmartPointer<vtkPoints>particles,intnumber_of_particles,constitk::Image<float,3>::SpacingType&spacing,constitk::Image<float,3>::PointType&origin);staticvtkSmartPointer<vtkPoints>convertToImageCoordinates(vtkSmartPointer<vtkPoints>particles,intnumber_of_particles,constitk::Image<float,3>::SpacingType&spacing,constitk::Image<float,3>::PointType&origin);staticstd::stringnum2str(floatnum);staticstd::stringnum2str(intnum);staticstd::vector<double>linspace(doublea,doubleb,size_tN);staticstd::stringint2str(intn,intnumber_of_zeros);//--------------- linear algebra -------------------------------------------// matrix multiplication without an allocation for the outputtemplate<typenameT>staticvoidmultiply_into(vnl_matrix<T>&out,constvnl_matrix<T>&lhs,constvnl_matrix<T>&rhs);//--------------- average normal directions --------------------------------/* Trying every theta (with a step size of dtheta), find the theta that results in the smallest MSE. */staticdoubleaverageThetaBruteForce(std::vector<double>thetas,doubledtheta);// the chord methodstaticdoubleaverageThetaChord(std::vector<double>thetas);// the exact methodstaticdoubleaverageThetaArc(std::vector<double>thetas);private:// only good for positive numbers.staticdoublemod2pi_pos(doublevin);// Ensure that v is [-PI, PI]staticdoublemod2pi(doublevin);/* Returns a value of v wrapped such that ref and v differ by no * more +/-PI */staticdoublemod2pi(doubleref,doublev);/* For a given theta, compute the MSE. A simple O(N) method used for testing. */staticdoublecomputeMSE(std::vector<double>thetas,doubletheta);};#endif // UTILS_H