util

package
v0.0.0-...-0f831d7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 16, 2024 License: Apache-2.0 Imports: 5 Imported by: 2

Documentation

Overview

Package util contains functions for linear and non-linear interpolations and their inversions.

Index

Constants

View Source
const (
	OddEven wrule = iota
	NonZero
)
View Source
const (
	Epsilon float64 = 0.000001 // 1:1,000,000
)

%f formats to 6dp by default

View Source
const (
	TwoPi = math.Pi * 2
)

Variables

View Source
var (
	SideOfLine = TriArea
)
View Source
var WindingRule = OddEven

WindingRule defines how edges in an edge crossing polygon are treated.

Functions

func AngleBetweenLines

func AngleBetweenLines(p1, p2, p3, p4 []float64) float64

AngleBetweenLines using Atan2 vs calculating the dot product (2xSqrt+Acos). Retains the directionality of the rotation from l1 to l2, unlike dot product. The result is in the range [-Pi,Pi].

func AngleInRange

func AngleInRange(a, r, b float64) bool

AngleInRange returns true if angle b is within [a,a+r].

func BBContains

func BBContains(p []float64, bb [][]float64) bool

BBContains returns true if p is in bb at the smallest dimensionality.

func BBFilter

func BBFilter(pts [][]float64, bb [][]float64) [][]float64

BBFilter returns only points from pts that are in bb at the smallest dimensionality.

func BBIntersection

func BBIntersection(bb1, bb2 [][]float64) [][]float64

BBIntersection returns the bb formed by the overlap or nil.

func BBOutline

func BBOutline(bb [][]float64) [][]float64

BBOutline returns a rectangle describing bb.

func BBOverlap

func BBOverlap(bb1, bb2 [][]float64) bool

BBOverlap returns true if bb1 and bb2 overlap at the smallest dimensionality.

func Barycentric

func Barycentric(p, tp1, tp2, tp3 []float64) (float64, float64, float64)

Barycentric converts a point on the plane into Barycentric weights given three non-coincident points, tp1, tp2 and tp3.

func Bezier1

func Bezier1(pts [][]float64, t float64) []float64

Bezier1 (flat curve) {p1, p2}

func Bezier2

func Bezier2(pts [][]float64, t float64) []float64

Bezier2 (quad curve) {p1, c1, p2}

func Bezier3

func Bezier3(pts [][]float64, t float64) []float64

Bezier3 (cubic curve) {p1, c1, c2, p2}

func Bezier3ToCatmull

func Bezier3ToCatmull(p1, p2, p3, p4 []float64) []float64

Bezier3ToCatmull converts a cubic bezier to a catmul curve. p1, c1, c2, p2 => t1, p1, p2, t2

func BoundingBox

func BoundingBox(pts ...[]float64) [][]float64

BoundingBox returns the minimum and maximum dimensional values in a set of points. Bounds are inclusive. The dimensionality of the smallest dimension point is used for all points.

func CalcDerivativeWeights

func CalcDerivativeWeights(w [][]float64) [][]float64

CalcDerivativeWeights calculates the derivative of the supplied curve. Bezier gradient (differentiation): Order of curve drops by one and new weights are the difference of the original weights scaled by the original order

func CalcExtremities

func CalcExtremities(points [][]float64) []float64

CalcExtremities finds the extremes of a curve in terms of t.

func CalcNextOrderWeights

func CalcNextOrderWeights(w [][]float64) [][]float64

CalcNextOrderWeights calculates the weights necessary to represent the supplied curve at next highest order, i.e. curve promotion b2 to b3. Note, there's no inverse.

func CalcPointsForArc

func CalcPointsForArc(theta float64) [][]float64

CalcPointsForArc takes an arc angle (less than or equal to Pi), and calculates the points for a Bezier cubic to describe it on a circle centered on (0,0) with radius 1. Mid-point of the curve is (1,0) Error increases for values > Pi/2 Returns nil if the angle is zero Ref: https://www.tinaja.com/glib/bezcirc2.pdf

