Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
94 lines (80 sloc) 2.67 KB
package geometry
import (
// A Line2D represents a 2D line, line segment, or ray by a point P and vector
// V. Methods by default assume a line unless the method states otherwise.
type Line2D struct {
P Vector2D // a point on the line
// a vector pointing in the line or ray direction (not necessarily
// normalized), or a vector pointing to the second end point on a line
// segment relative to P
V Vector2D
// NewLine2D returns a new Line2D.
func NewLine2D(px, py, vx, vy float64) *Line2D {
return &Line2D{Vector2D{px, py}, Vector2D{vx, vy}}
// Copy sets z to x and returns z.
func (z *Line2D) Copy(x *Line2D) *Line2D {
z.P.X = x.P.X
z.P.Y = x.P.Y
z.V.X = x.V.X
z.V.Y = x.V.Y
return z
// Equal compares a and b and returns true if they are exactly equal or false
// otherwise.
func (a *Line2D) Equal(b *Line2D) bool {
am, bm := a.V.Y/a.V.X, b.V.Y/b.V.Y
return am == bm && a.P.Y-am*a.P.X == b.P.Y-bm*b.P.X
// FuzzyEqual compares a and b and returns true of they are very close or false
// otherwise.
func (a *Line2D) FuzzyEqual(b *Line2D) bool {
if FuzzyEqual(a.V.X, 0) {
if FuzzyEqual(b.V.X, 0) {
return FuzzyEqual(a.P.X, b.P.X)
return false
am, bm := a.V.Y/a.V.X, b.V.Y/b.V.X
return FuzzyEqual(am, bm) && FuzzyEqual(a.P.Y-am*a.P.X, b.P.Y-bm*b.P.X)
// Length returns the length of line segment x.
func (x *Line2D) Length() float64 {
return math.Sqrt(x.V.X*x.V.X + x.V.Y*x.V.Y)
// LengthSquared returns the squared length of line segment x.
func (x *Line2D) LengthSquared() float64 {
return x.V.X*x.V.X + x.V.Y*x.V.Y
// Midpoint sets point z to the midpoint of line segment x, then returns z.
func (x *Line2D) Midpoint(z *Vector2D) *Vector2D {
z.X = x.P.X + 0.5*x.V.X
z.Y = x.P.Y + 0.5*x.V.Y
return z
// Normal sets vector z to the normal of line x with a length equal to x's as
// if it were a line segment, then returns z.
func (x *Line2D) Normal(z *Vector2D) *Vector2D {
z.X = x.V.Y
z.Y = -x.V.X
return z
// SegmentEqual compares a and b and returns true if the line segments are
// exactly equal and false otherwise.
func (a *Line2D) SegmentEqual(b *Line2D) bool {
return (a.P == b.P && a.V == b.V) || (a.P.X == b.P.X+b.V.X && a.P.Y == b.P.Y+b.V.Y && -a.V.X == b.V.X &&
-a.V.Y == b.V.Y)
// SegmentFuzzyEqual compares a and b as line segments and returns true if they
// are very close and false otherwise.
func (a *Line2D) SegmentFuzzyEqual(b *Line2D) bool {
return (a.P.FuzzyEqual(&b.P) && a.V.FuzzyEqual(&b.V)) || (FuzzyEqual(a.P.X, b.P.X+b.V.X) &&
FuzzyEqual(a.P.Y, b.P.Y+b.V.Y) && FuzzyEqual(a.P.X+a.V.X, b.P.X) && FuzzyEqual(a.P.Y+a.V.Y, b.P.Y))
// Slope returns the slope of x.
func (x *Line2D) Slope() float64 {
return x.V.Y / x.V.X