svVascularize

svv.domain.Patch

Domain Component v1.0.0

The Patch class decomposes a domain into a set of interpolation sub-problems which can be solved independently and then blended together to form the final domain interpolation function.

Each patch represents a local region of the domain where radial basis function (RBF) interpolation is performed. Patches are the fundamental building blocks that enable efficient implicit function construction for complex geometries.

Quick Example

import numpy as np
from svv.domain.patch import Patch

# Create a patch with points and normals
points = np.array([[0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1]])
normals = np.array([[0, 0, 1], [0, 0, 1], [0, 0, 1], [0, 0, 1]])

# Initialize patch with regularization parameter
patch = Patch(lam=0.01)

# Set data
patch.set_data(points, normals)

# Solve the interpolation problem
patch.solve(method="L-BFGS-B", precision=9)

# Build the interpolation function
interpolation_func = patch.build()

# Evaluate at new points
test_points = np.array([[0.5, 0.5, 0]])
values = interpolation_func(test_points)

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 signature f(x) where x is an array of points

Function Attributes

The returned function has the following attributes:

  • points: Original patch points
  • normals: Surface normals (provided or computed)
  • dimensions: Spatial dimension
  • min, max: Bounding box
  • centroid: Center of the patch
  • a, 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 coefficients
  • bᵢ are gradient coefficients (when normals are used)
  • c and d define the polynomial trend
  • pᵢ 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 matrix
  • c are the coefficients to be found
  • f are the target values (zeros for implicit surface)
  • λ is the regularization parameter

See Also