func CatmullToBezier3

func CatmullToBezier3(tau float64, p1, p2, p3, p4 []float64) []float64

CatmullToBezier3 converts a catmul curve to a cubic bezier. t1, p1, p2, t2 => p1, c1, c2, p2

func Centroid

func Centroid(pts ...[]float64) []float64

Centroid returns the vertex centroid of a set of points.

func Circumcircle

func Circumcircle(p1, p2, p3 []float64) []float64

Circumcircle returns the circle (center and radius) that passes through the three points.

func Coincident

func Coincident(lp1, lp2, lp3, lp4 []float64) bool

True if lines are on the same infinite line

func Collinear

func Collinear(lp1, lp2, p []float64) bool

Collinear returns true if three points are on a line (i.e. if the area of the resultant triangle is 0)

func CrossProduct

func CrossProduct(p1, p2, p3 []float64) float64

CrossProduct returns the cross product of the three points. Since the inputs are all in the x-y plane (i.e. z = 0), only the magnitude of the resultant z vector is returned (the x and y vectors are both 0).

func Cubic

func Cubic(t float64, p []float64) float64

Cubic calculates the value of f(t) for t in range [0,1] given the values of t at -1, 0, 1, 2 in p[] fitted to a cubic polynomial: f(t) = at^3 + bt^2 + ct + d. Clamped because it over/undershoots.

func DeCasteljau

func DeCasteljau(pts [][]float64, t float64) []float64

DeCasteljau uses de Casteljau's algorithm for degree n curves and returns the point and the tangent of the line it's traversing. {p1, c1, c2, c3, ..., p2}

func Dejitter

func Dejitter(closed bool, pts ...[]float64) [][]float64

Dejitter takes a list of points, greater than three long, and removes the one that forms the smallest area triangle with its adjacent points. If closed is true then the end points are candidates for elimination too.

func DistanceE

func DistanceE(p1, p2 []float64) float64

DistanceE returns the Euclidean distance between two points.

func DistanceESquared

func DistanceESquared(p1, p2 []float64) float64

DistanceESquared returns the squared Euclidean distance between two points.

func DistanceESquaredN

func DistanceESquaredN(p1, p2 []float64) float64

DistanceESquaredN returns the squared Euclidean distance between two points.

func DistanceToLineSquared

func DistanceToLineSquared(lp1, lp2, p []float64) (float64, []float64, float64)

DistanceToLineSquared calculates the squared Euclidean length of the normal from a point to the line. Returns the distance squared, the line intercept and the t value.

func DotProduct

func DotProduct(p1, p2, p3, p4 []float64) float64

DotProduct returns the dot product of the two lines, p1-p2 and p3-p4.

func DotProductAngle

func DotProductAngle(p1, p2, p3, p4 []float64) float64

DotProductAngle returns the angle between two lines using the dot product method. The result is in the range [0,Pi].

func Equals

func Equals(d1, d2 float64) bool

Equals returns true if two values are within Epsilon of each other.

func Equals32

func Equals32(d1, d2 float32) bool

Equals32 is the float32 version of Equals.

func EqualsP

func EqualsP(v1, v2 []float64) bool

EqualsP returns true if two points are equal (upto the extent of shared dimensions).

func IntersectionTVals

func IntersectionTVals(x1, y1, x2, y2, x3, y3, x4, y4 float64) ([]float64, error)

IntersectionTVals obtains values of t for each line for where they intersect. Actual intersection => both are in [0,1]

func IntersectionTValsP

func IntersectionTValsP(p1, p2, p3, p4 []float64) ([]float64, error)

IntersectionTValsP obtains values of t for each line for where they intersect. Actual intersection => both are in [0,1]

func InvLerp

func InvLerp(v, start, end float64) float64

InvLerp performs the inverse of Lerp and returns the value of t for a value v.

func InvLerp32

func InvLerp32(v, start, end float32) float32

InvLerp32 is a float32 version of InvLerp.

func InvLerpClamp

