geo

package
v0.0.0-...-4710020 Latest Latest
Warning

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

Go to latest
Published: Dec 12, 2024 License: BSD-3-Clause Imports: 4 Imported by: 0

README

geo

A collection of geometry primitives.

Why would you use this? You wouldn't. There are so many good math libraries. This is not one of them.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	HorizontalSlope = Slope{Angle: Horizontal, M: 0.}
	VerticalSlope   = Slope{Angle: Vertical, M: math.MaxFloat64}
)
View Source
var RngFUnit = RngF{Min: 0., Max: 1.}

Functions

func DegreesToRadians

func DegreesToRadians(degrees float64) float64

func Float64NearZero

func Float64NearZero(v float64, tolerance float64) bool

func FloatsEqual

func FloatsEqual(a, b float64) bool

func FloatsEqualTol

func FloatsEqualTol(a, b, tolerance float64) bool

func Fmt

func Fmt(a any, params any) fmt.Stringer

func IsCollinear

func IsCollinear[T Number](p1, p2, p3 Point[T]) bool

IsCollinear checks if three points are collinear

func Max

func Max[T Number](a, b T) T

func Min

func Min[T Number](a, b T) T

Surely these are SOMEWHERE? TODO: Yes, builtin min() and max(), and they are highly optimized, perform the same as this. So remove these.

func NullHitTest

func NullHitTest(PtF) bool

func OnSegment

func OnSegment[T Number](p, start, end Point[T]) bool

OnSegment checks if a point lies on a line segment

func Orient

func Orient[T Number](a, b, c Point[T]) T

Orient answers whether C is left / clockwise to direct segment AB. Response: 0: C is collinear < 0: C is left / clockwise > 0: C is right / counterclockwise

func Pt3dNearZero

func Pt3dNearZero(v Pt3dF, tolerance float64) bool

func RadiansToDegrees

func RadiansToDegrees(radians float64) float64

func Ratio

func Ratio(a, b float64) float64

Ratio answers a 0-1 value based on a's contributing factor to the final value.

func RectsEqual

func RectsEqual[T Number](a, b Rectangle[T]) bool

func Sqr

func Sqr[T Number](x T) T

func XAtY

func XAtY(s SegF, y float64) (float64, bool)

XAtY answers the X value for this segment at the given Y value, or false if the line does not intersect y.

func XYToIndex

func XYToIndex[T constraints.Integer](width, height T, pt Point[T]) (T, error)

XYToIndex converts an X, Y to a flat index.

func XYToIndexFast

func XYToIndexFast[T constraints.Integer](x, y, width T) T

XYToIndexFast converts an X, Y to a flat index without any bounds checking.

Types

type Angle

type Angle uint8
const (
	Oblique Angle = iota
	Horizontal
	Vertical
)

type BezF

type BezF = QuadraticBezier

type CircleHitTest

type CircleHitTest struct {
	// contains filtered or unexported fields
}

func (*CircleHitTest) Hit

func (t *CircleHitTest) Hit(pt PtF) bool

func (*CircleHitTest) Set

func (t *CircleHitTest) Set(center PtF, radius float64)

func (*CircleHitTest) String

func (t *CircleHitTest) String() string

type CubicBezier

type CubicBezier struct {
	P0, P1, P2, P3 PtF
}

CubicBezier represents a cubic Bezier curve.

func CubicBez

func CubicBez(x0, y0, x1, y1, x2, y2, x3, y3 float64) CubicBezier

CubicBez is shorthand for creating a cubic bezier curve.

func (*CubicBezier) At

func (bc *CubicBezier) At(t float64) PtF

At evaluates the Bezier curve at a given parameter t.

func (*CubicBezier) PointBounds

func (bc *CubicBezier) PointBounds() RectF

PointBounds is the bounding box for my control points. It does not include any point that lies outside the controls.

type Float

type Float interface {
	constraints.Float
}

type HitTest

type HitTest func(PtF) bool

HitTest answers true if the point is a hit.

type Line

type Line[T Float] struct {
	V Point[T]
	C T
}

