VTK/Examples/Broken/QuadricSurfaceFitting
From KitwarePublic
Jump to navigationJump to searchThis example currently does not work.
This example finds the best fit quadric surface through a set of points. Here is an example data set.
QuadricSurfaceFitting.cxx
#include <vtkPolyData.h>
#include <vtkImageData.h>
#include <vtkXMLPolyDataWriter.h>
#include <vtkXMLPolyDataReader.h>
#include <vtkSmartPointer.h>
#include <vtkMath.h>
#include <vtkQuadric.h>
#include <vtkContourFilter.h>
#include <vtkSampleFunction.h>
/* allocate memory for an nrow x ncol matrix */
template<class TReal>
TReal **create_matrix ( long nrow, long ncol )
{
typedef TReal* TRealPointer;
TReal **m = new TRealPointer[nrow];
TReal* block = ( TReal* ) calloc ( nrow*ncol, sizeof ( TReal ) );
m[0] = block;
for ( int row = 1; row < nrow; ++row )
{
m[ row ] = &block[ row * ncol ];
}
return m;
}
/* free a TReal matrix allocated with matrix() */
template<class TReal>
void free_matrix ( TReal **m )
{
free ( m[0] );
delete[] m;
}
int main (int argc, char *argv[])
{
//create points
/*
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
points->InsertNextPoint(0 ,0 ,0);
points->InsertNextPoint(1.1 ,1 ,2);
points->InsertNextPoint(-1,1 ,2);
points->InsertNextPoint(1 ,-1,2);
points->InsertNextPoint(-1,-1,2);
points->InsertNextPoint(1 ,-1,2);
points->InsertNextPoint(2 ,2 ,16);
vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
polydata->SetPoints(points);
*/
vtkSmartPointer<vtkXMLPolyDataReader> reader = vtkSmartPointer<vtkXMLPolyDataReader>::New();
reader->SetFileName(argv[1]);
reader->Update();
vtkPolyData* polydata = Reader->GetOutput();
vtkPoints* points = polydata->GetPoints();
//fit a quadric surface
int numberOfSamples = points->GetNumberOfPoints();
int numberOfVariables = 6;
double **x = create_matrix<double> (numberOfSamples, numberOfVariables);
double **y = create_matrix<double> ( numberOfSamples, 1 );
for(unsigned int i = 0; i < numberOfSamples; i++)
{
double p[3];
points->GetPoint(i,p);
x[i][0] = pow(p[0],2); //x^2
x[i][1] = pow(p[1],2); //y^2
x[i][2] = p[0] * p[1]; //x*y
x[i][3] = p[0]; // x
x[i][4] = p[1]; //y
x[i][5] = 1; // constant
//std::cout << x[i][0] << " " << x[i][1] << " " << x[i][2] << " " << x[i][3] << " " << x[i][4] << " " << x[i][5] << std::endl;
y[i][0] = p[2]; //z
}
double **m = create_matrix<double> ( numberOfVariables, 1 );
vtkMath::SolveLeastSquares(numberOfSamples, x, numberOfVariables, y, 1, m);
std::cout << "Solution is: " << std::endl;
for(unsigned int i = 0; i < numberOfVariables; i++)
{
std::cout << m[i][0] << " ";
}
std::cout << std::endl;
vtkSmartPointer<vtkXMLPolyDataWriter> pointsWriter = vtkSmartPointer<vtkXMLPolyDataWriter>::New();
pointsWriter->SetInput(polydata);
pointsWriter->SetFileName("Points.vtp");
pointsWriter->Write();
// create the quadric function definition
vtkSmartPointer<vtkQuadric> quadric = vtkSmartPointer<vtkQuadric>::New();
quadric->SetCoefficients(m[0][0], m[1][0], 0, m[2][0], 0, 0, m[3][0], m[4][0], 0, m[5][0]);
// sample the quadric function
vtkSmartPointer<vtkSampleFunction> sample = vtkSmartPointer<vtkSampleFunction>::New();
sample->SetSampleDimensions(50,50,50);
sample->SetImplicitFunction(quadric);
double xmin = -5, xmax = 5, ymin = -5, ymax = 5, zmin = 0, zmax = 5;
sample->SetModelBounds(xmin, xmax, ymin, ymax, zmin, zmax);
vtkSmartPointer<vtkContourFilter> contours = vtkSmartPointer<vtkContourFilter>::New();
contours->SetInput(sample->GetOutput());
contours->GenerateValues(1, 1.0, 1.0);
vtkSmartPointer<vtkXMLPolyDataWriter> surfaceWriter = vtkSmartPointer<vtkXMLPolyDataWriter>::New();
surfaceWriter->SetFileName("Quadratic.vtp");
surfaceWriter->SetInput(contours->GetOutput());
surfaceWriter->Write();
free_matrix(X);
free_matrix(M);
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 2.6)
PROJECT(QuadricSurfaceFitting)
FIND_PACKAGE(VTK REQUIRED)
INCLUDE(${VTK_USE_FILE})
ADD_EXECUTABLE(QuadricSurfaceFitting QuadricSurfaceFitting.cxx)
TARGET_LINK_LIBRARIES(QuadricSurfaceFitting vtkHybrid )