func InvLerpClamp(v, start, end float64) float64

InvLerpClamp is a clamped [start, end] version of InvLerp.

func InvLerpClamp32

func InvLerpClamp32(v, start, end float32) float32

InvLerpClamp32 is a float32 version of InvLerpClamp.

func InvNLerp

func InvNLerp(v, start, end float64, f NonLinear) float64

InvNLerp performs the inverse of NLerp and returns the value of t for a value v (clamped to [start, end]).

func InvNLerp32

func InvNLerp32(v, start, end float32, f NonLinear) float32

InvNLerp32 is a float32 version of InvNLerp for Path and x/image/vector

func InverseBarycentric

func InverseBarycentric(w1, w2, w3 float64, tp1, tp2, tp3 []float64) []float64

InverseBarycentric converts Barycentric weights plus the three non-coincident points back into a point on the plane.

func Kappa

func Kappa(dpt, d2pt []float64) float64

Kappa from first and second derivatives at a point.

func Kappa1

func Kappa1(dw, d2w [][]float64, t float64) float64

Kappa1 calculates curvature - note curve must have 2nd order derivative. Radius of curvature at t is 1/kappa(t)

func KappaC

func KappaC(p1, p2, p3 []float64) float64

KappaC estimates kappa from three points by calculating the center of the circumcircle.

func KappaM

func KappaM(p1, p2, p3 []float64) float64

KappaM calculates Menger curvature: 4*area / (d(p1, p2).d(p2s, p3).d(p3, p1)) Same result as KappaC but with more square roots...

func Left

func Left(lp1, lp2, p []float64) bool

Left returns true if p is to the left of the line

func LeftOn

func LeftOn(lp1, lp2, p []float64) bool

Left returns true if p is to the left of or on the line

func Lerp

func Lerp(t, start, end float64) float64

Lerp returns the value (1-t)*start + t*end.

func Lerp32

func Lerp32(t, start, end float32) float32

Lerp32 is a float32 version of Lerp.

func LerpClamp

func LerpClamp(t, start, end float64) float64

LerpClamp is a clamped [0,1] version of Lerp.

func LerpClamp32

func LerpClamp32(t, start, end float32) float32

LerpClamp32 is a float32 version of LerpClamp.

func LineAngle

func LineAngle(p1, p2 []float64) float64

LineAngle returns the angle of a line. Result is in range [-Pi, Pi]

func LineNormalToPoint

func LineNormalToPoint(lp1, lp2, p []float64) ([]float64, float64, float64)

LineNormalToPoint returns the point on the line that's normal to the specified point, in absolute terms and as a t value. The distance from the point to the line is returned too.

func MinD

func MinD(pts ...[]float64) int

MinD calculates the minimum dimensionality of point set

func NLerp

func NLerp(t, start, end float64, f NonLinear) float64

NLerp returns the value of the supplied non-linear function at t. Note t is clamped to [0,1]

func NLerp32

func NLerp32(t, start, end float32, f NonLinear) float32

NLerp32 is a float32 version of NLerp for Path and x/image/vector

func NRM

func NRM(start float64, f, df func(float64) float64) (float64, error)

NRM is a modified Newton-Raphson root search that bails if t falls outside of the range [0,1] since the curve isn't defined there.

func Parallel

func Parallel(lp1, lp2, lp3, lp4 []float64) bool

True if lines are parallel

func PointInPoly

func PointInPoly(pt []float64, poly ...[]float64) bool

PointInPoly returns true is a point is within the polygon defined by the list of vertices according to the setting of WindingRule (OddEven or NonZero).

func PointInTriangle

func PointInTriangle(p, tp1, tp2, tp3 []float64) bool

PointInTriangle returns true if p is in the triangle formed by tp1, tp2 and tp3.

func PointOnLine

func PointOnLine(lp1, lp2, p []float64) (bool, float64)

PointOnLine returns if p is on the line and t for p if it is.

func RectToBB

func RectToBB(rect image.Rectangle) [][]float64