https://github.com/vlecomte/cp-geo/blob/master/basics/line.tex

func LineFromDir

func LineFromDir[T Float](v Point[T], c T) Line[T]

From direction vector v and offset c

func LineFromPts

func LineFromPts[T Float](p, q Point[T]) Line[T]

From points P and Q

func LineFromXys

func LineFromXys[T Float](px, py, qx, qy T) Line[T]

From points P and Q as XYs.

type LnF

type LnF = Line[float64]

type Mode

type Mode = uint8
const (
	Lines Mode = iota
	Rays
	RayLine
	RaySegment
	Segments
)

type Number

type Number interface {
	constraints.Integer | constraints.Float
}

type Orientation

type Orientation uint8
const (
	Collinear Orientation = iota
	Clockwise
	CounterClockwise
)

func RadialDist

func RadialDist(a, b float64) (float64, Orientation)

RadialDist answers the distance between two unit values, accounting for wrapping. Andswer 0 - 1, with 1 being the two values are closest. Examples: a=.1, b=.9, distance is .2, i.e. it wraps around 1.

type Point

type Point[T Number] struct {
	X T
	Y T
}

func Centroid

func Centroid[T Number](pts []Point[T]) Point[T]

func ConvertPoint

func ConvertPoint[A Number, B Number](a Point[A]) Point[B]

func FindIntersection

func FindIntersection[T Number](s1, s2 Segment[T]) (Point[T], bool)

FindIntersection finds the intersection between two line segments. Note: I am finding cases where this doesn't work, where an intersection is found on some segments but if you scale one of the points further out, no intersection. From https://github.com/vlecomte/cp-geo/blob/master/basics/segment.tex Further note: This doesn't seem to find intersections exactly on end points. Further review of that page shows yes this is correct, there's a different algorithm to account for endpoints.

func IndexToXY

func IndexToXY[T constraints.Integer](width, height, index T) (Point[T], error)

IndexToXY converts a flat index into an array into an XY position.

func PerpendicularIntersection

func PerpendicularIntersection[T Float](seg Segment[T], pt Point[T]) (Point[T], bool)

PerpendicularIntersection finds the intersection of point to the line segment by drawing a perpendicular line from point to segment. Note: this is from Gemini. Seems to work but not heavily tested.

func Pt

func Pt[T Number](x, y T) Point[T]

Pt is shorthand for creating a point from two values.

func Pts

func Pts[T Number](xys ...T) []Point[T]

Pts creates a slice of Points from x y values.

func (Point[T]) Add

func (a Point[T]) Add(b Point[T]) Point[T]

func (Point[T]) Area

func (p Point[T]) Area() T

func (Point[T]) Cross

func (a Point[T]) Cross(b Point[T]) T

func (Point[T]) Degrees

func (a Point[T]) Degrees(b Point[T]) float64

Degrees finds the angle of the segment with this point as the origin. Degrees will be 0-360, with 0/360 on the right, proceeding clockwise.

func (Point[T]) Dist

func (a Point[T]) Dist(b Point[T]) float64

func (Point[T]) DistSquared

func (a Point[T]) DistSquared(b Point[T]) T

Dist2 is the distance without the square root.

func (Point[T]) Dot

func (a Point[T]) Dot(b Point[T]) float64

func (Point[T]) Inside

func (a Point[T]) Inside(r Rectangle[T]) bool

func (Point[T]) Magnitude

func (a Point[T]) Magnitude() float64

func (Point[T]) Mult

func (a Point[T]) Mult(b Point[T]) Point[T]

func (Point[T]) Normalize

func (a Point[T]) Normalize() Point[T]

Normalize normalizs the point to a unit. Can be negative if they are generated from a negative point, i.e. a negative direction vector.

func (Point[T]) Project

func (a Point[T]) Project(m, dist float64) (Point[T], Point[T])

Given slope m and distance, project the positive and negative points on the line. Uses upper-left coordinate system.

func (Point[T]) ProjectDegree

func (a Point[T]) ProjectDegree(deg, dist float64) Point[T]

