Documentation ¶
Overview ¶
Package model2d provides various tools for loading, manipulating, saving, and using 2D shapes. It is also intended to aid in creating 3D models which incorporate 2D shapes in some way.
Index ¶
- Constants
- func BoundsValid(b Bounder) bool
- func CacheScalarFunc(f func(float64) float64) func(float64) float64
- func ColliderContains(c Collider, coord Coord, margin float64) bool
- func Colorize(g *image.Gray, co color.Color) *image.RGBA
- func ColorizeOverlay(gs []*image.Gray, cs []color.Color) *image.RGBA
- func CurveEvalX(c Curve, x float64) float64
- func CurveInverseX(c Curve, x float64) float64
- func EncodeCSV(m *Mesh) []byte
- func EncodeCustomSVG(meshes []*Mesh, colors []string, thicknesses []float64, bounds Bounder) []byte
- func EncodeSVG(m *Mesh) []byte
- func GroupBounders(objects []Bounder)
- func GroupSegments(faces []*Segment)
- func InBounds(b Bounder, c Coord) bool
- func MarchingSquaresASCII(s Solid, delta float64) string
- func Rasterize(path string, obj interface{}, scale float64) error
- func RasterizeColor(path string, objs []interface{}, colors []color.Color, scale float64) error
- func SaveImage(path string, img image.Image) error
- func Triangulate(polygon []Coord) [][3]Coord
- func TriangulateMesh(m *Mesh) [][3]Coord
- type BVH
- type BezierCurve
- func (b BezierCurve) CachedEvalX(x float64) func(float64) float64
- func (b BezierCurve) Eval(t float64) Coord
- func (b BezierCurve) EvalX(x float64) float64
- func (b BezierCurve) InverseX(x float64) float64
- func (b BezierCurve) Length(tol float64, maxSplits int) float64
- func (b BezierCurve) Split(t float64) (BezierCurve, BezierCurve)
- func (b BezierCurve) Transpose() BezierCurve
- type BezierFitter
- func (b *BezierFitter) FirstGuess(points []Coord) BezierCurve
- func (b *BezierFitter) FirstGuessConstrained(points []Coord, t1, t2 *Coord) BezierCurve
- func (b *BezierFitter) Fit(m *Mesh) []BezierCurve
- func (b *BezierFitter) FitChain(points []Coord, closed bool) []BezierCurve
- func (b *BezierFitter) FitCubic(points []Coord, start BezierCurve) BezierCurve
- func (b *BezierFitter) FitCubicConstrained(points []Coord, t1, t2 *Coord, start BezierCurve) BezierCurve
- func (b *BezierFitter) MSE(points []Coord, curve BezierCurve) float64
- type Bitmap
- type Bounder
- type Circle
- type Collider
- type ColliderSolid
- type ColorBitFunc
- type ConvexPolytope
- type Coord
- func NewCoordArray(a [2]float64) Coord
- func NewCoordPolar(theta, radius float64) Coord
- func NewCoordRandBounds(min, max Coord) Coord
- func NewCoordRandNorm() Coord
- func NewCoordRandUniform() Coord
- func NewCoordRandUnit() Coord
- func Ones(a float64) Coord
- func ProjectMedialAxis(p PointSDF, c Coord, iters int, eps float64) Coord
- func X(x float64) Coord
- func XY(x, y float64) Coord
- func Y(y float64) Coord
- func (c Coord) Add(c1 Coord) Coord
- func (c Coord) AddScalar(s float64) Coord
- func (c Coord) Array() [2]float64
- func (c Coord) Dist(c1 Coord) float64
- func (c Coord) Div(c1 Coord) Coord
- func (c Coord) Dot(c1 Coord) float64
- func (c Coord) L1Dist(c1 Coord) float64
- func (c Coord) Max(c1 Coord) Coord
- func (c Coord) Mid(c1 Coord) Coord
- func (c Coord) Min(c1 Coord) Coord
- func (c Coord) Mul(c1 Coord) Coord
- func (c Coord) Norm() float64
- func (c Coord) Normalize() Coord
- func (c Coord) ProjectOut(c1 Coord) Coord
- func (c Coord) Recip() Coord
- func (c Coord) Reflect(c1 Coord) Coord
- func (c Coord) Scale(s float64) Coord
- func (c Coord) SquaredDist(c1 Coord) float64
- func (c Coord) Sub(c1 Coord) Coord
- func (c Coord) Sum() float64
- type CoordMap
- func (m *CoordMap) Delete(key Coord)
- func (m *CoordMap) KeyRange(f func(key Coord) bool)
- func (m *CoordMap) Len() int
- func (m *CoordMap) Load(key Coord) (interface{}, bool)
- func (m *CoordMap) Range(f func(key Coord, value interface{}) bool)
- func (m *CoordMap) Store(key Coord, value interface{})
- func (m *CoordMap) Value(key Coord) interface{}
- func (m *CoordMap) ValueRange(f func(value interface{}) bool)
- type CoordToCoord
- func (m *CoordToCoord) Delete(key Coord)
- func (m *CoordToCoord) KeyRange(f func(key Coord) bool)
- func (m *CoordToCoord) Len() int
- func (m *CoordToCoord) Load(key Coord) (Coord, bool)
- func (m *CoordToCoord) Range(f func(key Coord, value Coord) bool)
- func (m *CoordToCoord) Store(key Coord, value Coord)
- func (m *CoordToCoord) Value(key Coord) Coord
- func (m *CoordToCoord) ValueRange(f func(value Coord) bool)
- type CoordToFaces
- func (m *CoordToFaces) Append(key Coord, x *Segment) []*Segment
- func (m *CoordToFaces) Delete(key Coord)
- func (m *CoordToFaces) KeyRange(f func(key Coord) bool)
- func (m *CoordToFaces) Len() int
- func (m *CoordToFaces) Load(key Coord) ([]*Segment, bool)
- func (m *CoordToFaces) Range(f func(key Coord, value []*Segment) bool)
- func (m *CoordToFaces) Store(key Coord, value []*Segment)
- func (m *CoordToFaces) Value(key Coord) []*Segment
- func (m *CoordToFaces) ValueRange(f func(value []*Segment) bool)
- type CoordToInt
- func (m *CoordToInt) Add(key Coord, x int) int
- func (m *CoordToInt) Delete(key Coord)
- func (m *CoordToInt) KeyRange(f func(key Coord) bool)
- func (m *CoordToInt) Len() int
- func (m *CoordToInt) Load(key Coord) (int, bool)
- func (m *CoordToInt) Range(f func(key Coord, value int) bool)
- func (m *CoordToInt) Store(key Coord, value int)
- func (m *CoordToInt) Value(key Coord) int
- func (m *CoordToInt) ValueRange(f func(value int) bool)
- type CoordTree
- func (c *CoordTree) Contains(p Coord) bool
- func (c *CoordTree) Dist(p Coord) float64
- func (c *CoordTree) Empty() bool
- func (c *CoordTree) KNN(k int, p Coord) []Coord
- func (c *CoordTree) Leaf() bool
- func (c *CoordTree) NearestNeighbor(p Coord) Coord
- func (c *CoordTree) Slice() []Coord
- func (c *CoordTree) SphereCollision(p Coord, r float64) bool
- type Curve
- type DistTransform
- type EdgeMap
- func (m *EdgeMap) Delete(key [2]Coord)
- func (m *EdgeMap) KeyRange(f func(key [2]Coord) bool)
- func (m *EdgeMap) Len() int
- func (m *EdgeMap) Load(key [2]Coord) (interface{}, bool)
- func (m *EdgeMap) Range(f func(key [2]Coord, value interface{}) bool)
- func (m *EdgeMap) Store(key [2]Coord, value interface{})
- func (m *EdgeMap) Value(key [2]Coord) interface{}
- func (m *EdgeMap) ValueRange(f func(value interface{}) bool)
- type EdgeToBool
- func (m *EdgeToBool) Delete(key [2]Coord)
- func (m *EdgeToBool) KeyRange(f func(key [2]Coord) bool)
- func (m *EdgeToBool) Len() int
- func (m *EdgeToBool) Load(key [2]Coord) (bool, bool)
- func (m *EdgeToBool) Range(f func(key [2]Coord, value bool) bool)
- func (m *EdgeToBool) Store(key [2]Coord, value bool)
- func (m *EdgeToBool) Value(key [2]Coord) bool
- func (m *EdgeToBool) ValueRange(f func(value bool) bool)
- type EdgeToInt
- func (m *EdgeToInt) Add(key [2]Coord, x int) int
- func (m *EdgeToInt) Delete(key [2]Coord)
- func (m *EdgeToInt) KeyRange(f func(key [2]Coord) bool)
- func (m *EdgeToInt) Len() int
- func (m *EdgeToInt) Load(key [2]Coord) (int, bool)
- func (m *EdgeToInt) Range(f func(key [2]Coord, value int) bool)
- func (m *EdgeToInt) Store(key [2]Coord, value int)
- func (m *EdgeToInt) Value(key [2]Coord) int
- func (m *EdgeToInt) ValueRange(f func(value int) bool)
- type FaceSDF
- type GeneralBVH
- type InterpBitmap
- func (b *InterpBitmap) Bitmap() *Bitmap
- func (b *InterpBitmap) Contains(c Coord) bool
- func (b *InterpBitmap) FlipX() *InterpBitmap
- func (b *InterpBitmap) FlipY() *InterpBitmap
- func (b *InterpBitmap) Get(x, y int) color.RGBA
- func (b *InterpBitmap) Invert() *InterpBitmap
- func (b *InterpBitmap) Max() Coord
- func (b *InterpBitmap) Min() Coord
- type Interpolator
- type IntersectedSolid
- type JoinedCollider
- type JoinedCurve
- type JoinedSolid
- type JoinedTransform
- type LinearConstraint
- type Matrix2
- func (m *Matrix2) Add(m1 *Matrix2) *Matrix2
- func (m *Matrix2) Det() float64
- func (m *Matrix2) Eigenvalues() [2]complex128
- func (m *Matrix2) Inverse() *Matrix2
- func (m *Matrix2) InvertInPlace()
- func (m *Matrix2) InvertInPlaceDet(det float64)
- func (m *Matrix2) Mul(m1 *Matrix2) *Matrix2
- func (m *Matrix2) MulColumn(c Coord) Coord
- func (m *Matrix2) MulColumnInv(c Coord, det float64) Coord
- func (m *Matrix2) SVD(u, s, v *Matrix2)
- func (m *Matrix2) Scale(s float64)
- func (m *Matrix2) Transpose() *Matrix2
- type Matrix2Transform
- type Mesh
- func MarchingSquares(s Solid, delta float64) *Mesh
- func MarchingSquaresConj(s Solid, delta float64, iters int, xforms ...Transform) *Mesh
- func MarchingSquaresSearch(s Solid, delta float64, iters int) *Mesh
- func NewMesh() *Mesh
- func NewMeshPolar(radius func(theta float64) float64, stops int) *Mesh
- func NewMeshRect(min, max Coord) *Mesh
- func NewMeshSegments(faces []*Segment) *Mesh
- func (m *Mesh) Add(f *Segment)
- func (m *Mesh) AddMesh(m1 *Mesh)
- func (m *Mesh) Blur(rate float64) *Mesh
- func (m *Mesh) Contains(f *Segment) bool
- func (m *Mesh) Decimate(maxVertices int) *Mesh
- func (m *Mesh) EliminateColinear(epsilon float64) *Mesh
- func (m *Mesh) Find(ps ...Coord) []*Segment
- func (m *Mesh) Invert() *Mesh
- func (m *Mesh) Iterate(f func(*Segment))
- func (m *Mesh) IterateSorted(f func(*Segment), cmp func(f1, f2 *Segment) bool)
- func (m *Mesh) IterateVertices(f func(c Coord))
- func (m *Mesh) Manifold() bool
- func (m *Mesh) MapCoords(f func(Coord) Coord) *Mesh
- func (m *Mesh) Max() Coord
- func (m *Mesh) Min() Coord
- func (m *Mesh) Neighbors(f *Segment) []*Segment
- func (m *Mesh) Remove(f *Segment)
- func (m *Mesh) Repair(epsilon float64) *Mesh
- func (m *Mesh) RepairNormals(epsilon float64) (*Mesh, int)
- func (m *Mesh) Rotate(angle float64) *Mesh
- func (m *Mesh) SaveSVG(path string) error
- func (m *Mesh) Scale(s float64) *Mesh
- func (m *Mesh) SegmentSlice() []*Segment
- func (m *Mesh) SegmentsSlice() []*Segment
- func (m *Mesh) Smooth(iters int) *Mesh
- func (m *Mesh) SmoothSq(iters int) *Mesh
- func (m *Mesh) Subdivide(iters int) *Mesh
- func (m *Mesh) Transform(t Transform) *Mesh
- func (m *Mesh) Translate(v Coord) *Mesh
- func (m *Mesh) VertexSlice() []Coord
- type MeshHierarchy
- type MultiCollider
- type PointSDF
- type Rasterizer
- func (r *Rasterizer) Rasterize(obj interface{}) *image.Gray
- func (r *Rasterizer) RasterizeCollider(c Collider) *image.Gray
- func (r *Rasterizer) RasterizeColliderSolid(c Collider) *image.Gray
- func (r *Rasterizer) RasterizeSolid(s Solid) *image.Gray
- func (r *Rasterizer) RasterizeSolidFilter(s Solid, f func(r *Rect) bool) *image.Gray
- type Ray
- type RayCollision
- type Rect
- type RectCollider
- type SDF
- type Scale
- type Segment
- func (s *Segment) CircleCollision(c Coord, r float64) bool
- func (s Segment) Closest(c Coord) Coord
- func (s Segment) Dist(c Coord) float64
- func (s *Segment) FirstRayCollision(r *Ray) (RayCollision, bool)
- func (s Segment) Length() float64
- func (s Segment) Max() Coord
- func (s Segment) Mid() Coord
- func (s Segment) Min() Coord
- func (s *Segment) Normal() Coord
- func (s *Segment) RayCollisions(r *Ray, f func(RayCollision)) int
- func (s *Segment) RectCollision(r *Rect) bool
- func (s *Segment) SegmentCollision(s1 *Segment) bool
- type SegmentCollider
- type Solid
- func BitmapToSolid(b *Bitmap) Solid
- func CacheSolidBounds(s Solid) Solid
- func CheckedFuncSolid(min, max Coord, f func(Coord) bool) Solid
- func ForceSolidBounds(s Solid, min, max Coord) Solid
- func FuncSolid(min, max Coord, f func(Coord) bool) Solid
- func RotateSolid(solid Solid, axis Coord, angle float64) Solid
- func ScaleSolid(solid Solid, s float64) Solid
- func SmoothJoin(radius float64, sdfs ...SDF) Solid
- func TransformSolid(t Transform, s Solid) Solid
- func TranslateSolid(solid Solid, offset Coord) Solid
- type SubtractedSolid
- type Transform
- type Translate
Constants ¶
const ( DefaultBezierFitterNumIters = 100 DefaultBezierFitTolerance = 1e-8 DefaultBezierFitDelta = 1e-5 DefaultBezierFitMinStepScale = 1e-2 DefaultBezierFitLineStep = 2.0 DefaultBezierFitLineGSS = 8 )
const ( DefaultMedialAxisIters = 32 DefaultMedialAxisEps = 1e-8 )
const ( RasterizerDefaultSubsamples = 8 RasterizerDefaultLineWidth = 1.0 )
const DefaultBezierMaxSplits = 16
DefaultBezierMaxSplits determines the maximum number of subdivisions when computing Bezier arc lengths.
Variables ¶
This section is empty.
Functions ¶
func BoundsValid ¶ added in v0.2.9
BoundsValid checks for numerical issues with the bounds.
func CacheScalarFunc ¶ added in v0.2.13
CacheScalarFunc creates a scalar function that is equivalent to a deterministic function f, but caches results across calls in a concurrency-safe manner.
func ColliderContains ¶
ColliderContains checks if a point is within a Collider and at least margin away from the border.
If the margin is negative, points are also conatined if the point is less than -margin away from the surface.
func Colorize ¶ added in v0.2.13
Colorize turns a grayscale image into a color image with an alpha channel.
It is assumed that black (0) is "positive" while white (0xff) is negative.
func ColorizeOverlay ¶ added in v0.2.13
ColorizeOverlay turns a series of grayscale images into corresponding colors and then overlays them, each on top of the last.
All images must have the same bounds.
func CurveEvalX ¶ added in v0.2.6
CurveEvalX finds the y value that occurs at the given x value, assuming that the curve is monotonic in x.
If the y value cannot be found, NaN is returned.
func CurveInverseX ¶ added in v0.2.6
CurveInverseX gets the t value between 0 and 1 where the x value is equal to some x, assuming the curve is monotonic in x.
If the t cannot be found, NaN is returned.
func EncodeCustomSVG ¶ added in v0.2.11
EncodeCustomSVG encodes multiple meshes, each with a different color and line thickness.
If bounds is not nil, it is used to determine the resulting bounds of the SVG. Otherwise, the union of all meshes is used.
func GroupBounders ¶ added in v0.2.11
func GroupBounders(objects []Bounder)
GroupBounders sorts a slice of objects into a balanced bounding box hierarchy.
The sorted slice can be recursively cut in half, and each half will be spatially separated as well as possible along some axis. To cut a slice in half, divide the length by two, round down, and use the result as the start index for the second half.
func GroupSegments ¶
func GroupSegments(faces []*Segment)
GroupSegments is like GroupBounders, but for segments in particular.
This can be used to prepare models for being turned into a collider efficiently, or for storing meshes in an order well-suited for file compression.
The resulting hierarchy can be passed directly to GroupedSegmentsToCollider().
func MarchingSquaresASCII ¶ added in v0.2.8
MarchingSquaresASCII turns a Solid into an ASCII-art line-drawing using a 2D version of marching cubes.
The delta is used as the horizontal spacing, and an aspect ratio of 2.0 (height/width) is assumed.
func Rasterize ¶ added in v0.2.6
Rasterize renders a Solid, Collider, or Mesh to an image file.
The bounds of the object being rendered are scaled by the provided scale factor to convert to pixel coordinates.
This uses the default rasterization settings, such as the default line width and anti-aliasing settings. To change this, use a Rasterizer object directly.
func RasterizeColor ¶ added in v0.2.13
RasterizeColor is like Rasterize, but it renders multiple objects in different colors.
func SaveImage ¶ added in v0.2.7
SaveImage saves a rasterized image to a file, inferring the file type from the extension.
func Triangulate ¶
Triangulate turns any simple polygon into a set of equivalent triangles.
The polygon is passed as a series of points, in order. The first point is re-used as the ending point, so no ending should be explicitly specified.
Unlike TriangulateMesh, the order of the coordinates needn't be clockwise, and the orientation of the resulting triangles is undefined.
This should only be used for polygons with several vertices. For more complex shapes, use TriangulateMesh.
func TriangulateMesh ¶ added in v0.2.10
TriangulateMesh creates a minimal collection of triangles that cover the enclosed region of a mesh.
The mesh must be manifold, non-intersecting, and have the correct orientation (i.e. correct normals). The mesh may have holes, and is assumed to obey the even-odd rule for containment. If the mesh does not meet the expected criteria, the behavior of TriangulateMesh is undefined and may result in a panic.
The vertices of the resulting triangles are ordered clockwise (assuming a y-axis that points upward). This way, each triangle can itself be considered a minimal, correctly-oriented mesh.
Types ¶
type BVH ¶ added in v0.2.11
type BVH struct { // Leaf, if non-nil, is the sole object in this node. Leaf *Segment // Branch, if Leaf is nil, points to two children. Branch []*BVH }
BVH represents a (possibly unbalanced) axis-aligned bounding box hierarchy of segments.
A BVH can be used to accelerate collision detection. See BVHToCollider() for more details.
A BVH node is either a leaf (a single segment), or a branch with two or more children.
For a more generic BVH that supports any object rather than just segments, see GeneralBVH.
func NewBVHAreaDensity ¶ added in v0.2.11
NewBVHAreaDensity is like NewGeneralBVHAreaDensity but for segments.
type BezierCurve ¶
type BezierCurve []Coord
BezierCurve implements an arbitrarily high-dimensional Bezier curve.
func (BezierCurve) CachedEvalX ¶ added in v0.2.13
func (b BezierCurve) CachedEvalX(x float64) func(float64) float64
CachedEvalX returns a function like EvalX that is cached between calls in a concurrency-safe manner.
func (BezierCurve) Eval ¶
func (b BezierCurve) Eval(t float64) Coord
Eval evaluates the curve at time t, where 0 <= t <= 1.
func (BezierCurve) EvalX ¶
func (b BezierCurve) EvalX(x float64) float64
EvalX finds the y value that occurs at the given x value, assuming that the curve is monotonic in x.
If the y value cannot be found, NaN is returned.
func (BezierCurve) InverseX ¶
func (b BezierCurve) InverseX(x float64) float64
InverseX gets the t value between 0 and 1 where the x value is equal to some x, assuming the curve is monotonic in x.
If the t cannot be found, NaN is returned.
func (BezierCurve) Length ¶ added in v0.2.22
func (b BezierCurve) Length(tol float64, maxSplits int) float64
Length approximates the arclength of the curve within the given margin of error.
If maxSplits is specified, it determines the maximum number of sub-divisions to perform. Otherwise, DefaultBezierMaxSplits is used.
func (BezierCurve) Split ¶ added in v0.2.22
func (b BezierCurve) Split(t float64) (BezierCurve, BezierCurve)
Split creates two Bezier curves from b, where the first curve represents b in the range [0, t] and the second in the range [t, 1].
func (BezierCurve) Transpose ¶
func (b BezierCurve) Transpose() BezierCurve
Transpose generates a BezierCurve where x and y are swapped.
type BezierFitter ¶ added in v0.2.15
type BezierFitter struct { // NumIters is the number of gradient steps to use to // fit each Bezier curve. // If 0, DefaultBezierFitterNumIters is used. NumIters int // Tolerance is the maximum mean-squared error for a // curve when fitting a chain of connected points. // It is relative to the area of the bounding box of // the points in the chain. // // If 0, DefaultBezierFitTolerance is used. Tolerance float64 // Delta, if specified, controls the step size used // for finite differences, relative to the size of the // entire Bezier curve. // If 0, DefaultBezierFitDelta is used. Delta float64 // L2Penalty, if specified, is a loss penalty imposed // on the squared distance between the control points // and their corresponding endpoints, scaled relative // to the distance between the endpoints. L2Penalty float64 // MinStepScale, if specified, is a scalar multiplied // by the finite-differences delta to decide the first // (and smallest) step to try for line search. // If 0, DefaultBezierFitMinStepScale is used. MinStepScale float64 // LineStep, if specified, is the rate of increase for // each step of line search. Larger values make line // search faster, but can miss local minima. // If 0, DefaultBezierFitLineStep is used. LineStep float64 // LineGSS, if specified, is the number of steps used // for golden section search at the end of line // search. Higher values yield more precise steps. // If 0, DefaultBezierFitLineGSS is used. LineGSS int // Momentum, if specified, is the momentum coefficient. // If 0, regular gradient descent is used. Momentum float64 // AllowIntersections can be set to true to allow // Bezier curves to cross themselves. AllowIntersections bool // NoFirstGuess disables FirstGuess() approximations // during Fit() and FitChain() calls. NoFirstGuess bool }
A BezierFitter fits Bezier curves to points.
func (*BezierFitter) FirstGuess ¶ added in v0.2.15
func (b *BezierFitter) FirstGuess(points []Coord) BezierCurve
FirstGuess attempts to quickly approximate some subset of the specified points with a cubic Bezier curve, allowing for potentially faster convergence when fitting all of the points.
This method assumes that all of the points are sorted along the curve from a start point to an end point, and no two points are exactly equal. This is a stronger assumption than FitCubic() makes.
func (*BezierFitter) FirstGuessConstrained ¶ added in v0.2.22
func (b *BezierFitter) FirstGuessConstrained(points []Coord, t1, t2 *Coord) BezierCurve
FirstGuessConstrained is like FirstGuess, but the control points are optionally constrained to given tangent directions.
func (*BezierFitter) Fit ¶ added in v0.2.15
func (b *BezierFitter) Fit(m *Mesh) []BezierCurve
Fit fits a collection of cubic Bezier curves to a manifold mesh.
func (*BezierFitter) FitChain ¶ added in v0.2.15
func (b *BezierFitter) FitChain(points []Coord, closed bool) []BezierCurve
FitChain fits a sequence of points along some curve using one or more cubic Bezier curves.
The closed argument indicates if the final point should be smoothly reconnected to the first point.
The points should be ordered along the desired curve, and no two points should be exactly equal.
func (*BezierFitter) FitCubic ¶ added in v0.2.15
func (b *BezierFitter) FitCubic(points []Coord, start BezierCurve) BezierCurve
FitCubic finds the cubic Bezier curve of best fit for the points.
The first and last points are used as start and end points, and all the other points may be in any order.
func (*BezierFitter) FitCubicConstrained ¶ added in v0.2.15
func (b *BezierFitter) FitCubicConstrained(points []Coord, t1, t2 *Coord, start BezierCurve) BezierCurve
FitCubicConstrained is like FitCubic, but constrains the tangent vectors at either the start or end point, or both.
If non-nil, t1 is the direction for the first control point from the first point, and t2 is the direction of the second control point from the last point.
func (*BezierFitter) MSE ¶ added in v0.2.15
func (b *BezierFitter) MSE(points []Coord, curve BezierCurve) float64
MSE computes the MSE of a cubic Bezier fit.
type Bitmap ¶
A Bitmap is a two-dimensional image with boolean values. The data is stored in row-major order.
func MustReadBitmap ¶
func MustReadBitmap(path string, c ColorBitFunc) *Bitmap
MustReadBitmap is like ReadBitmap, except that it panics if the bitmap cannot be read.
func NewBitmapImage ¶
func NewBitmapImage(img image.Image, c ColorBitFunc) *Bitmap
NewBitmapImage creates a Bitmap from an image, by calling c for each pixel and using the result as the bit.
If c is nil, then the mean RGBA is computed, and pixels are considered true if they are closer to the mean in L2 distance than they are to the top-left pixel. For images with two dominant colors, this is equivalent to making the background false, and the foreground true, assuming that the first pixel is background.
func ReadBitmap ¶
func ReadBitmap(path string, c ColorBitFunc) (*Bitmap, error)
ReadBitmap is like NewBitmapImage, except that it reads the image from a file.
func (*Bitmap) Get ¶
Get gets the bit at the coordinate.
If the coordinate is out of bounds, false is returned.
type Bounder ¶
type Bounder interface { // Get the corners of a bounding box. // // A point p satisfies p >= Min and p <= Max if it is // within the bounds. Min() Coord Max() Coord }
A Bounder is an object contained in an axis-aligned bounding box.
type Collider ¶
type Collider interface { Bounder // RayCollisions enumerates the collisions with a ray. // It returns the total number of collisions. // // f may be nil, in which case this is simply used for // counting. RayCollisions(r *Ray, f func(RayCollision)) int // FirstRayCollision gets the ray collision with the // lowest scale. // // The second return value is false if no collisions // were found. FirstRayCollision(r *Ray) (collision RayCollision, collides bool) // CircleCollision checks if the collider touches a // circle with origin c and radius r. CircleCollision(c Coord, r float64) bool }
A Collider is the outline of a 2-dimensional shape. It can count its intersections with a ray, and check if any part of the outline is inside a circle.
All methods of a Collider are safe for concurrency.
func TransformCollider ¶ added in v0.2.11
func TransformCollider(t DistTransform, c Collider) Collider
TransformCollider applies t to the Collider c to produce a new, transformed Collider.
type ColliderSolid ¶
type ColliderSolid struct {
// contains filtered or unexported fields
}
A ColliderSolid is a Solid that uses a Collider to check if points are in the solid.
There are two modes for a ColliderSolid. In the first, points are inside the solid if a ray passes through the surface of the Collider an odd number of times. In the second, points are inside the solid if a sphere of a pre-determined radius touches the surface of the Collider from the point. The second modality is equivalent to creating a thick but hollow solid.
func NewColliderSolid ¶
func NewColliderSolid(c Collider) *ColliderSolid
NewColliderSolid creates a basic ColliderSolid.
func NewColliderSolidHollow ¶
func NewColliderSolidHollow(c Collider, r float64) *ColliderSolid
NewColliderSolidHollow creates a ColliderSolid that only reports containment around the edges.
func NewColliderSolidInset ¶
func NewColliderSolidInset(c Collider, inset float64) *ColliderSolid
NewColliderSolidInset creates a ColliderSolid that only reports containment at some distance from the surface.
If inset is negative, then the solid is outset from the collider.
func (*ColliderSolid) Contains ¶
func (c *ColliderSolid) Contains(coord Coord) bool
Contains checks if coord is in the solid.
func (*ColliderSolid) Max ¶
func (c *ColliderSolid) Max() Coord
Max gets the maximum of the bounding box.
func (*ColliderSolid) Min ¶
func (c *ColliderSolid) Min() Coord
Min gets the minimum of the bounding box.
type ColorBitFunc ¶
ColorBitFunc turns colors into single bits.
type ConvexPolytope ¶ added in v0.2.11
type ConvexPolytope []*LinearConstraint
A ConvexPolytope is the intersection of some linear constraints.
func NewConvexPolytopeRect ¶ added in v0.2.11
func NewConvexPolytopeRect(min, max Coord) ConvexPolytope
NewConvexPolytopeRect creates a rectangular convex polytope.
func (ConvexPolytope) Contains ¶ added in v0.2.11
func (c ConvexPolytope) Contains(coord Coord) bool
Contains checks that c satisfies the constraints.
func (ConvexPolytope) Mesh ¶ added in v0.2.11
func (c ConvexPolytope) Mesh() *Mesh
Mesh creates a mesh containing all of the finite faces of the polytope.
For complicated polytopes, this may take a long time to run, since it is O(n^2) in the constraints.
func (ConvexPolytope) Solid ¶ added in v0.2.11
func (c ConvexPolytope) Solid() Solid
Solid creates a solid out of the polytope.
This runs in O(n^2) in the constraints, so it may be unacceptable for large polytopes.
type Coord ¶
A Coord is a coordinate in 2-D Euclidean space.
func NewCoordArray ¶
NewCoordArray creates a Coord from an array of x and y.
func NewCoordPolar ¶ added in v0.2.9
NewCoordPolar converts polar coordinates to a Coord.
func NewCoordRandBounds ¶ added in v0.2.8
NewCoordRandBounds creates a random Coord uniformly inside the given rectangular boundary.
func NewCoordRandNorm ¶
func NewCoordRandNorm() Coord
NewCoordRandNorm creates a random Coord with normally distributed components.
func NewCoordRandUniform ¶ added in v0.2.4
func NewCoordRandUniform() Coord
NewCoordRandUniform creates a random Coord with uniformly random coordinates in [0, 1).
func NewCoordRandUnit ¶
func NewCoordRandUnit() Coord
NewCoordRandUnit creates a random Coord with magnitude 1.
func ProjectMedialAxis ¶ added in v0.2.8
ProjectMedialAxis projects the point c onto the medial axis of the shape defined by SDF p.
The iters argument specifies the number of search steps to perform to narrow down the medial axis. If 0, DefaultMedialAxisIters is used.
The eps argument specifies how close two points on the surface of p must be to be considered the same point. If 0, DefaultMedialAxisEps is used.
The bounds of p are used to aid computation. Thus, it is important to get tight bounds on the SDF for maximally accurate results.
func (Coord) AddScalar ¶ added in v0.2.6
AddScalar adds s to all of the coordinates and returns the new coordinate.
func (Coord) ProjectOut ¶
ProjectOut projects the c1 direction out of c.
func (Coord) SquaredDist ¶ added in v0.2.13
SquaredDist gets the squared Euclidean distance to c1.
type CoordMap ¶ added in v0.2.14
type CoordMap struct {
// contains filtered or unexported fields
}
CoordMap implements a map-like interface for mapping Coord to interface{}.
This can be more efficient than using a map directly, since it uses a special hash function for coordinates. The speed-up is variable, but was ~2x as of mid-2021.
func (*CoordMap) Delete ¶ added in v0.2.14
Delete removes the key from the map if it exists, and does nothing otherwise.
func (*CoordMap) KeyRange ¶ added in v0.2.14
KeyRange is like Range, but only iterates over keys, not values.
func (*CoordMap) Load ¶ added in v0.2.14
Load gets the value for the given key.
If no value is present, the first return argument is a zero value, and the second is false. Otherwise, the second return value is true.
func (*CoordMap) Range ¶ added in v0.2.14
Range iterates over the map, calling f successively for each value until it returns false, or all entries are enumerated.
It is not safe to modify the map with Store or Delete during enumeration.
func (*CoordMap) Store ¶ added in v0.2.14
Store assigns the value to the given key, overwriting the previous value for the key if necessary.
func (*CoordMap) ValueRange ¶ added in v0.2.14
ValueRange is like Range, but only iterates over values only.
type CoordToCoord ¶ added in v0.2.14
type CoordToCoord struct {
// contains filtered or unexported fields
}
CoordToCoord implements a map-like interface for mapping Coord to Coord.
This can be more efficient than using a map directly, since it uses a special hash function for coordinates. The speed-up is variable, but was ~2x as of mid-2021.
func NewCoordToCoord ¶ added in v0.2.14
func NewCoordToCoord() *CoordToCoord
NewCoordToCoord creates an empty map.
func (*CoordToCoord) Delete ¶ added in v0.2.14
func (m *CoordToCoord) Delete(key Coord)
Delete removes the key from the map if it exists, and does nothing otherwise.
func (*CoordToCoord) KeyRange ¶ added in v0.2.14
func (m *CoordToCoord) KeyRange(f func(key Coord) bool)
KeyRange is like Range, but only iterates over keys, not values.
func (*CoordToCoord) Len ¶ added in v0.2.14
func (m *CoordToCoord) Len() int
Len gets the number of elements in the map.
func (*CoordToCoord) Load ¶ added in v0.2.14
func (m *CoordToCoord) Load(key Coord) (Coord, bool)
Load gets the value for the given key.
If no value is present, the first return argument is a zero value, and the second is false. Otherwise, the second return value is true.
func (*CoordToCoord) Range ¶ added in v0.2.14
func (m *CoordToCoord) Range(f func(key Coord, value Coord) bool)
Range iterates over the map, calling f successively for each value until it returns false, or all entries are enumerated.
It is not safe to modify the map with Store or Delete during enumeration.
func (*CoordToCoord) Store ¶ added in v0.2.14
func (m *CoordToCoord) Store(key Coord, value Coord)
Store assigns the value to the given key, overwriting the previous value for the key if necessary.
func (*CoordToCoord) Value ¶ added in v0.2.14
func (m *CoordToCoord) Value(key Coord) Coord
Value is like Load(), but without a second return value.
func (*CoordToCoord) ValueRange ¶ added in v0.2.14
func (m *CoordToCoord) ValueRange(f func(value Coord) bool)
ValueRange is like Range, but only iterates over values only.
type CoordToFaces ¶ added in v0.2.14
type CoordToFaces struct {
// contains filtered or unexported fields
}
CoordToFaces implements a map-like interface for mapping Coord to []*Segment.
This can be more efficient than using a map directly, since it uses a special hash function for coordinates. The speed-up is variable, but was ~2x as of mid-2021.
func NewCoordToFaces ¶ added in v0.2.14
func NewCoordToFaces() *CoordToFaces
NewCoordToFaces creates an empty map.
func (*CoordToFaces) Append ¶ added in v0.2.14
func (m *CoordToFaces) Append(key Coord, x *Segment) []*Segment
Append appends x to the value stored for the given key and returns the new value.
func (*CoordToFaces) Delete ¶ added in v0.2.14
func (m *CoordToFaces) Delete(key Coord)
Delete removes the key from the map if it exists, and does nothing otherwise.
func (*CoordToFaces) KeyRange ¶ added in v0.2.14
func (m *CoordToFaces) KeyRange(f func(key Coord) bool)
KeyRange is like Range, but only iterates over keys, not values.
func (*CoordToFaces) Len ¶ added in v0.2.14
func (m *CoordToFaces) Len() int
Len gets the number of elements in the map.
func (*CoordToFaces) Load ¶ added in v0.2.14
func (m *CoordToFaces) Load(key Coord) ([]*Segment, bool)
Load gets the value for the given key.
If no value is present, the first return argument is a zero value, and the second is false. Otherwise, the second return value is true.
func (*CoordToFaces) Range ¶ added in v0.2.14
func (m *CoordToFaces) Range(f func(key Coord, value []*Segment) bool)
Range iterates over the map, calling f successively for each value until it returns false, or all entries are enumerated.
It is not safe to modify the map with Store or Delete during enumeration.
func (*CoordToFaces) Store ¶ added in v0.2.14
func (m *CoordToFaces) Store(key Coord, value []*Segment)
Store assigns the value to the given key, overwriting the previous value for the key if necessary.
func (*CoordToFaces) Value ¶ added in v0.2.14
func (m *CoordToFaces) Value(key Coord) []*Segment
Value is like Load(), but without a second return value.
func (*CoordToFaces) ValueRange ¶ added in v0.2.14
func (m *CoordToFaces) ValueRange(f func(value []*Segment) bool)
ValueRange is like Range, but only iterates over values only.
type CoordToInt ¶ added in v0.2.14
type CoordToInt struct {
// contains filtered or unexported fields
}
CoordToInt implements a map-like interface for mapping Coord to int.
This can be more efficient than using a map directly, since it uses a special hash function for coordinates. The speed-up is variable, but was ~2x as of mid-2021.
func NewCoordToInt ¶ added in v0.2.14
func NewCoordToInt() *CoordToInt
NewCoordToInt creates an empty map.
func (*CoordToInt) Add ¶ added in v0.2.14
func (m *CoordToInt) Add(key Coord, x int) int
Add adds x to the value stored for the given key and returns the new value.
func (*CoordToInt) Delete ¶ added in v0.2.14
func (m *CoordToInt) Delete(key Coord)
Delete removes the key from the map if it exists, and does nothing otherwise.
func (*CoordToInt) KeyRange ¶ added in v0.2.14
func (m *CoordToInt) KeyRange(f func(key Coord) bool)
KeyRange is like Range, but only iterates over keys, not values.
func (*CoordToInt) Len ¶ added in v0.2.14
func (m *CoordToInt) Len() int
Len gets the number of elements in the map.
func (*CoordToInt) Load ¶ added in v0.2.14
func (m *CoordToInt) Load(key Coord) (int, bool)
Load gets the value for the given key.
If no value is present, the first return argument is a zero value, and the second is false. Otherwise, the second return value is true.
func (*CoordToInt) Range ¶ added in v0.2.14
func (m *CoordToInt) Range(f func(key Coord, value int) bool)
Range iterates over the map, calling f successively for each value until it returns false, or all entries are enumerated.
It is not safe to modify the map with Store or Delete during enumeration.
func (*CoordToInt) Store ¶ added in v0.2.14
func (m *CoordToInt) Store(key Coord, value int)
Store assigns the value to the given key, overwriting the previous value for the key if necessary.
func (*CoordToInt) Value ¶ added in v0.2.14
func (m *CoordToInt) Value(key Coord) int
Value is like Load(), but without a second return value.
func (*CoordToInt) ValueRange ¶ added in v0.2.14
func (m *CoordToInt) ValueRange(f func(value int) bool)
ValueRange is like Range, but only iterates over values only.
type CoordTree ¶ added in v0.2.13
type CoordTree struct { Coord Coord // SplitAxis is the dimension to split on for branches. SplitAxis int // At least one of these is non-nil for branches. LessThan *CoordTree GreaterEqual *CoordTree }
A CoordTree is a k-d tree over Coords.
A nil *CoordTree represents an empty tree.
func NewCoordTree ¶ added in v0.2.13
func (*CoordTree) Contains ¶ added in v0.2.13
Contains checks if any point in the tree is exactly equal to p.
func (*CoordTree) Dist ¶ added in v0.2.14
Dist gets the distance from a point p to its nearest neighbor in c.
func (*CoordTree) KNN ¶ added in v0.2.13
KNN gets the closest K coordinates to p in the tree. The results are sorted by ascending distance.
If there are fewer than K coordinates in the tree, then fewer than K coordinates are returned.
func (*CoordTree) Leaf ¶ added in v0.2.13
Leaf returns true if this tree contains 1 or fewer points.
func (*CoordTree) NearestNeighbor ¶ added in v0.2.13
NearestNeighbor gets the closest coordinate to p in the tree.
This will panic() if c is empty.
type Curve ¶ added in v0.2.6
A Curve is a parametric curve that returns points for values of t in the range [0, 1].
func CurveTranspose ¶ added in v0.2.6
CurveTranspose generates a Curve where x and y are swapped from the original c.
type DistTransform ¶ added in v0.2.11
type DistTransform interface { Transform // ApplyDistance computes the distance between // t.Apply(c1) and t.Apply(c2) given the distance // between c1 and c2, where c1 and c2 are arbitrary // points. ApplyDistance(d float64) float64 }
DistTransform is a Transform that changes Euclidean distances in a coordinate-independent fashion.
The inverse of a DistTransform should also be a DistTransform.
func Rotation ¶ added in v0.2.11
func Rotation(theta float64) DistTransform
Rotation creates a rotation transformation using an angle in radians.
type EdgeMap ¶ added in v0.2.14
type EdgeMap struct {
// contains filtered or unexported fields
}
EdgeMap implements a map-like interface for mapping [2]Coord to interface{}.
This can be more efficient than using a map directly, since it uses a special hash function for coordinates. The speed-up is variable, but was ~2x as of mid-2021.
func (*EdgeMap) Delete ¶ added in v0.2.14
Delete removes the key from the map if it exists, and does nothing otherwise.
func (*EdgeMap) KeyRange ¶ added in v0.2.14
KeyRange is like Range, but only iterates over keys, not values.
func (*EdgeMap) Load ¶ added in v0.2.14
Load gets the value for the given key.
If no value is present, the first return argument is a zero value, and the second is false. Otherwise, the second return value is true.
func (*EdgeMap) Range ¶ added in v0.2.14
Range iterates over the map, calling f successively for each value until it returns false, or all entries are enumerated.
It is not safe to modify the map with Store or Delete during enumeration.
func (*EdgeMap) Store ¶ added in v0.2.14
Store assigns the value to the given key, overwriting the previous value for the key if necessary.
func (*EdgeMap) ValueRange ¶ added in v0.2.14
ValueRange is like Range, but only iterates over values only.
type EdgeToBool ¶ added in v0.2.14
type EdgeToBool struct {
// contains filtered or unexported fields
}
EdgeToBool implements a map-like interface for mapping [2]Coord to bool.
This can be more efficient than using a map directly, since it uses a special hash function for coordinates. The speed-up is variable, but was ~2x as of mid-2021.
func NewEdgeToBool ¶ added in v0.2.14
func NewEdgeToBool() *EdgeToBool
NewEdgeToBool creates an empty map.
func (*EdgeToBool) Delete ¶ added in v0.2.14
func (m *EdgeToBool) Delete(key [2]Coord)
Delete removes the key from the map if it exists, and does nothing otherwise.
func (*EdgeToBool) KeyRange ¶ added in v0.2.14
func (m *EdgeToBool) KeyRange(f func(key [2]Coord) bool)
KeyRange is like Range, but only iterates over keys, not values.
func (*EdgeToBool) Len ¶ added in v0.2.14
func (m *EdgeToBool) Len() int
Len gets the number of elements in the map.
func (*EdgeToBool) Load ¶ added in v0.2.14
func (m *EdgeToBool) Load(key [2]Coord) (bool, bool)
Load gets the value for the given key.
If no value is present, the first return argument is a zero value, and the second is false. Otherwise, the second return value is true.
func (*EdgeToBool) Range ¶ added in v0.2.14
func (m *EdgeToBool) Range(f func(key [2]Coord, value bool) bool)
Range iterates over the map, calling f successively for each value until it returns false, or all entries are enumerated.
It is not safe to modify the map with Store or Delete during enumeration.
func (*EdgeToBool) Store ¶ added in v0.2.14
func (m *EdgeToBool) Store(key [2]Coord, value bool)
Store assigns the value to the given key, overwriting the previous value for the key if necessary.
func (*EdgeToBool) Value ¶ added in v0.2.14
func (m *EdgeToBool) Value(key [2]Coord) bool
Value is like Load(), but without a second return value.
func (*EdgeToBool) ValueRange ¶ added in v0.2.14
func (m *EdgeToBool) ValueRange(f func(value bool) bool)
ValueRange is like Range, but only iterates over values only.
type EdgeToInt ¶ added in v0.2.14
type EdgeToInt struct {
// contains filtered or unexported fields
}
EdgeToInt implements a map-like interface for mapping [2]Coord to int.
This can be more efficient than using a map directly, since it uses a special hash function for coordinates. The speed-up is variable, but was ~2x as of mid-2021.
func NewEdgeToInt ¶ added in v0.2.14
func NewEdgeToInt() *EdgeToInt
NewEdgeToInt creates an empty map.
func (*EdgeToInt) Add ¶ added in v0.2.14
Add adds x to the value stored for the given key and returns the new value.
func (*EdgeToInt) Delete ¶ added in v0.2.14
Delete removes the key from the map if it exists, and does nothing otherwise.
func (*EdgeToInt) KeyRange ¶ added in v0.2.14
KeyRange is like Range, but only iterates over keys, not values.
func (*EdgeToInt) Load ¶ added in v0.2.14
Load gets the value for the given key.
If no value is present, the first return argument is a zero value, and the second is false. Otherwise, the second return value is true.
func (*EdgeToInt) Range ¶ added in v0.2.14
Range iterates over the map, calling f successively for each value until it returns false, or all entries are enumerated.
It is not safe to modify the map with Store or Delete during enumeration.
func (*EdgeToInt) Store ¶ added in v0.2.14
Store assigns the value to the given key, overwriting the previous value for the key if necessary.
func (*EdgeToInt) ValueRange ¶ added in v0.2.14
ValueRange is like Range, but only iterates over values only.
type FaceSDF ¶ added in v0.2.14
type FaceSDF interface { PointSDF // FaceSDF gets the SDF at c and also returns the // nearest point and face to c on the surface. FaceSDF(c Coord) (*Segment, Coord, float64) }
A FaceSDF is a PointSDF that can additionally get the segment containing the closest point.
func GroupedSegmentsToSDF ¶ added in v0.2.3
GroupedSegmentsToSDF creates a FaceSDF from a slice of segments. If the segments are not grouped by GroupSegments(), the resulting PointSDF is inefficient.
type GeneralBVH ¶ added in v0.2.11
type GeneralBVH struct { // Leaf, if non-nil, is the final bounder. Leaf Bounder // Branch, if Leaf is nil, points to two children. Branch []*GeneralBVH }
GeneralBVH represents a (possibly unbalanced) axis-aligned bounding box hierarchy.
A GeneralBVH can store arbitrary Bounders. For a mesh-specific version, see BVH.
func NewGeneralBVHAreaDensity ¶ added in v0.2.11
func NewGeneralBVHAreaDensity(objects []Bounder) *GeneralBVH
NewGeneralBVHAreaDensity creates a GeneralBVH by minimizing the product of each bounding box's perimeter with the number of objects contained in the bounding box at each branch.
This is good for efficient ray collision detection.
type InterpBitmap ¶
type InterpBitmap struct { Data []color.RGBA Width int Height int Model color.Model F ColorBitFunc // Interp is the interpolation function. // A zero value is Bicubic. Interp Interpolator }
An InterpBitmap is a dynamic Bitmap backed by an image with a color interpolation scheme.
func MustReadInterpBitmap ¶
func MustReadInterpBitmap(path string, c ColorBitFunc) *InterpBitmap
MustReadInterpBitmap is like ReadInterpBitmap, except that it panics if the InterpBitmap cannot be read.
func NewInterpBitmap ¶
func NewInterpBitmap(img image.Image, c ColorBitFunc) *InterpBitmap
NewInterpBitmap creates a InterpBitmap from an image.
If c is nil, then the mean RGBA is computed, and pixels are considered true if they are closer to the mean in L2 distance than they are to the top-left pixel. For images with two dominant colors, this is equivalent to making the background false, and the foreground true, assuming that the first pixel is background.
func ReadInterpBitmap ¶
func ReadInterpBitmap(path string, c ColorBitFunc) (*InterpBitmap, error)
ReadInterpBitmap is like NewInterpBitmap, except that it reads the image from a file.
func (*InterpBitmap) Bitmap ¶
func (b *InterpBitmap) Bitmap() *Bitmap
Bitmap gets an uninterpolated bitmap from b.
func (*InterpBitmap) Contains ¶
func (b *InterpBitmap) Contains(c Coord) bool
Contains gets the bit at the interpolated coordinate.
If the coordinate is out of bounds, false is returned.
func (*InterpBitmap) FlipX ¶
func (b *InterpBitmap) FlipX() *InterpBitmap
FlipX reverses the x-axis.
func (*InterpBitmap) FlipY ¶
func (b *InterpBitmap) FlipY() *InterpBitmap
FlipY reverses the y-axis.
func (*InterpBitmap) Get ¶
func (b *InterpBitmap) Get(x, y int) color.RGBA
Get gets the color at the coordinate.
If the coordinate is out of bounds, a the edge of the image is extended.
func (*InterpBitmap) Invert ¶
func (b *InterpBitmap) Invert() *InterpBitmap
Invert creates a new InterpBitmap with the opposite color bitmap values.
func (*InterpBitmap) Max ¶
func (b *InterpBitmap) Max() Coord
Max gets the maximum of the pixel bounding box.
func (*InterpBitmap) Min ¶
func (b *InterpBitmap) Min() Coord
Min gets the minimum of the pixel bounding box.
type Interpolator ¶
type Interpolator int
Interpolator is a 1-dimensional interpolation kernel.
const ( Bicubic Interpolator = iota Bilinear )
func (Interpolator) Kernel ¶
func (i Interpolator) Kernel(t float64) []float64
type IntersectedSolid ¶ added in v0.2.3
type IntersectedSolid []Solid
IntersectedSolid is a Solid containing the intersection of one or more Solids.
func (IntersectedSolid) Contains ¶ added in v0.2.3
func (i IntersectedSolid) Contains(c Coord) bool
func (IntersectedSolid) Max ¶ added in v0.2.3
func (i IntersectedSolid) Max() Coord
func (IntersectedSolid) Min ¶ added in v0.2.3
func (i IntersectedSolid) Min() Coord
type JoinedCollider ¶
type JoinedCollider struct {
// contains filtered or unexported fields
}
A JoinedCollider wraps multiple other Colliders and only passes along rays and circles that enter their combined bounding box.
func NewJoinedCollider ¶
func NewJoinedCollider(other []Collider) *JoinedCollider
NewJoinedCollider creates a JoinedCollider which combines zero or more other colliders.
func (*JoinedCollider) CircleCollision ¶
func (j *JoinedCollider) CircleCollision(center Coord, r float64) bool
func (*JoinedCollider) FirstRayCollision ¶
func (j *JoinedCollider) FirstRayCollision(r *Ray) (RayCollision, bool)
func (*JoinedCollider) Max ¶
func (j *JoinedCollider) Max() Coord
func (*JoinedCollider) Min ¶
func (j *JoinedCollider) Min() Coord
func (*JoinedCollider) RayCollisions ¶
func (j *JoinedCollider) RayCollisions(r *Ray, f func(RayCollision)) int
type JoinedCurve ¶ added in v0.2.6
type JoinedCurve []Curve
A JoinedCurve combines Curves into a single curve. Each curve should end where the next curve begins.
func SmoothBezier ¶ added in v0.2.6
func SmoothBezier(start1, c1, c2, end1 Coord, ctrlEnds ...Coord) JoinedCurve
SmoothBezier creates a joined cubic bezier curve where control points are reflected around end-points. The first four points define the first bezier curve. After that, each group of two points defines a control point and an endpoint.
func (JoinedCurve) Eval ¶ added in v0.2.6
func (j JoinedCurve) Eval(t float64) Coord
Eval evaluates the joint curve.
Each sub-curve consumes an equal fraction of t. For t outside of [0, 1], the first or last curve is used.
type JoinedSolid ¶
type JoinedSolid []Solid
A JoinedSolid is a Solid composed of other solids.
func (JoinedSolid) Contains ¶
func (j JoinedSolid) Contains(c Coord) bool
func (JoinedSolid) Max ¶
func (j JoinedSolid) Max() Coord
func (JoinedSolid) Min ¶
func (j JoinedSolid) Min() Coord
func (JoinedSolid) Optimize ¶ added in v0.2.11
func (j JoinedSolid) Optimize() Solid
Optimize creates a version of the solid that is faster when joining a large number of smaller solids.
type JoinedTransform ¶ added in v0.2.8
type JoinedTransform []Transform
A JoinedTransform composes transformations from left to right.
func (JoinedTransform) Apply ¶ added in v0.2.8
func (j JoinedTransform) Apply(c Coord) Coord
func (JoinedTransform) ApplyBounds ¶ added in v0.2.8
func (j JoinedTransform) ApplyBounds(min Coord, max Coord) (Coord, Coord)
func (JoinedTransform) ApplyDistance ¶ added in v0.2.11
func (j JoinedTransform) ApplyDistance(d float64) float64
ApplyDistance transforms a distance.
It panic()s if any transforms don't implement DistTransform.
func (JoinedTransform) Inverse ¶ added in v0.2.8
func (j JoinedTransform) Inverse() Transform
type LinearConstraint ¶ added in v0.2.11
A LinearConstraint defines a half-space of all points c such that c.Dot(Normal) <= Max.
func (*LinearConstraint) Contains ¶ added in v0.2.11
func (l *LinearConstraint) Contains(c Coord) bool
Contains checks if the half-space contains c.
type Matrix2 ¶
type Matrix2 [4]float64
Matrix2 is a 2x2 matrix, stored in row-major order.
func NewMatrix2Columns ¶
NewMatrix2Columns creates a Matrix2 with the given coordinates as column entries.
func NewMatrix2Rotation ¶
NewMatrix2Rotation creates a rotation matrix that rotates column vectors by theta.
func (*Matrix2) Eigenvalues ¶ added in v0.2.2
func (m *Matrix2) Eigenvalues() [2]complex128
Eigenvalues computes the eigenvalues of the matrix.
There may be a repeated eigenvalue, but for numerical reasons two are always returned.
func (*Matrix2) InvertInPlace ¶
func (m *Matrix2) InvertInPlace()
InvertInPlace moves the inverse of m into m without causing any new allocations.
func (*Matrix2) InvertInPlaceDet ¶ added in v0.2.14
InvertInPlaceDet is an optimization for InvertInPlace when the determinant has been pre-computed.
func (*Matrix2) MulColumnInv ¶ added in v0.2.14
MulColumnInv multiplies the inverse of m by the column c, given the determinant of m.
type Matrix2Transform ¶ added in v0.2.8
type Matrix2Transform struct {
Matrix *Matrix2
}
Matrix2Transform is a Transform that applies a matrix to coordinates.
func (*Matrix2Transform) Apply ¶ added in v0.2.8
func (m *Matrix2Transform) Apply(c Coord) Coord
func (*Matrix2Transform) ApplyBounds ¶ added in v0.2.8
func (m *Matrix2Transform) ApplyBounds(min, max Coord) (Coord, Coord)
func (*Matrix2Transform) Inverse ¶ added in v0.2.8
func (m *Matrix2Transform) Inverse() Transform
type Mesh ¶
type Mesh struct {
// contains filtered or unexported fields
}
A Mesh is a collection of segments.
The segments are uniquely identified as pointers, not as values. This is important for methods which reference existing segments, such as Remove and Neighbors.
Segments in a mesh are "connected" when they contain exactly identical points. Thus, small rounding errors can cause segments to incorrectly be disassociated with each other.
A Mesh can be read safely from concurrent Goroutines, but modifications must not be performed concurrently with any mesh operations.
func MarchingSquares ¶
MarchingSquares turns a Solid into a mesh using a 2D version of the marching cubes algorithm.
func MarchingSquaresConj ¶ added in v0.2.9
MarchingSquaresConj is like MarchingSquaresSearch, but in a transformed space. In particular, it applies a series of transformations to the Solid, and then applies the inverse to the resulting mesh.
func MarchingSquaresSearch ¶
MarchingSquaresSearch is like MarchingSquares, but applies an additional search step to move the vertices along the edges of each square.
The tightness of the triangulation will double for every iteration.
func NewMeshPolar ¶ added in v0.2.9
NewMeshPolar creates a closed polar mesh.
The mesh will have correct normals if the radius function returns positive values when theta is in the range [0, 2*pi].
Even if the polar function does not reach its original value at 2*pi radians, the mesh will be closed by connecting the first point to the last.
func NewMeshRect ¶ added in v0.2.13
NewMeshRect creates a rectangle mesh.
func NewMeshSegments ¶
NewMeshSegments creates a mesh with the given collection of segments.
func (*Mesh) Blur ¶
Blur moves each vertex closer to the average of its neighbors.
The rate argument controls how much the vertices move. If it is 1, then the vertices become the average of their neighbors. If it is 0, then the vertices remain where they are.
func (*Mesh) Decimate ¶ added in v0.2.6
Decimate repeatedly removes vertices from a mesh until it contains maxVertices or fewer vertices with two neighbors.
For manifold meshes, maxVertices is a hard-limit on the number of resulting vertices. For non-manifold meshes, more than maxVertices vertices will be retained if all of the remaining vertices are not part of exactly two segments.
func (*Mesh) EliminateColinear ¶ added in v0.2.13
EliminateColinear eliminates vertices that connect nearly co-linear edges.
The epsilon argument should be a small positive value that is used to approximate co-linearity. A good value for very precise results is 1e-8.
func (*Mesh) Find ¶
Find gets all the segments that contain all of the passed points.
For example, to find all segments containing a line from from p1 to p2, you could do m.Find(p1, p2).
func (*Mesh) Invert ¶ added in v0.2.11
Invert flips every segment in the mesh, effectively inverting all the normals.
func (*Mesh) Iterate ¶
Iterate calls f for every segment in m in an arbitrary order.
If f adds or removes segments, they will not be visited.
func (*Mesh) IterateSorted ¶
IterateSorted is like Iterate, but it first sorts all the segments according to a less than function, cmp.
func (*Mesh) IterateVertices ¶ added in v0.1.1
IterateVertices calls f for every vertex in m in an arbitrary order.
If f adds or removes vertices, they will not be visited.
func (*Mesh) Manifold ¶
Manifold checks if the mesh is manifold, i.e. if every vertex has two segments.
func (*Mesh) MapCoords ¶
MapCoords creates a new mesh by transforming all of the coordinates according to the function f.
func (*Mesh) Neighbors ¶
Neighbors gets all the segments with a side touching a given segment f.
The segment f itself is not included in the results.
The segment f needn't be in the mesh. However, if it is not in the mesh, but an equivalent segment is, then said equivalent segment will be in the results.
func (*Mesh) Remove ¶
Remove removes the segment f from the mesh.
It looks at f as a pointer, so the pointer must be exactly the same as one passed to Add.
func (*Mesh) Repair ¶ added in v0.2.6
Repair finds vertices that are close together and combines them into one.
The epsilon argument controls how close points have to be. In particular, it sets the approximate maximum distance across all dimensions.
func (*Mesh) RepairNormals ¶ added in v0.2.4
RepairNormals flips normals when they point within the shape defined by the mesh, as determined by the even-odd rule.
The repaired mesh is returned, along with the number of modified segments.
The check is performed by adding the normal, scaled by epsilon, to the center of the segment, and then counting the number of ray collisions from this point in the direction of the normal.
func (*Mesh) Rotate ¶ added in v0.2.15
Rotate returns a mesh with all coordinates rotated around the origin by a given angle (in radians).
func (*Mesh) Scale ¶ added in v0.2.2
Scale creates a new mesh by scaling the coordinates by a factor s.
func (*Mesh) SegmentSlice ¶ added in v0.2.11
SegmentSlice gets a snapshot of all the segments currently in the mesh. The resulting slice is a copy, and will not change as the mesh is updated.
func (*Mesh) SegmentsSlice ¶
SegmentsSlice is exactly like SegmentSlice(), and is only implemented for backwards-compatibility.
func (*Mesh) Smooth ¶
Smooth is similar to Blur, but it is less sensitive to differences in segment length.
func (*Mesh) SmoothSq ¶
SmoothSq is like Smooth, but it minimizes the sum of squared segment lengths rather than the sum of lengths directly. Thus, SmoothSq produces more even segments than Smooth.
func (*Mesh) Subdivide ¶
Subdivide uses Chaikin subdivision to add segments between every vertex.
This can only be applied to manifold meshes. This can be checked with m.Manifold().
func (*Mesh) Translate ¶ added in v0.2.13
Translate returns a mesh with all coordinates added to a given vector.
func (*Mesh) VertexSlice ¶ added in v0.1.1
VertexSlice gets a snapshot of all the vertices currently in the mesh.
The result is a copy and is in no way connected to the mesh in memory.
type MeshHierarchy ¶ added in v0.2.10
type MeshHierarchy struct { // Mesh is the root shape of this (sub-)hierarchy. Mesh *Mesh // MeshSolid is a solid indicating which points are // contained in the mesh. MeshSolid Solid Children []*MeshHierarchy }
A MeshHierarchy is a tree structure where each node is a closed, simple polygon, and children are contained inside their parents.
Only manifold meshes with no self-intersections can be converted into a MeshHierarchy.
func MeshToHierarchy ¶ added in v0.2.10
func MeshToHierarchy(m *Mesh) []*MeshHierarchy
MeshToHierarchy creates a MeshHierarchy for each exterior mesh contained in m.
The mesh m must be manifold and have no self-intersections.
func (*MeshHierarchy) Contains ¶ added in v0.2.10
func (m *MeshHierarchy) Contains(c Coord) bool
Contains checks if c is inside the hierarchy using the even-odd rule.
func (*MeshHierarchy) FullMesh ¶ added in v0.2.10
func (m *MeshHierarchy) FullMesh() *Mesh
FullMesh re-combines the root mesh with all of its children.
func (*MeshHierarchy) MapCoords ¶ added in v0.2.10
func (m *MeshHierarchy) MapCoords(f func(Coord) Coord) *MeshHierarchy
MapCoords creates a new MeshHierarchy by applying f to every coordinate in every mesh.
func (*MeshHierarchy) Max ¶ added in v0.2.10
func (m *MeshHierarchy) Max() Coord
Max gets the maximum point of the outer mesh's bounding box.
func (*MeshHierarchy) Min ¶ added in v0.2.10
func (m *MeshHierarchy) Min() Coord
Min gets the minimum point of the outer mesh's bounding box.
type MultiCollider ¶ added in v0.2.6
type MultiCollider interface { Collider SegmentCollider RectCollider }
func GroupedSegmentsToCollider ¶
func GroupedSegmentsToCollider(segs []*Segment) MultiCollider
GroupedSegmentsToCollider converts pre-grouped segments into an efficient MultiCollider. If the segments were not grouped with GroupSegments, then the resulting collider may be highly inefficient.
func MeshToCollider ¶
func MeshToCollider(m *Mesh) MultiCollider
MeshToCollider converts a mesh to an efficient MultiCollider.
type PointSDF ¶ added in v0.2.3
type PointSDF interface { SDF // PointSDF gets the SDF at c and also returns the // nearest point to c on the surface. PointSDF(c Coord) (Coord, float64) }
A PointSDF is an SDF that can additionally get the nearest point on a surface.
func FuncPointSDF ¶ added in v0.2.13
FuncPointSDF creates a PointSDF from a function.
If the bounds are invalid, FuncPointSDF() will panic(). In particular, max must be no less than min, and all floating-point values must be finite numbers.
type Rasterizer ¶ added in v0.2.6
type Rasterizer struct { // Scale determines how many pixels comprise a unit // distance in the model being rasterized. // // This determines how large output images are, given // the bounds of the model being rasterized. // // A value of 0 defaults to a value of 1. Scale float64 // Subsamples indicates how many sub-samples to test // for each axis in each pixel. // A value of 1 means one sample is taken per pixel, // and values higher than one cause anti-aliasing. // If 0, RasterizerDefaultSubsamples is used. Subsamples int // LineWidth is the thickness of lines (in pixels) // when rendering a mesh or collider. // // If 0, RasterizerDefaultLineWidth is used. LineWidth float64 // Bounds, if non-nil, is used to override the bounds // of any rasterized object. // This can be used to add padding, or have a // consistent canvas when drawing a moving scene. Bounds Bounder }
A Rasterizer converts 2D models into raster images.
func (*Rasterizer) Rasterize ¶ added in v0.2.6
func (r *Rasterizer) Rasterize(obj interface{}) *image.Gray
Rasterize rasterizes a Solid, Mesh, or Collider.
func (*Rasterizer) RasterizeCollider ¶ added in v0.2.6
func (r *Rasterizer) RasterizeCollider(c Collider) *image.Gray
RasterizeCollider rasterizes the collider as a line drawing.
func (*Rasterizer) RasterizeColliderSolid ¶ added in v0.2.7
func (r *Rasterizer) RasterizeColliderSolid(c Collider) *image.Gray
RasterizeColliderSolid rasterizes the collider as a filled in Solid using the even-odd test.
func (*Rasterizer) RasterizeSolid ¶ added in v0.2.6
func (r *Rasterizer) RasterizeSolid(s Solid) *image.Gray
RasterizeSolid rasterizes a Solid into an image.
func (*Rasterizer) RasterizeSolidFilter ¶ added in v0.2.6
RasterizeSolidFilter rasterizes a Solid using a heuristic filter than can eliminate the need to render blank regions of the image.
If f returns false for a given rectangular region, it means that the solid is definitely uniform within the region (i.e. there is no boundary in the region). The exact pattern with which f is called will depend on the image and rasterization parameters.
type Ray ¶
A Ray is a line originating at a point and extending infinitely in some (positive) direction.
type RayCollision ¶
type RayCollision struct { // The amount of the ray direction to add to the ray // origin to hit the point in question. // // The scale should be non-negative. Scale float64 // The normal pointing outward from the outline at the // point of collision. Normal Coord // Extra contains additional, implementation-specific // information about the collision. Extra interface{} }
RayCollision is a point where a ray intersects a 2-dimensional outline.
type Rect ¶ added in v0.2.4
A Rect is a 2D axis-aligned rectangle.
func BoundsRect ¶ added in v0.2.13
BoundsRect creates a Rect from a Bounder's bounds.
type RectCollider ¶ added in v0.2.6
type RectCollider interface { // RectCollision returns true if any part of the // outline is inside the rect. RectCollision(r *Rect) bool }
A RectCollider is a 2-dimensional outline which can detect if a 2D axis-aligned rectangular area collides with the outline.
type SDF ¶ added in v0.2.3
An SDF is a signed distance function.
An SDF returns 0 on the boundary of some surface, positive values inside the surface, and negative values outside the surface. The magnitude is the distance to the surface.
All methods of an SDF are safe for concurrency.
func ColliderToSDF ¶ added in v0.2.3
ColliderToSDF generates an SDF that uses bisection search to approximate the SDF for any Collider.
The iterations argument controls the precision. If set to 0, a default of 32 is used.
func FuncSDF ¶ added in v0.2.13
FuncSDF creates an SDF from a function.
If the bounds are invalid, FuncSDF() will panic(). In particular, max must be no less than min, and all floating-point values must be finite numbers.
func TransformSDF ¶ added in v0.2.11
func TransformSDF(t DistTransform, s SDF) SDF
TransformSDF applies t to the SDF s to produce a new, transformed SDF.
type Scale ¶ added in v0.2.11
type Scale struct {
Scale float64
}
Scale is a transform that scales an object.
func (*Scale) ApplyBounds ¶ added in v0.2.11
func (*Scale) ApplyDistance ¶ added in v0.2.11
type Segment ¶
type Segment [2]Coord
A Segment is a 2-dimensional line segment.
The order determines the normal direction.
In particular, if the segments in a polygon go in the clockwise direction, assuming the y-axis faces up, then the normals face outwards from the polygon.
func (*Segment) CircleCollision ¶
CircleCollision checks if the circle intersects the segment s.
func (Segment) Dist ¶ added in v0.2.3
Dist gets the minimum distance from c to a point on the line segment.
func (*Segment) FirstRayCollision ¶
func (s *Segment) FirstRayCollision(r *Ray) (RayCollision, bool)
FirstRayCollision gets the ray collision if there is one.
func (*Segment) Normal ¶
Normal computes the normal vector to the segment, facing outwards from the surface.
func (*Segment) RayCollisions ¶
func (s *Segment) RayCollisions(r *Ray, f func(RayCollision)) int
RayCollisions calls f (if non-nil) with a collision (if applicable) and returns the collisions count (0 or 1).
func (*Segment) RectCollision ¶ added in v0.2.6
RectCollision returns true if any part of the segment is inside of the rectangle.
func (*Segment) SegmentCollision ¶ added in v0.2.6
SegmentCollision returns true if s intersects s1.
type SegmentCollider ¶ added in v0.2.6
type SegmentCollider interface { // SegmentCollision returns true if the segment // collides with the outline. SegmentCollision(s *Segment) bool }
A SegmentCollider is a 2-dimensional outline which can detect if a line segment collides with the outline.
type Solid ¶
type Solid interface { // Contains must always return false outside of the // boundaries of the solid. Bounder Contains(p Coord) bool }
A Solid is a boolean function where a value of true indicates that a point is part of the solid, and false indicates that it is not.
All methods of a Solid are safe for concurrency.
func BitmapToSolid ¶
func CacheSolidBounds ¶ added in v0.2.11
CacheSolidBounds creates a Solid that has a cached version of the solid's boundary coordinates.
The solid also explicitly checks that points are inside the boundary before passing them off to s.
func CheckedFuncSolid ¶ added in v0.2.11
CheckedFuncSolid is like FuncSolid, but it does an automatic bounds check before calling f.
func ForceSolidBounds ¶ added in v0.2.7
ForceSolidBounds creates a new solid that reports the exact bounds given by min and max.
Points outside of these bounds will be removed from s, but otherwise s is preserved.
func FuncSolid ¶ added in v0.2.11
FuncSolid creates a Solid from a function.
If the bounds are invalid, FuncSolid() will panic(). In particular, max must be no less than min, and all floating-point values must be finite numbers.
func RotateSolid ¶ added in v0.2.15
RotateSolid creates a new Solid by rotating a Solid by a given angle (in radians).
func ScaleSolid ¶
ScaleSolid creates a new Solid that scales incoming coordinates c by 1/s. Thus, the new solid is s times larger.
func SmoothJoin ¶ added in v0.2.11
SmoothJoin joins the SDFs into a union Solid and smooths the intersections using a given smoothing radius.
If the radius is 0, it is equivalent to turning the SDFs directly into solids and then joining them.
func TransformSolid ¶ added in v0.2.8
TransformSolid applies t to the solid s to produce a new, transformed solid.
func TranslateSolid ¶ added in v0.2.13
TranslateSolid creates a new Solid by translating a Solid by a given offset.
type SubtractedSolid ¶ added in v0.2.3
SubtractedSolid is a Solid consisting of all the points in Positive which are not in Negative.
func (*SubtractedSolid) Contains ¶ added in v0.2.3
func (s *SubtractedSolid) Contains(c Coord) bool
func (*SubtractedSolid) Max ¶ added in v0.2.3
func (s *SubtractedSolid) Max() Coord
func (*SubtractedSolid) Min ¶ added in v0.2.3
func (s *SubtractedSolid) Min() Coord
type Transform ¶ added in v0.2.8
type Transform interface { // Apply applies the transformation to c. Apply(c Coord) Coord // ApplyBounds gets a new bounding rectangle that is // guaranteed to bound the old bounding rectangle when // it is transformed. ApplyBounds(min, max Coord) (Coord, Coord) // Inverse gets an inverse transformation. // // The inverse may not perfectly invert bounds // transformations, since some information may be lost // during such a transformation. Inverse() Transform }
Transform is an invertible coordinate transformation.
type Translate ¶ added in v0.2.8
type Translate struct {
Offset Coord
}
Translate is a Transform that adds an offset to coordinates.
func (*Translate) ApplyBounds ¶ added in v0.2.8
func (*Translate) ApplyDistance ¶ added in v0.2.11
Source Files ¶
- bezier_fit.go
- bitmap.go
- bounder.go
- bvh.go
- collisions.go
- coord_tree.go
- coords.go
- curves.go
- doc.go
- export.go
- fast_maps.go
- import.go
- interp.go
- marching.go
- matrix.go
- medial_axis.go
- mesh.go
- mesh_hierarchy.go
- mesh_ops.go
- polytope.go
- ptr_mesh.go
- rasterize.go
- sdf.go
- shapes.go
- smooth.go
- solid.go
- transform.go
- triangulate.go