RectToBB converts an image.Rectangle to a bounding box

func Remap

func Remap(v, istart, iend, ostart, oend float64) float64

Remap converts v from one space to another by applying InvLerp to find t in the initial range, and then using t to find v' in the new range.

func Remap32

func Remap32(v, istart, iend, ostart, oend float32) float32

Remap32 is a float32 version of Remap.

func RemapClamp

func RemapClamp(v, istart, iend, ostart, oend float64) float64

RemapClamp is a clamped version of Remap.

func RemapClamp32

func RemapClamp32(v, istart, iend, ostart, oend float32) float32

RemapClamp32 is a float32 version of RemapClamp.

func RemapNL

func RemapNL(v, istart, iend, ostart, oend float64, fi, fo NonLinear) float64

RemapNL converts v from one space to another by applying InvNLerp to find t in the initial range, and then using t to find v' in the new range.

func RemapNL32

func RemapNL32(v, istart, iend, ostart, oend float32, fi, fo NonLinear) float32

RemapNL32 is a float32 version of RemapNL for Path and x/image/vector

func Right(lp1, lp2, p []float64) bool

Right returns true if p is to the right of the line

func RightOn

func RightOn(lp1, lp2, p []float64) bool

RightOn returns true if p is to the right of or on the line

func SplitCurve

func SplitCurve(pts [][]float64, t float64) [][][]float64

SplitCurve splits curve at t into two new curves such that the end of the lhs is the start of the rhs {p1, c1, c2, c3, ..., p2}

func ToF32

func ToF32(pts ...float64) []float32

ToF32 casts a slice of float64 to float32. Possible loss of resolution.

func ToF64

func ToF64(pts ...float32) []float64

ToF64 casts a slice of float32 to float64.

func TriArea

func TriArea(p1, p2, p3 []float64) float64

TriArea returns the signed area of a triangle by finding the determinant of M = {{p1[0] p1[1] 1}

{p2[0] p2[1] 1}
{p3[0] p3[1] 1}}

func Vec

func Vec(p1, p2 []float64) []float64

Vec returns the vector joining two points.

func VecMag

func VecMag(v []float64) float64

VecMag returns the magnitude of the vector.

func VecNormalize

func VecNormalize(v []float64) []float64

VecNormalize scales a vector to unit length.

func Within

func Within(d1, d2, e float64) bool

Within returns true if the two values are within e of each other.

Types

type BezierCurve

type BezierCurve struct {
	Weights    [][]float64
	WeightsDt  [][]float64
	WeightsDt2 [][]float64
	WeightsDt3 [][]float64
}

BezierCurve stores the derivative curve weights.

func NewBezierCurve

func NewBezierCurve(weights [][]float64) *BezierCurve

NewBezierCurve creates a new BezierCurve with the weights of the first, second and third order derivatives of the supplied curve.

func (*BezierCurve) CurveDt2X

func (bc *BezierCurve) CurveDt2X(t float64) float64

CurveDt2X returns the X value for the second order derivative of the curve at t.

func (*BezierCurve) CurveDt2Y

func (bc *BezierCurve) CurveDt2Y(t float64) float64

CurveDt2Y returns the Y value for the second order derivative of the curve at t.

func (*BezierCurve) CurveDt3X

func (bc *BezierCurve) CurveDt3X(t float64) float64

CurveDt3X returns the X value for the third order derivative of the curve at t.

func (*BezierCurve) CurveDt3Y

func (bc *BezierCurve) CurveDt3Y(t float64) float64

CurveDt3Y returns the Y value for the third order derivative of the curve at t.

func (*BezierCurve) CurveDtX

func (bc *BezierCurve) CurveDtX(t float64) float64

CurveDtX returns the X value for the derivative of the curve at t.

func (*BezierCurve) CurveDtY

func (bc *BezierCurve) CurveDtY(t float64) float64

CurveDtY returns the Y value for the derivative of the curve at t.

func (*BezierCurve) CurveX

