This is an example of how to instanciate the Ponca::Concept::PointConcept in order to use Ponca on existing data structures without any memory duplication.
#include <cmath>
#include <algorithm>
#include <iostream>
#include <Ponca/src/Fitting/basket.h>
#include <Ponca/src/Fitting/gls.h>
#include <Ponca/src/Fitting/orientedSphereFit.h>
#include <Ponca/src/Fitting/weightFunc.h>
#include <Ponca/src/Fitting/weightKernel.h>
#include "Eigen/Eigen"
#include <vector>
using namespace std;
#define DIMENSION 3
class MyPoint
{
public:
enum {Dim = DIMENSION};
typedef double Scalar;
typedef Eigen::Matrix<Scalar, Dim, 1> VectorType;
typedef Eigen::Matrix<Scalar, Dim, Dim> MatrixType;
PONCA_MULTIARCH inline MyPoint(Scalar* _interlacedArray, int _pId)
: m_pos (Eigen::Map< const VectorType >(_interlacedArray + Dim*2*_pId )),
m_normal(Eigen::Map< const VectorType >(_interlacedArray + Dim*2*_pId+Dim))
{}
PONCA_MULTIARCH inline const Eigen::Map< const VectorType >& pos() const { return m_pos; }
PONCA_MULTIARCH inline const Eigen::Map< const VectorType >& normal() const { return m_normal; }
private:
Eigen::Map< const VectorType > m_pos, m_normal;
};
typedef MyPoint::Scalar Scalar;
typedef MyPoint::VectorType VectorType;
template<typename Fit>
void test_fit(Fit& _fit,
Scalar* _interlacedArray,
int _n,
const VectorType& _p)
{
Scalar tmax = 100.0;
_fit.setWeightFunc(WeightFunc(tmax));
_fit.init(_p);
for(int i = 0; i!= _n; i++)
{
}
_fit.finalize();
if(_fit.isStable())
{
cout << "Center: [" << _fit.center().transpose() << "] ; radius: " << _fit.radius() << endl;
cout << "Pratt normalization"
<< (_fit.applyPrattNorm() ? " is now done." : " has already been applied.") << endl;
cout << "Value of the scalar field at the initial point: "
<< _p.transpose()
<< " is equal to " << _fit.potential(_p)
<< endl;
cout << "It's gradient at this place is equal to: "
<< _fit.primitiveGradient(_p).transpose()
<< endl;
cout << "Fitted Sphere: " << endl
<< "\t Tau : " << _fit.tau() << endl
<< "\t Eta : " << _fit.eta().transpose() << endl
<< "\t Kappa: " << _fit.kappa() << endl;
cout << "The initial point " << _p.transpose() << endl
<< "Is projected at " << _fit.project(_p).transpose() << endl;
}
}
Scalar* buildInterlacedArray(int _n)
{
Scalar* interlacedArray = new Scalar[uint8_t(2*DIMENSION*_n)];
for(int k=0; k<_n; ++k)
{
Eigen::Matrix<Scalar, DIMENSION, 1> nvec = Eigen::Matrix<Scalar, DIMENSION, 1>::Random().normalized();
Eigen::Matrix<Scalar, DIMENSION, 1> pvec = nvec * Eigen::internal::random<Scalar>(0.9,1.1);
memcpy(interlacedArray+2*DIMENSION*k, pvec.data(), DIMENSION*sizeof(Scalar));
memcpy(interlacedArray+2*DIMENSION*k+DIMENSION, nvec.data(), DIMENSION*sizeof(Scalar));
}
return interlacedArray;
}
int main()
{
int n = 1000;
Scalar *interlacedArray = buildInterlacedArray(n);
VectorType p (interlacedArray);
Fit fit;
test_fit(fit, interlacedArray, n, p);
}
Aggregator class used to declare specialized structures using CRTP.
bool addNeighbor(const DataPoint &_nei)
Add a neighbor to perform the fit.
Weighting function based on the euclidean distance between a query and a reference position.
This Source Code Form is subject to the terms of the Mozilla Public License, v.