ProjectDegree takes a degree and distance and projects a new point.

func (Point[T]) Radians

func (a Point[T]) Radians() float64

func (Point[T]) Rotate

func (a Point[T]) Rotate(origin Point[T], angleInRads float64) Point[T]

Rotate the point. Rotation will be: In Quandrant 4 this rotates CW for positive angles and CCW for negative. TODO: API might be confusing, after not using it I've started thinking of the a point as the center and the point being passed in as the point to rotate. so might switch those.

func (Point[T]) Sub

func (a Point[T]) Sub(b Point[T]) Point[T]

func (Point[T]) ToIndex

func (p Point[T]) ToIndex(xy Point[T]) T

ToIndex converts the xy point into an index into a flat array as represented by this point.

type Point3d

type Point3d[T Number] struct {
	X T
	Y T
	Z T
}

func Pt3d

func Pt3d[T Number](x, y, z T) Point3d[T]

Pt3d is shorthand for creating a point3d from three values.

func (Point3d[T]) Add

func (a Point3d[T]) Add(b Point3d[T]) Point3d[T]

func (Point3d[T]) CLampFast

func (a Point3d[T]) CLampFast(rng Range[T]) Point3d[T]

func (Point3d[T]) Cross

func (a Point3d[T]) Cross(b Point3d[T]) Point3d[T]

Cross calculates the cross product of two vectors and returns a new vector

func (Point3d[T]) Div

func (a Point3d[T]) Div(b Point3d[T]) Point3d[T]

func (Point3d[T]) DivT

func (a Point3d[T]) DivT(t T) Point3d[T]

func (Point3d[T]) Dot

func (a Point3d[T]) Dot(b Point3d[T]) T

func (Point3d[T]) DotProduct

func (a Point3d[T]) DotProduct(b Point3d[T]) T

func (Point3d[T]) Magnitude

func (a Point3d[T]) Magnitude() float64

func (Point3d[T]) Mult

func (a Point3d[T]) Mult(b Point3d[T]) Point3d[T]

func (Point3d[T]) MultT

func (a Point3d[T]) MultT(t T) Point3d[T]

func (Point3d[T]) Normalize

func (a Point3d[T]) Normalize() Point3d[T]

func (Point3d[T]) Sub

func (a Point3d[T]) Sub(b Point3d[T]) Point3d[T]

func (Point3d[T]) SubT

func (a Point3d[T]) SubT(t T) Point3d[T]

type Poly

type Poly[T Number] struct {
	Pts []Point[T]
}

type PolyF

type PolyF = Poly[float64]

type PolyF64

type PolyF64 = Poly[float64]

type PolyI

type PolyI = Poly[int]

type PolyI64

type PolyI64 = Poly[int64]

type PolyUI64

type PolyUI64 = Poly[uint64]

type PolygonBB

type PolygonBB[T Number] struct {
	Pts []Point[T]
	BB  Rectangle[T]
}

PolygonBB is a closed polygon that includes the computed bounding box.

func PolyBB

func PolyBB[T Float](pts []Point[T]) PolygonBB[T]

type PolygonBBF64

type PolygonBBF64 = PolygonBB[float64]

type ProcessPtF64Func

type ProcessPtF64Func func(pt PtF) PtF

type Pt3dF

type Pt3dF = Point3d[float64]

func LinePlaneIntersection

func LinePlaneIntersection(lineA, lineB Pt3dF, planeNormal, planeOrigin Pt3dF) (Pt3dF, bool)

func TrianglePlaneIntersection

func TrianglePlaneIntersection(tri Tri3dF, triPt Pt3dF, planeTri Tri3dF, planePt Pt3dF) (Pt3dF, bool)

func TrianglePlaneIntersection2

func TrianglePlaneIntersection2(tri Tri3dF, triPt Pt3dF, planeTri Tri3dF, planePt Pt3dF) (Pt3dF, bool)

func TrianglePlaneIntersection5

func TrianglePlaneIntersection5(tri Tri3dF, triPt Pt3dF, planeTri Tri3dF, planePt Pt3dF) (Pt3dF, bool)