func (bc *BezierCurve) CurveX(t float64) float64

CurveX returns the X value for the curve at t.

func (*BezierCurve) CurveY

func (bc *BezierCurve) CurveY(t float64) float64

CurveY returns the Y value for the curve at t.

func (*BezierCurve) Kappa

func (bc *BezierCurve) Kappa(t float64) float64

Kappa calculates the curvature at t. Radius of curvature at t is 1/kappa(t)

type NLCatenary

type NLCatenary struct{}

NLCatenary v = cosh(t)

func (*NLCatenary) InvTransform

func (nl *NLCatenary) InvTransform(v float64) float64

func (*NLCatenary) Transform

func (nl *NLCatenary) Transform(t float64) float64

type NLCircle1

type NLCircle1 struct{}

NLCircle1 v = 1 - sqrt(1-t^2)

func (*NLCircle1) InvTransform

func (nl *NLCircle1) InvTransform(v float64) float64

func (*NLCircle1) Transform

func (nl *NLCircle1) Transform(t float64) float64

type NLCircle2

type NLCircle2 struct{}

NLCircle2 v = sqrt(2t-t^2)

func (*NLCircle2) InvTransform

func (nl *NLCircle2) InvTransform(v float64) float64

func (*NLCircle2) Transform

func (nl *NLCircle2) Transform(t float64) float64

type NLCompound

type NLCompound struct {
	Fs []NonLinear
}

NLCompound v = nl[0](nl[1](nl[2](...nl[n-1](t))))

func NewNLCompound

func NewNLCompound(fs []NonLinear) *NLCompound

func (*NLCompound) InvTransform

func (nl *NLCompound) InvTransform(v float64) float64

func (*NLCompound) Transform

func (nl *NLCompound) Transform(t float64) float64

type NLCube

type NLCube struct{}

NLCube v = t^3

func (*NLCube) InvTransform

func (nl *NLCube) InvTransform(v float64) float64

func (*NLCube) Transform

func (nl *NLCube) Transform(t float64) float64

type NLExponential

type NLExponential struct {
	K     float64
	Scale float64
}

NLExponential v = (exp(t*k) - 1) * scale

func NewNLExponential

func NewNLExponential(k float64) *NLExponential

func (*NLExponential) InvTransform

func (nl *NLExponential) InvTransform(v float64) float64

func (*NLExponential) Transform

func (nl *NLExponential) Transform(t float64) float64

type NLGauss

type NLGauss struct {
	K, Offs, Scale float64
}

NLGauss v = gauss(t, k)

func NewNLGauss

func NewNLGauss(k float64) *NLGauss

func (*NLGauss) InvTransform

func (nl *NLGauss) InvTransform(v float64) float64

func (*NLGauss) Transform

func (nl *NLGauss) Transform(t float64) float64

type NLLame

type NLLame struct {
	N   float64
	M   float64
	Odn float64
	Odm float64
}

NLLame (aka superellipse) v = 1 - (1-t^n)^1/m

func NewNLLame

func NewNLLame(n, m float64) *NLLame

func (*NLLame) InvTransform

func (nl *NLLame) InvTransform(v float64) float64

func (*NLLame) Transform

func (nl *NLLame) Transform(t float64) float64

type NLLinear

type NLLinear struct{}

NLLinear v = t

func (*NLLinear) InvTransform

func (nl *NLLinear) InvTransform(v float64) float64

func (*NLLinear) Transform

func (nl *NLLinear) Transform(t float64) float64

type NLLogarithmic

type NLLogarithmic struct {
	K     float64
	Scale float64
}

NLLogarithmic v = log(1+t*k) * scale

func NewNLLogarithmic

func NewNLLogarithmic(k float64) *NLLogarithmic

func (*NLLogarithmic) InvTransform

func (nl *NLLogarithmic) InvTransform(v float64) float64

func (*NLLogarithmic) Transform

func (nl *NLLogarithmic) Transform(t float64) float64

type NLLogistic

