Skip to content

Bivariate Linear Piecewise Function ​

BivariateLinearPiecewiseFunction represents a piecewise-planar surface over a triangulation. Every cell has three vertices (xtk,ytk,ztk).

Solver mathematical model ​

Let st∈{0,1} select a triangle and λtk∈[0,1] be its barycentric weights. Both implementations enforce exactly one active triangle whose weights sum to one, and express the coordinates as weighted sums over all vertices:

∑tst=1,x=∑t,kxtkλtk,y=∑t,kytkλtk,z=∑t,kztkλtk.

Rust ties each weight group to its selector with the per-triangle equality ∑k=02λtk=st and registers the z relation as an explicit equality row. Kotlin instead combines the global row ∑t,kλtk=1 with the SOS2-style rows ∑k=02λtk≤3st per triangle and exposes z=∑t,kztkλtk directly as resultPolynomial; for binary st the two encodings describe the same feasible set.

Only one triangle may carry nonzero weights. This is different from an unrestricted convex hull over all vertices and therefore preserves the piecewise surface across non-coplanar cells.

Direct evaluation ​

For each triangle, the evaluator computes barycentric coordinates (λ0,λ1,λ2). Both implementations use the same geometry tolerance 1e-12: weights down to -1e-12 are accepted. The first triangle for which every weight is within that tolerance contains the input, and

z=λ0z0+λ1z1+λ2z2.

Inputs outside every triangle return null/None. Construction rejects every triangle with a non-finite coordinate or an absolute 2-D determinant at or below 1e-12; degenerate triangles therefore cannot reach evaluation in either implementation.

Kotlin/Rust example ​

kotlin
val surface = BivariateLinearPiecewiseFunction(
    x = xPolynomial,
    y = yPolynomial,
    triangles = triangles,
    converter = IntoValue.Identity,
    name = "surface"
)
rust
let surface = BivariateLinearPiecewiseFunction::new(
    1,
    "surface",
    x_input,
    y_input,
    vec![Triangle3::new(
        Point3::new(0.0, 0.0, 0.0),
        Point3::new(1.0, 0.0, 10.0),
        Point3::new(0.0, 1.0, 20.0),
    )],
);
assert_eq!(surface.selector_variables().len(), 1);

Tests and references ​