Skip to content

Commit

Permalink
Merge pull request #136 from jmaleo/meanNormalDer
Browse files Browse the repository at this point in the history
Mean normal der
  • Loading branch information
nmellado authored Mar 13, 2024
2 parents 36b81e9 + 521d7f8 commit 2eadc3c
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Current head (v.1.3 RC)

- Bug-fixes and code improvements
- [all] Limit explicit use of exceptions and adapt to compilation mode (#135)
- [fitting] Fix MeanNormal and MeanNormalDer classes for mean normal vector derivatives computation (#136)

- Docs
- [spatialPartitioning] Update KdTree docs to reflect the kdtree API refactor (#129)
Expand Down
26 changes: 17 additions & 9 deletions Ponca/src/Fitting/mean.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,15 @@ namespace Ponca {
PONCA_EXPLICIT_CAST_OPERATORS(MeanNormal,meanNormal)
PONCA_FITTING_DECLARE_INIT
PONCA_FITTING_DECLARE_ADDNEIGHBOR

/// \brief Mean of the normals of the input points
///
/// Defined as \f$ n(\mathbf{x}) = \frac{\sum_i w_\mathbf{x}(\mathbf{p_i}) \mathbf{n_i}}{\sum_i w_\mathbf{x}(\mathbf{p_i})} \f$,
/// where \f$\left[\mathbf{p_i}, \mathbf{n_i} \in \text{neighborhood}(\mathbf{x})\right]\f$ are all the point and normal samples in \f$\mathbf{x}\f$'s neighborhood
PONCA_MULTIARCH inline VectorType meanNormalVector() const {
return (m_sumN / Base::getWeightSum());
}

}; //class MeanNormal

template<class DataPoint, class _WFunctor, int DiffType, typename T>
Expand Down Expand Up @@ -134,7 +143,6 @@ namespace Ponca {
PROVIDES_MEAN_NORMAL_DERIVATIVE, /*!< \brief Provides derivative of the mean normal*/
};

private:
/*! \brief Derivatives of the input normals of the input points vectors*/
VectorArray m_dSumN {VectorArray::Zero()};

Expand All @@ -147,27 +155,27 @@ namespace Ponca {
/// \brief Compute the derivative of the mean normal vector of the input points.
///
/// ### Step-by-step derivation of the mean normal :
/// Given the definition of the mean normal \f$ n(\mathbf{x}) = \frac{\sum_i w_\mathbf{x}(\mathbf{n_i}) \mathbf{n_i}}{\sum_i w_\mathbf{x}(\mathbf{n_i})} \f$,
/// where \f$\left[\mathbf{n_i} \in \text{neighborhood}(\mathbf{x})\right]\f$ are all the normal samples in \f$\mathbf{x}\f$'s neighborhood.
/// Given the definition of the mean normal \f$ n(\mathbf{x}) = \frac{\sum_i w_\mathbf{x}(\mathbf{p_i}) \mathbf{n_i}}{\sum_i w_\mathbf{x}(\mathbf{p_i})} \f$,
/// where \f$\left[\mathbf{p_i}, \mathbf{n_i} \in \text{neighborhood}(\mathbf{x})\right]\f$ are all the point and normal samples in \f$\mathbf{x}\f$'s neighborhood.
///
/// We denote \f$ t(\mathbf{x}) = \sum_i w_\mathbf{x}(\mathbf{n_i}) \mathbf{n_i} \f$ and \f$ s(\mathbf{x}) = \sum_i w_\mathbf{x}(\mathbf{n_i})\f$,
/// We denote \f$ t(\mathbf{x}) = \sum_i w_\mathbf{x}(\mathbf{p_i}) \mathbf{n_i} \f$ and \f$ s(\mathbf{x}) = \sum_i w_\mathbf{x}(\mathbf{p_i})\f$,
/// such that \f$ n(\mathbf{x}) = \frac{t(\mathbf{x})}{s(\mathbf{x})}\f$.
///
/// By definition, \f$ n'(\mathbf{x}) = \frac{s(\mathbf{x})t'(\mathbf{x}) - t(\mathbf{x})s'(\mathbf{x})}{s(\mathbf{x})^2}\f$.
///
/// Assuming the weight of each normal is dependent on the position, we have \f$ s'(\mathbf{x}) = \sum_i w'_\mathbf{x}(\mathbf{n_i}) \f$.
/// Assuming the weight of each normal is dependent on the position, we have \f$ s'(\mathbf{x}) = \sum_i w'_\mathbf{x}(\mathbf{p_i}) \f$.
///
/// We rewrite \f$ t(\mathbf{x}) = \sum u(\mathbf{x})v(\mathbf{x}) \f$, with \f$ u(\mathbf{x}) = w_\mathbf{x}(\mathbf{n_i}) \f$ and \f$ v(\mathbf{x}) = \mathbf{n_i} \f$.
/// We rewrite \f$ t(\mathbf{x}) = \sum u(\mathbf{x})v(\mathbf{x}) \f$, with \f$ u(\mathbf{x}) = w_\mathbf{x}(\mathbf{p_i}) \f$ and \f$ v(\mathbf{x}) = \mathbf{n_i} \f$.
///
/// Assuming the normal vectors themselves do not change with position, \f$v(\mathbf{x})\f$ is constant, its derivative is null,
/// and so \f$ t'(\mathbf{x}) = \sum_i u'(\mathbf{x}) v(\mathbf{x}) = \sum_i w'_\mathbf{x}(\mathbf{n_i}) \mathbf{n_i} \f$.
///
/// Which leads to \f$ n'(\mathbf{x}) = \frac{\sum_i w'\mathbf{x}(\mathbf{n_i}) \mathbf{n_i} - n(\mathbf{x})\sum w'(\mathbf{x})}{\sum_i w\mathbf{x}(\mathbf{n_i})} \f$.
/// Which leads to \f$ n'(\mathbf{x}) = \frac{\sum_i w'_\mathbf{x}(\mathbf{p_i}) \mathbf{n_i} - n(\mathbf{x})\sum_i w'_\mathbf{x}(\mathbf{p_i})}{\sum_i w_\mathbf{x}(\mathbf{p_i})} \f$.
/// \note This code is not directly tested.

PONCA_MULTIARCH inline const VectorArray& dMeanNormal() const
PONCA_MULTIARCH VectorArray dMeanNormal() const
{
return m_dSumN;
return ( m_dSumN - Base::meanNormalVector() * Base::m_dSumW ) / Base::getWeightSum();
}

}; //class MeanNormalDer
Expand Down

0 comments on commit 2eadc3c

Please sign in to comment.