Constructor
Patch(lam=0)
Parameters
Parameter | Type | Default | Description |
---|---|---|---|
lam |
float | 0 | Regularization parameter (lambda) for the RBF interpolation. Higher values provide more smoothing. |
Attributes
Attribute | Type | Description |
---|---|---|
points |
np.ndarray | Points defining the patch (n×d array) |
normals |
np.ndarray | Normal vectors at each point (n×d array, optional) |
kernel |
Kernel | Kernel object for RBF calculations |
solver |
Solver | Optimization solver for finding RBF coefficients |
constants |
np.ndarray | Solved coefficients for the interpolation function |
rbf_degree |
int | Degree of the RBF (default: 3 for Duchon's thin-plate spline) |
lam |
float | Regularization parameter |
Methods
set_data(*args)
Set the point cloud data for the patch.
Parameters
*args
: Variable arguments- Single argument: points array (n×d)
- Two arguments: points array (n×d) and normals array (n×d)
Notes
When normals are provided, they are used as initial values for the kernel, improving convergence and accuracy of the interpolation.
solve(method="L-BFGS-B", precision=9)
Solve the interpolation problem to find optimal RBF coefficients.
Parameters
method
(str, default="L-BFGS-B"): Optimization method- "L-BFGS-B": Limited-memory Broyden-Fletcher-Goldfarb-Shanno Bounded
- Other scipy.optimize methods are supported
precision
(int, default=9): Number of decimal places to round the constants
Notes
The solver automatically skips normal estimation if normals were provided in set_data()
.
build()
Build and return the interpolation function for the patch.
Returns
f
(callable): Interpolation function with signaturef(x)
where x is an array of points
Function Attributes
The returned function has the following attributes:
points
: Original patch pointsnormals
: Surface normals (provided or computed)dimensions
: Spatial dimensionmin
,max
: Bounding boxcentroid
: Center of the patcha
,b
,c
,d
: RBF coefficients
Interpolation Function
The interpolation function returned by build()
evaluates the implicit function at given points using Duchon's thin-plate spline formulation:
f(x) = Σᵢ aᵢ φ(||x - pᵢ||) + Σᵢ bᵢ · ∇φ(||x - pᵢ||) + c · x + d
Where:
φ(r) = r³
is the RBF kernel (cubic for 3D)aᵢ
are the RBF coefficientsbᵢ
are gradient coefficients (when normals are used)c
andd
define the polynomial trendpᵢ
are the patch points
f(x, show=False)
Evaluate the interpolation at given points.
Parameters
x
(np.ndarray): Points to evaluate (m×d array)show
(bool, default=False): Print debug information during evaluation
Returns
values
(np.ndarray): Interpolated values at the points
Examples
Basic Patch Interpolation
import numpy as np
from svv.domain.patch import Patch
# Create sample points on a sphere
theta = np.linspace(0, np.pi, 10)
phi = np.linspace(0, 2*np.pi, 10)
theta, phi = np.meshgrid(theta, phi)
x = np.sin(theta.ravel()) * np.cos(phi.ravel())
y = np.sin(theta.ravel()) * np.sin(phi.ravel())
z = np.cos(theta.ravel())
points = np.column_stack((x, y, z))
# Create patch
patch = Patch(lam=0.001)
patch.set_data(points)
# Solve interpolation
patch.solve()
# Build function
f = patch.build()
# Test interpolation
test_pt = np.array([[0.5, 0.5, 0.5]])
value = f(test_pt)
print(f"Interpolated value: {value[0]:.4f}")
Patch with Normal Constraints
# Points and normals from a surface
points = np.array([
[0, 0, 0],
[1, 0, 0.1],
[0, 1, 0.1],
[1, 1, 0.2]
])
# Normals pointing upward with slight variation
normals = np.array([
[0, 0, 1],
[0.1, 0, 0.99],
[0, 0.1, 0.99],
[0.1, 0.1, 0.98]
])
# Normalize the normals
normals = normals / np.linalg.norm(normals, axis=1, keepdims=True)
# Create patch with normal constraints
patch = Patch(lam=0.01)
patch.set_data(points, normals)
# Solve with high precision
patch.solve(method="L-BFGS-B", precision=12)
# Build and evaluate
f = patch.build()
# Create a grid for visualization
xx, yy = np.meshgrid(np.linspace(-0.5, 1.5, 20),
np.linspace(-0.5, 1.5, 20))
zz = np.zeros_like(xx)
grid_points = np.column_stack((xx.ravel(), yy.ravel(), zz.ravel()))
# Evaluate on grid
values = np.array([f(pt.reshape(1, -1))[0] for pt in grid_points])
values = values.reshape(xx.shape)
print(f"Min value: {values.min():.4f}")
print(f"Max value: {values.max():.4f}")
Accessing Interpolation Coefficients
# Create and solve a patch
patch = Patch(lam=0.0)
patch.set_data(points, normals)
patch.solve()
# Build function
f = patch.build()
# Access the RBF coefficients
print(f"RBF coefficients (a): {f.a.shape}")
print(f"Gradient coefficients (b): {f.b.shape}")
print(f"Linear coefficients (c): {f.c}")
print(f"Constant term (d): {f.d}")
# Access patch properties
print(f"Patch centroid: {f.centroid}")
print(f"Bounding box: [{f.min}, {f.max}]")
print(f"Dimensions: {f.dimensions}D")
Theory
Radial Basis Functions: The Patch class uses Duchon's thin-plate splines as the radial basis function. For 3D problems, this corresponds to φ(r) = r³, which provides C² continuity and minimal bending energy.
Hermite Interpolation: When normals are provided, the patch performs Hermite interpolation, matching both function values and derivatives at the data points. This results in more accurate surface representation.
Regularization: The lam
parameter controls the trade-off between interpolation accuracy and smoothness. Small values (near 0) give exact interpolation but may oscillate. Larger values provide smoother results but may not pass exactly through the data points.
Mathematical Formulation
The patch solves the following optimization problem:
min ||Kc - f||² + λ||c||²
Where:
K
is the kernel matrixc
are the coefficients to be foundf
are the target values (zeros for implicit surface)λ
is the regularization parameter
See Also
svv.domain.Domain
- Main domain class that uses patches