...
This commit is contained in:
parent
506e2772f7
commit
e3ab4596e1
5 changed files with 92 additions and 77 deletions
|
@ -32,7 +32,7 @@ func main() {
|
||||||
gx.Point{0, 1},
|
gx.Point{0, 1},
|
||||||
gx.Point{1, 0},
|
gx.Point{1, 0},
|
||||||
}.Line()
|
}.Line()
|
||||||
fmt.Println(l1.Crosses(l2))
|
fmt.Println(gx.LinersCross(l1, l2))
|
||||||
fmt.Println(l1.ContainsPoint(gx.Point{1, 4}))
|
fmt.Println(l1.ContainsPoint(gx.Point{1, 4}))
|
||||||
|
|
||||||
t := gx.Rectangle{
|
t := gx.Rectangle{
|
||||||
|
|
142
src/gx/line.go
142
src/gx/line.go
|
@ -13,76 +13,48 @@ type Liner interface {
|
||||||
Line() Line
|
Line() Line
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type LinerPointContainer interface {
|
||||||
|
Liner
|
||||||
|
PointContainer
|
||||||
|
}
|
||||||
|
|
||||||
// The type represents a line segment.
|
// The type represents a line segment.
|
||||||
type LineSegment [2]Point
|
type LineSegment [2]Point
|
||||||
|
|
||||||
// The type represents multiple line segments.
|
// The type represents multiple line segments.
|
||||||
type LineSegments []LineSegment
|
type LineSegments []LineSegment
|
||||||
|
|
||||||
// Check whether the liner is parallel to the line.
|
type Edge = LineSegment
|
||||||
func (l Line) Parallel(liner Liner) bool {
|
type Edges []Vertex
|
||||||
buf := liner.Line()
|
|
||||||
|
|
||||||
|
// Check if two LinerPointContainers do cross and return the
|
||||||
|
// crossing point.
|
||||||
|
func LinersCross(lp1, lp2 LinerPointContainer) (Point, bool) {
|
||||||
|
l1 := lp1.Line()
|
||||||
|
l2 := lp2.Line()
|
||||||
|
|
||||||
if buf.K == l.K {
|
p, crosses := l1.crossesLine(l2)
|
||||||
return true
|
if !crosses ||
|
||||||
}
|
!lp1.ContainsPoint(p) ||
|
||||||
|
!lp2.ContainsPoint(p) {
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l Line) Line() Line {
|
|
||||||
return l
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l Line) ContainsPoint(p Point) bool {
|
|
||||||
buf := Line{0, p.Y}
|
|
||||||
pc, ok := l.crossesLine(buf)
|
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return pc == p
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l Line) Crosses(with Liner) (Point, bool) {
|
|
||||||
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) {
|
|
||||||
if l1.Parallel(l2) {
|
|
||||||
return Point{}, false
|
return Point{}, false
|
||||||
}
|
}
|
||||||
|
|
||||||
x := (l1.C - l2.C) / (l2.K - l1.K)
|
return p, true
|
||||||
y := l1.K*x + l1.C
|
|
||||||
return Point{x, y}, true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l LineSegment) ContainsPoint(p Point) bool {
|
// Check whether the liner is parallel to the other liner.
|
||||||
line := l.Line()
|
func LinersParallel(first, second Liner) bool {
|
||||||
if !line.ContainsPoint(p) {
|
l1 := first.Line()
|
||||||
return false
|
l2 := second.Line()
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
return l1.K == l2.K
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get square of length of line segment.
|
// Returns the line itself. Made to implement the Liner interface.
|
||||||
func (ls LineSegment) LenSqr() Float {
|
func (l Line) Line() Line {
|
||||||
return Sqr(ls[0].X - ls[1].X) +
|
return l
|
||||||
Sqr(ls[0].Y - ls[1].Y)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get length of the line segment.
|
|
||||||
func (ls LineSegment) Len() Float {
|
|
||||||
return math.Sqrt(ls.LenSqr())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns corresponding to the segment line line.
|
// Returns corresponding to the segment line line.
|
||||||
|
@ -96,35 +68,55 @@ func (l LineSegment) Line() Line {
|
||||||
return Line{k, c}
|
return Line{k, c}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l LineSegment) Crosses(with Liner) (Point, bool) {
|
func (l Line) ContainsPoint(p Point) bool {
|
||||||
switch with.(type) {
|
buf := Line{0, p.Y}
|
||||||
case Line :
|
pc, ok := l.crossesLine(buf)
|
||||||
return l.crossesLine(with.(Line))
|
if !ok {
|
||||||
case LineSegment :
|
return false
|
||||||
return l.crossesLineSegment(with.(LineSegment))
|
|
||||||
default:
|
|
||||||
panic("The type that is not defined to be crossed")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return pc == p
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l LineSegment) Contains(what any) bool {
|
func (l LineSegment) ContainsPoint(p Point) bool {
|
||||||
switch what.(type) {
|
line := l.Line()
|
||||||
case Point :
|
if !line.ContainsPoint(p) {
|
||||||
return l.containsPoint(what.(Point))
|
return false
|
||||||
default :
|
|
||||||
panic("Unexpected type")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xMax := Max(l[0].X, l[1].X)
|
||||||
|
xMin := Min(l[0].X, l[1].X)
|
||||||
|
|
||||||
|
yMax := Max(l[0].Y, l[1].Y)
|
||||||
|
yMin := Min(l[0].Y, l[1].Y)
|
||||||
|
|
||||||
|
if !(xMin < p.X && p.X < xMax) ||
|
||||||
|
!(yMin < p.Y && p.Y < yMax) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l LineSegment) containsPoint(p Point) bool {
|
func (l1 Line) crossesLine(l2 Line) (Point, bool) {
|
||||||
return false
|
if LinersParallel(l1, l2) {
|
||||||
|
return Point{}, false
|
||||||
|
}
|
||||||
|
|
||||||
|
x := (l1.C - l2.C) / (l2.K - l1.K)
|
||||||
|
y := l1.K*x + l1.C
|
||||||
|
return Point{x, y}, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l LineSegment) crossesLineSegment(with LineSegment) (Point, bool) {
|
|
||||||
return Point{}, false
|
// 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l LineSegment) crossesLine(with Line) (Point, bool) {
|
// Get length of the line segment.
|
||||||
return Point{}, false
|
func (ls LineSegment) Len() Float {
|
||||||
|
return math.Sqrt(ls.LenSqr())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,22 @@ func Sgn(v Float) Float {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Max(v1, v2 Float) Float {
|
||||||
|
if v1 > v2 {
|
||||||
|
return v1
|
||||||
|
}
|
||||||
|
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
func Min(v1, v2 Float) Float {
|
||||||
|
if v1 < v2 {
|
||||||
|
return v1
|
||||||
|
}
|
||||||
|
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
func RadiansToDegrees(v Float) Float {
|
func RadiansToDegrees(v Float) Float {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,13 @@ func (r Rectangle) Vertices() Points {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r Rectangle) Edges() LineSegments {
|
func (r Rectangle) Edges() LineSegments {
|
||||||
return LineSegments{}
|
vs := r.Vertices()
|
||||||
|
return LineSegments{
|
||||||
|
LineSegment{vs[0], vs[1]},
|
||||||
|
LineSegment{vs[1], vs[2]},
|
||||||
|
LineSegment{vs[2], vs[3]},
|
||||||
|
LineSegment{vs[4], vs[0]},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get 2 triangles that the rectangle consists of.
|
// Get 2 triangles that the rectangle consists of.
|
||||||
|
|
|
@ -9,6 +9,7 @@ type Vector struct {
|
||||||
X, Y Float
|
X, Y Float
|
||||||
}
|
}
|
||||||
type Point = Vector
|
type Point = Vector
|
||||||
|
type Vertex = Vector
|
||||||
|
|
||||||
type Vectors []Vector
|
type Vectors []Vector
|
||||||
type Points []Point
|
type Points []Point
|
||||||
|
|
Loading…
Reference in a new issue