Proiject a ray perpendicular to triPt on tri to find its intersection with the plane (as defined by planeTri and planePt)

type Pt3dF32

type Pt3dF32 = Point3d[float32]

type Pt3dF64

type Pt3dF64 = Point3d[float64]

type Pt3dI

type Pt3dI = Point3d[int]

type Pt3dI64

type Pt3dI64 = Point3d[int64]

type PtF

type PtF = Point[float64]

func CubicBezierDistance

func CubicBezierDistance(cb CubicBezier, pt PtF) (float64, PtF)

CubicBezierDistance approximates the distance from a point to a Bezier curve

func CubicBezierDistanceSquared

func CubicBezierDistanceSquared(cb CubicBezier, pt PtF) (float64, PtF)

CubicBezierDistanceSquared approximates the distance from a point to a Bezier curve

func DegreesToDirectionCw

func DegreesToDirectionCw(degrees float64) PtF

DegreesToDirectionCcw converts degrees to a direction vector, where 0 = right and it continues clockwise, so 90 is down.

func DistPointToSegment

func DistPointToSegment(seg SegF, p PtF) (float64, PtF)

DistPointToSegment answers the distance from the point to the segment, as well as the point found on the segment. From https://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment

func DistSquared

func DistSquared(seg SegF, p PtF) (float64, PtF)

DistSquared answers the squared distance from the point to the segment, as well as the point found on the segment. From https://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment

func DistToPolyF

func DistToPolyF(poly []PtF, pt PtF) (float64, PtF)

func LineLineIntersectionF

func LineLineIntersectionF(l1, l2 LnF) (PtF, bool)

LineLineIntersectionF provides the intersection of two lines. https://github.com/vlecomte/cp-geo/blob/master/basics/line.tex

func LineToSegIntersection

func LineToSegIntersection(A, B PtF, pq SegF) (PtF, bool)

https://stackoverflow.com/questions/34415671/intersection-of-a-line-with-a-line-segment-in-c line segment p-q intersect with line A-B. This looks a lot more efficient than the current seg-seg test I'm doing, but also I actually want a seg-seg test because this gives false positives. So... maybe I'll switch to it if I think of a way for it to make sense, but probably not because this is just a different operation.

func PtToSegIntersection

func PtToSegIntersection(pt, direction PtF, seg SegF) (PtF, bool)

func PtToSegIntersection_Off

func PtToSegIntersection_Off(pt, direction PtF, seg SegF) (PtF, bool)

func PtToSegIntersection_Off2

func PtToSegIntersection_Off2(pt, direction PtF, seg SegF) (PtF, bool)

func QuadraticBezierDistanceBrute

func QuadraticBezierDistanceBrute(cb QuadraticBezier, pt PtF) (float64, PtF)

QuadraticBezierDistanceBrute approximates the distance from a point to a Bezier curve

func QuadraticBezierDistanceSquared

func QuadraticBezierDistanceSquared(cb QuadraticBezier, pt PtF) (float64, PtF)

QuadraticBezierDistanceSquared approximates the distance from a point to a Bezier curve

func QuadraticBezierDistanceSquaredBrute

func QuadraticBezierDistanceSquaredBrute(cb QuadraticBezier, pt PtF) (float64, PtF)

QuadraticBezierDistanceSquaredBrute approximates the distance from a point to a Bezier curve

type PtF32

type PtF32 = Point[float32]

type PtF64

type PtF64 = Point[float64]

type PtI

type PtI = Point[int]

type PtI64

type PtI64 = Point[int64]

type QuadraticBezier

type QuadraticBezier struct {
	P0, P1, P2 PtF
}

QuadraticBezier represents a quadratic Bezier curve.

func Bez

func Bez(x0, y0, x1, y1, x2, y2 float64) QuadraticBezier

Bez is shorthand for creating a quadratic bezier curve.

func QuadraticBez

func QuadraticBez(x0, y0, x1, y1, x2, y2 float64) QuadraticBezier

