Hello gophers. This thread seeks to concretely define the scope of the spatial/r3 package and the spatial/r2 package.
BackgroundI am a mechanical engineer who works with physical simulations and has interest in CAD using Golang. I have started using gonum due to the excellent design of the spatial/r3 and spatial/r2 packages. Today I rely on lots of spatial code I have programmed which I feel belongs in a common gonum package which could be spatial/r3 or a new spatial package.
These include
* Spatial primitives like line and plane types for minimum distance calculations
* Triangle types for 3D/2D meshing and graphical rendering
*Tetrahedron for 3D meshing solids or volumes
* Affine transform for spatial linear transformations of vectors
* scalar and vector field differentiation (Hessian, Gradient, Divergence, Laplacian)
* Box type for 3D rendering
* Element-wise vector functions
Scope of additions
Most additions below apply to the r2 package as well with the exception of Tetrahedron and Plane types.
New type additions
The types mentioned above would amount to the following signature addition in the r3 package
type (
Tetrahedron [4]Vec
Triangle [3]Vec
Line [2]Vec
Plane struct{ P, n Vec }
Affine struct{ mat [16]float64 }
)
The Box type is not included since it already is part of r3. Although a triangle can represent a plane it is suggested a dedicated type be used since minimum distance calculation depends on having the unit normal to the plane. If instead triangle's Normal() method was used this would call
math.Sqrt twice during minimum distance calculation, a far cry from simple addition and subtraction necessary with a dedicated Plane type. Worth noting dedicated Plane type also uses less memory, 2 vs. 3 vectors for representation.
Package level functions additions
New package level functions would amount to the following:
func Gradient(p Vec, tol float64, f func(Vec) float64) Vec
func Divergence(p Vec, tol float64, f func(Vec) Vec) float64
func Laplacian(p Vec, tol float64, f func(Vec) float64) float64
It is worth noting Laplacian can be constructed as follows from Gradient and Divergence though this would incur the cost of calling f twice as much.
func Laplacian(p Vec, tol float64, f func(Vec) float64) float64 {
return Divergence(p, tol, func(v Vec) Vec { return Gradient(p, tol, f) })
}
The functions corresponding to Hessian and Jacobian should be added as methods to the existing r3.Mat type. These should set the matrix to the result.
I mentioned the use of element-wise vector functions. These are commonly used for computer graphics for bounding box calculations. I have not included them here since they would bloat the API and are rather easy to implement and have a niche application.
Package level constructors added
Some of the new types would need constructors to be used effectively. These are detailed as follows
For new Affine type NewAffine gives users precise control over how the linear transformation is constructed.
func NewAffine(a []float64) Affine
ComposeAffine is a shorthand way of setting rotational, translational and scaling parameters of the linear transform
func ComposeAffine(position, scale Vec, q Rotation) Affine
To construct a valid plane for best performance the normal vector must be normalized. This means a constructor is necessary to avoid giving users a footgun. The normal vector field would then be unexported.
func NewPlane(pointOnPlane, normal Vec) Plane
Transformer interface special consideration
It has been discussed that vector transformations could be expressed as an interface as follows
Idiomatic Go:
type Transformer interface {
Transform(Vec) Vec
}
alternative with more familiar mathematical terminology:
type Transform interface {
Apply(Vec) Vec
}
gonum/spatial/r3 types Rotation and Affine would then implement this interface and help users design APIs that use these or other transformations. An example of where this is needed is the sdf package with the
Transform3D function.
Relevant links to this discussion
issue
#1809 spatial/r3: Transformer interface and scope of r3 package
issue
#1808 spatial/r3: Add Tetrahedron type
issue
#1797 proposal: spatial manipulation matrices (Affine transforms)
issue
#1791 proposal: spatial package: add Box, Triangle types and Elem functions