1 package geo
2
3 import "fmt"
4
5 type Box struct {
6 TopLeft *Point
7 Width float64
8 Height float64
9 }
10
11 func NewBox(tl *Point, width, height float64) *Box {
12 return &Box{
13 TopLeft: tl,
14 Width: width,
15 Height: height,
16 }
17 }
18
19 func (b *Box) Copy() *Box {
20 if b == nil {
21 return nil
22 }
23 return NewBox(b.TopLeft.Copy(), b.Width, b.Height)
24 }
25
26 func (b *Box) Center() *Point {
27 return NewPoint(b.TopLeft.X+b.Width/2, b.TopLeft.Y+b.Height/2)
28 }
29
30
31 func (b *Box) Intersects(s Segment, buffer float64) bool {
32 tl := NewPoint(b.TopLeft.X-buffer, b.TopLeft.Y-buffer)
33 tr := NewPoint(tl.X+b.Width+buffer*2, tl.Y)
34 br := NewPoint(tr.X, tr.Y+b.Height+buffer*2)
35 bl := NewPoint(tl.X, br.Y)
36
37 if p := IntersectionPoint(s.Start, s.End, tl, tr); p != nil {
38 return true
39 }
40 if p := IntersectionPoint(s.Start, s.End, tr, br); p != nil {
41 return true
42 }
43 if p := IntersectionPoint(s.Start, s.End, br, bl); p != nil {
44 return true
45 }
46 if p := IntersectionPoint(s.Start, s.End, bl, tl); p != nil {
47 return true
48 }
49 return false
50 }
51
52 func (b *Box) Intersections(s Segment) []*Point {
53 pts := []*Point{}
54
55 tl := b.TopLeft
56 tr := NewPoint(tl.X+b.Width, tl.Y)
57 br := NewPoint(tr.X, tr.Y+b.Height)
58 bl := NewPoint(tl.X, br.Y)
59
60 if p := IntersectionPoint(s.Start, s.End, tl, tr); p != nil {
61 pts = append(pts, p)
62 }
63 if p := IntersectionPoint(s.Start, s.End, tr, br); p != nil {
64 pts = append(pts, p)
65 }
66 if p := IntersectionPoint(s.Start, s.End, br, bl); p != nil {
67 pts = append(pts, p)
68 }
69 if p := IntersectionPoint(s.Start, s.End, bl, tl); p != nil {
70 pts = append(pts, p)
71 }
72 return pts
73 }
74
75 func (b *Box) ToString() string {
76 if b == nil {
77 return ""
78 }
79 return fmt.Sprintf("{TopLeft: %s, Width: %.0f, Height: %.0f}", b.TopLeft.ToString(), b.Width, b.Height)
80 }
81
82 func (b *Box) Contains(p *Point) bool {
83 return !(p.X < b.TopLeft.X || b.TopLeft.X+b.Width < p.X ||
84 p.Y < b.TopLeft.Y || b.TopLeft.Y+b.Height < p.Y)
85 }
86
87 func (b1 Box) Overlaps(b2 Box) bool {
88
89 return (b1.TopLeft.X < (b2.TopLeft.X + b2.Width)) && ((b1.TopLeft.X + b1.Width) > b2.TopLeft.X) &&
90 (b1.TopLeft.Y < (b2.TopLeft.Y + b2.Height)) && ((b1.TopLeft.Y + b1.Height) > b2.TopLeft.Y)
91 }
92
View as plain text