QuadraticBez is shorthand for creating a quadratic bezier curve.

func (*QuadraticBezier) At

func (b *QuadraticBezier) At(t float64) PtF

At evaluates the Bezier curve at a given parameter t.

func (*QuadraticBezier) PointBounds

func (b *QuadraticBezier) PointBounds() RectF

PointBounds is the bounding box for my control points. It does not include any point that lies outside the controls.

type Range

type Range[T Number] struct {
	Min T
	Max T
}

func Rng

func Rng[T Number](min, max T) Range[T]

func (Range[T]) Clamp

func (p Range[T]) Clamp(value T) T

Clamp returns the value clipped to my range.

func (Range[T]) ClampFast

func (r Range[T]) ClampFast(value T) T

ClampFast returns the value clipped to my range. It assumes Min is less than Max.

func (Range[T]) Clip

func (p Range[T]) Clip(value T) T

Clip returns the value clipped to my range. TODO: Clamp() seems more common so switch to that.

func (Range[T]) Contains

func (p Range[T]) Contains(value T) bool

Contains returns true if the value is contained in the range.

func (Range[T]) Intersection

func (a Range[T]) Intersection(b Range[T]) Range[T]

Intersection returns the intersection of A and B ranges.

func (Range[T]) MapNormal

func (p Range[T]) MapNormal(normal float64) T

MapNormal takes a normalized (0-1) value and maps it to my range.

func (Range[T]) Midpoint

func (p Range[T]) Midpoint() T

Midpoint returns the center of the range.

func (Range[T]) Normalize

func (p Range[T]) Normalize(value T) float64

Normalize returns the value clipped to my range and normalized to 0-1.

func (Range[T]) Overlaps

func (a Range[T]) Overlaps(b Range[T]) bool

Overlaps returns true if the ranges overlap.

type RectF

type RectF = Rectangle[float64]

type RectF32

type RectF32 = Rectangle[float32]

type RectF64

type RectF64 = Rectangle[float64]

type RectI

type RectI = Rectangle[int]

type RectI64

type RectI64 = Rectangle[int64]

type Rectangle

type Rectangle[T Number] struct {
	L, T, R, B T
}

func ConvertRect

func ConvertRect[A Number, B Number](a Rectangle[A]) Rectangle[B]

func PolygonBounds

func PolygonBounds[T Float](ptss ...[]Point[T]) Rectangle[T]

func PtBounds

func PtBounds[T Number](pts []Point[T]) Rectangle[T]

func Rect

func Rect[T Number](left, top, right, bottom T) Rectangle[T]

func (Rectangle[T]) Add

func (r1 Rectangle[T]) Add(l, t, r, b T) Rectangle[T]

func (Rectangle[T]) Area

func (r Rectangle[T]) Area() T

func (Rectangle[T]) Center

func (r Rectangle[T]) Center() Point[T]

func (Rectangle[T]) Clip

func (r1 Rectangle[T]) Clip(r2 Rectangle[T]) Rectangle[T]

Clip returns r1 clipped by r2.

func (Rectangle[T]) Contains

func (r1 Rectangle[T]) Contains(r2 Rectangle[T]) bool

func (Rectangle[T]) ContainsPoint

func (r Rectangle[T]) ContainsPoint(pt Point[T]) bool

ContainsPoint returns true if the point is inside the half-closed rectangle.

func (Rectangle[T]) Height

func (r Rectangle[T]) Height() T

func (Rectangle[T]) IsZero

func (r Rectangle[T]) IsZero() bool

func (Rectangle[T]) LT

func (r Rectangle[T]) LT() Point[T]

func (Rectangle[T]) MergePoint

func (r1 Rectangle[T]) MergePoint(x, y T) Rectangle[T]

MergePoint will expand the bounds to include the point.

func (Rectangle[T]) Overlaps

func (r1 Rectangle[T]) Overlaps(r2 Rectangle[T]) bool

func (Rectangle[T]) RB

func (r Rectangle[T]) RB() Point[T]

func (Rectangle[T]) Size

func (r Rectangle[T]) Size() Point[T]