type NLLogistic struct {
	K, Mp, Offs, Scale float64
}

NLLogistic v = logistic(t, k, mp)

func NewNLLogistic

func NewNLLogistic(k, mp float64) *NLLogistic

k > 0 and mp (0,1) - not checked

func (*NLLogistic) InvTransform

func (nl *NLLogistic) InvTransform(v float64) float64

func (*NLLogistic) Transform

func (nl *NLLogistic) Transform(t float64) float64

type NLOmt

type NLOmt struct {
	F NonLinear
}

NLOmt v = 1-f(1-t)

func NewNLOmt

func NewNLOmt(f NonLinear) *NLOmt

func (*NLOmt) InvTransform

func (nl *NLOmt) InvTransform(v float64) float64

func (*NLOmt) Transform

func (nl *NLOmt) Transform(t float64) float64

type NLP3

type NLP3 struct{} // first derivative 0 at t=0,1

NLP3 v = t^2 * (3-2t)

func (*NLP3) InvTransform

func (nl *NLP3) InvTransform(v float64) float64

func (*NLP3) Transform

func (nl *NLP3) Transform(t float64) float64

type NLP5

type NLP5 struct{} // first and second derivatives 0 at t=0,1

NLP5 v = t^3 * (t*(6t-15) + 10)

func (*NLP5) InvTransform

func (nl *NLP5) InvTransform(v float64) float64

func (*NLP5) Transform

func (nl *NLP5) Transform(t float64) float64

type NLRand

type NLRand struct {
	Steps []float64
	Dt    float64
}

NLRand uses random incremental steps from a normal distribution, smoothed with a cubic.

func NewNLRand

func NewNLRand(mean, std float64, sharp bool) *NLRand

NewRandNL calculates a collection of ascending values [0,1] with an average increment of mean and standard deviation of std.

func (*NLRand) InvTransform

func (nl *NLRand) InvTransform(v float64) float64

func (*NLRand) Transform

func (nl *NLRand) Transform(t float64) float64

type NLSin

type NLSin struct{} // first derivative 0 at t=0,1

NLSin v = sin(t) with t mapped to [-Pi/2,Pi/2]

func (*NLSin) InvTransform

func (nl *NLSin) InvTransform(v float64) float64

func (*NLSin) Transform

func (nl *NLSin) Transform(t float64) float64

type NLSin1

type NLSin1 struct{} // first derivative 0 at t=1

NLSin1 v = sin(t) with t mapped to [0,Pi/2]

func (*NLSin1) InvTransform

func (nl *NLSin1) InvTransform(v float64) float64

func (*NLSin1) Transform

func (nl *NLSin1) Transform(t float64) float64

type NLSin2

type NLSin2 struct{} // first derivative 0 at t=0,1

NLSin2 v = sin(t) with t mapped to [-Pi/2,0]

func (*NLSin2) InvTransform

func (nl *NLSin2) InvTransform(v float64) float64

func (*NLSin2) Transform

func (nl *NLSin2) Transform(t float64) float64

type NLSquare

type NLSquare struct{}

NLSquare v = t^2

func (*NLSquare) InvTransform

func (nl *NLSquare) InvTransform(v float64) float64

func (*NLSquare) Transform

func (nl *NLSquare) Transform(t float64) float64

type NLStopped

type NLStopped struct {
	Stops [][]float64 // Pairs of t, v - both strictly ascending in [0,1]
}

NewStoppedNL uses linear interpolation between the supplied stops

func NewNLStopped

func NewNLStopped(stops [][]float64) *NLStopped

func (*NLStopped) InvTransform

func (nl *NLStopped) InvTransform(v float64) float64

func (*NLStopped) Transform

func (nl *NLStopped) Transform(t float64) float64

type NonLinear

type NonLinear interface {
	Transform(t float64) float64
	InvTransform(v float64) float64
}

NonLinear interface defines the transform and its inverse as used by NLerp etc. For mapping 0 -> 1 non-linearly. No checks! Only valid in range [0,1]

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL