Skip to content

Commit

Permalink
Changed line has point algorithm to vector, x2 performance
Browse files Browse the repository at this point in the history
  • Loading branch information
mrsombre committed Jan 10, 2024
1 parent 988bbcb commit 0e06d8d
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 17 deletions.
19 changes: 2 additions & 17 deletions geometry_line.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,27 +75,12 @@ func (ln Line) Segment(length float64) Line {

// IsPointOnLine tests if the Point is on the Line.
func (ln Line) IsPointOnLine(p Point) bool {
if ln.IsHorizontal() {
return ln.From.Y == p.Y
}
if ln.IsVertical() {
return ln.From.X == p.X
}

// diagonal
slope := ln.Slope()
yIntercept := ln.From.Y - slope*ln.From.X
expectedY := slope*p.X + yIntercept

return math.Round(p.Y) == math.Round(expectedY)
return isPointOnLine(ln, p, false)
}

// IsPointOnSegment tests if the Point is on the Line segment.
func (ln Line) IsPointOnSegment(p Point) bool {
if !ln.Rect().IsContainsPoint(p) {
return false
}
return ln.IsPointOnLine(p)
return isPointOnLine(ln, p, true)
}

// LinesIntersection returns the crossing Point of two Lines.
Expand Down
8 changes: 8 additions & 0 deletions geometry_line_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,14 @@ func TestLine_IsPointOnLine(t *testing.T) {
}
}

func BenchmarkLine_IsPointOnLine(b *testing.B) {
line := Line{Point{0, 0}, Point{300, 300}}
point := Point{150, 150}
for i := 0; i < b.N; i++ {
line.IsPointOnLine(point)
}
}

func TestLine_IsPointOnSegment(t *testing.T) {
tests := []struct {
name string
Expand Down
19 changes: 19 additions & 0 deletions geometry_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,22 @@ func linesIntersection(a, b Line, s1, s2 bool) (Point, bool) {
Y: a.From.Y + t*av.Y,
}, true
}

func isPointOnLine(ln Line, point Point, s bool) bool {
lv := ln.Vector()
pv := point.Sub(ln.From)

pcp := lv.X*pv.Y - lv.Y*pv.X
if pcp != 0 {
return false
}

if s {
dp := pv.X*lv.X + pv.Y*lv.Y
l := lv.X*lv.X + lv.Y*lv.Y

return dp >= 0 && dp <= l
}

return true
}

0 comments on commit 0e06d8d

Please sign in to comment.