func (Rectangle[T]) String

func (r Rectangle[T]) String() string

func (Rectangle[T]) Translate

func (r Rectangle[T]) Translate(pt Point[T]) Rectangle[T]

func (Rectangle[T]) Union

func (r1 Rectangle[T]) Union(r2 Rectangle[T]) Rectangle[T]

func (Rectangle[T]) Width

func (r Rectangle[T]) Width() T

func (Rectangle[T]) WithExpand

func (r Rectangle[T]) WithExpand(v T) Rectangle[T]

Expand adds the value to all edges.

func (Rectangle[T]) WithSize

func (r Rectangle[T]) WithSize(pt Point[T]) Rectangle[T]

type RngF

type RngF = Range[float64]

type RngF32

type RngF32 = Range[float32]

type RngF64

type RngF64 = Range[float64]

type RngI

type RngI = Range[int]

type RngI64

type RngI64 = Range[int64]

type SegF

type SegF = Segment[float64]

type SegF32

type SegF32 = Segment[float32]

type SegF64

type SegF64 = Segment[float64]

type SegFmtF

type SegFmtF struct {
	Seg SegF
}

func (SegFmtF) String

func (f SegFmtF) String() string

type SegI

type SegI = Segment[int]

type SegI64

type SegI64 = Segment[int64]

type Segment

type Segment[T Number] struct {
	A Point[T]
	B Point[T]
}

Segment represents a line segment with start and end points

func ConvertSegment

func ConvertSegment[A Number, B Number](seg Segment[A]) Segment[B]

func Seg

func Seg[T Number](ax, ay, bx, by T) Segment[T]

Seg is shorthand for creating a segment from two points.

func (Segment[T]) AddPt

func (s Segment[T]) AddPt(pt Point[T]) Segment[T]

AddPt adds the point and returns the new segment.

func (Segment[T]) AsArray

func (s Segment[T]) AsArray() []Point[T]

AsArray returns my points in a slice.

func (Segment[T]) Degrees

func (s Segment[T]) Degrees() float64

Degrees finds the angle of the segment with A as the origin. Degrees will be 0-360, with 0/360 on the right, proceeding clockwise.

func (Segment[T]) Dir

func (s Segment[T]) Dir() Point[T]

Dir answers the direction vector of this segment.

func (Segment[T]) Interp

func (s Segment[T]) Interp(unit T) Point[T]

Interp answers a new point at the unit position on this segment, where 0. = A and 1. = B. Note this really only works on floats, need a way to narrow that constraint.

func (Segment[T]) Len

func (s Segment[T]) Len() T

Len answers the length of this segment.

func (Segment[T]) LenSquared

func (s Segment[T]) LenSquared() T

LenSquared answers the squared length of this segment.

func (Segment[T]) Midpoint

func (s Segment[T]) Midpoint() Point[T]

func (Segment[T]) PerpendicularSlope

func (s Segment[T]) PerpendicularSlope() Slope

PerpendicularSlope answers the perpendicular of Slope.

func (Segment[T]) Slope

func (s Segment[T]) Slope() Slope

Slope answers the slope of this line segment. Uses upper left coordinates.

type SliceSegFmtF

type SliceSegFmtF struct {
	Segs []SegF
}

func (SliceSegFmtF) String

func (f SliceSegFmtF) String() string

type Slope

type Slope struct {
	Angle Angle
	M     float64
}

type Tri3dF

type Tri3dF = Triangle3d[float64]

type Triangle3d

type Triangle3d[T Number] struct {
	A Point3d[T]
	B Point3d[T]
	C Point3d[T]
}

func Tri3d

func Tri3d[T Number](a, b, c Point3d[T]) Triangle3d[T]

Tri3d is shorthand for creating a triangle.

func Tri3dFlat

func Tri3dFlat[T Number](ax, ay, az, bx, by, bz, cx, cy, cz T) Triangle3d[T]

func (Triangle3d[T]) Center

func (t Triangle3d[T]) Center() Point3d[T]

Jump to

Keyboard shortcuts

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