Given a surface in $R^3$ and a point P on the surface, I want to calculate the surface normal in this point, the vector that is perpendicular to the surface.
However, I do not know the whole surface, but merely a random sampling of points on the surface.
How can I calculate a good approximation of the surface normal?
The surface is non-intersecting, smooth and roughly planar, if that matters
Select some number of close points of P. Within some radius, or the K closest neighbors.
Fit a plane to those points using Linear least squares. Possibly weigh points closer to P higher, using Weighted least squares. $$ a \cdot \left( x - x_0 \right) + b \cdot \left( y - y_0 \right) + c \cdot \left( z - z_0 \right) = 1 $$ $$ A X = B $$ $$ \hat X = \left( A^\intercal A \right)^{-1} A^\intercal B \\ \textbf{or} \\ \hat X = \left( A^\intercal W A \right)^{-1} A^\intercal W B $$
A has one row for each point, minus P.
B is column vector filled with ones.
X is the vector $ \begin{pmatrix} a & b & c \end{pmatrix}^\intercal $.
$ \hat X $ is the estimation of X.
W is a diagonal matrix with the weight of each point.
Calculate the normal of the plane. This is just the norm of X in the above equations.
Here are some papers on the subject: