gg/src/gx/line.go

110 lines
2 KiB
Go
Raw Normal View History

2023-05-28 19:14:02 +03:00
package gx
import (
"math"
)
2023-05-28 19:45:58 +03:00
// The type represents mathematical equation of line and line itself.
type Line struct {
2023-05-28 19:14:02 +03:00
K, C Float
}
type Liner interface {
Line() Line
}
2023-05-28 19:14:02 +03:00
// The type represents a line segment.
type LineSegment [2]Point
// Check whether the liner is parallel to the line.
func (l Line) Parallel(liner Liner) bool {
buf := liner.Line()
if buf.K == l.K {
return true
}
return false
}
2023-05-28 21:07:05 +03:00
func (l Line) Line() Line {
return l
}
func (l Line) Crosses(with Liner) (Point, bool) {
// Parallel liners cannot cross by definition.
if l.Parallel(with) {
return Point{}, false
}
switch with.(type) {
case Line :
return l.crossesLine(with.(Line))
case LineSegment :
return with.(LineSegment).crossesLine(l)
default:
panic("unhandled type")
}
}
func (l1 Line) crossesLine(l2 Line) (Point, bool) {
x := (l1.C - l2.C) / (l2.K - l1.K)
y := l1.K*x + l1.C
return Point{x, y}, true
}
2023-05-28 19:14:02 +03:00
// Get square of length of line segment.
func (ls LineSegment) LenSqr() Float {
return Sqr(ls[0].X - ls[1].X) +
Sqr(ls[0].Y - ls[1].Y)
}
// Get length of the line segment.
func (ls LineSegment) Len() Float {
return math.Sqrt(ls.LenSqr())
}
2023-05-28 19:45:58 +03:00
// Returns corresponding to the segment line line.
func (l LineSegment) Line() Line {
2023-05-28 19:14:02 +03:00
p0 := l[0]
p1 := l[1]
k := (p0.Y - p1.Y) / (p0.X - p1.X)
c := p0.Y - p0.X*k
2023-05-28 19:45:58 +03:00
return Line{k, c}
2023-05-28 19:14:02 +03:00
}
2023-05-28 21:07:05 +03:00
func (l LineSegment) Crosses(with Liner) (Point, bool) {
switch with.(type) {
case Line :
return l.crossesLine(with.(Line))
case LineSegment :
return l.crossesLineSegment(with.(LineSegment))
default:
panic("The type that is not defined to be crossed")
}
}
2023-05-28 21:07:05 +03:00
func (l LineSegment) Contains(what any) bool {
switch what.(type) {
case Point :
return l.containsPoint(what.(Point))
default :
panic("Unexpected type")
}
}
func (l LineSegment) containsPoint(p Point) bool {
return false
}
func (l LineSegment) crossesLineSegment(with LineSegment) (Point, bool) {
return Point{}, false
}
2023-05-28 21:07:05 +03:00
func (l LineSegment) crossesLine(with Line) (Point, bool) {
return Point{}, false
}