VTK/Examples/Broken/QuadricSurfaceFitting

From KitwarePublic
< VTK‎ | Examples
Jump to navigationJump to search

This 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 )