-
Notifications
You must be signed in to change notification settings - Fork 0
/
geometry_rect.go
125 lines (105 loc) · 2.67 KB
/
geometry_rect.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package main
import (
"fmt"
"math"
)
// Rect represents a rectangle in a 2D plane.
type Rect struct {
Xf, Xt, Yf, Yt float64
}
// IsSame tests if two Rects are the same.
func (r Rect) IsSame(t Rect) bool {
return r.Xf == t.Xf && r.Xt == t.Xt && r.Yf == t.Yf && r.Yt == t.Yt
}
// Width returns the width of the Rect.
func (r Rect) Width() float64 {
return r.Xt - r.Xf
}
// Height returns the height of the Rect.
func (r Rect) Height() float64 {
return r.Yt - r.Yf
}
// Area returns the area of the Rect.
func (r Rect) Area() float64 {
return r.Width() * r.Height()
}
// Center returns the center Point of the Rect.
func (r Rect) Center() Point {
return NewPoint(
math.Round(r.Xf+r.Width()/2),
math.Round(r.Yf+r.Height()/2),
)
}
// Symmetric returns the symmetric Rect according to the given width and height.
func (r Rect) Symmetric(width, height float64) Rect {
return Rect{
Xf: width - r.Xf,
Xt: width - r.Xt,
Yf: height - r.Yf,
Yt: height - r.Yt,
}
}
// IsContainsPoint tests if the Rect contains the Point.
func (r Rect) IsContainsPoint(t Point) bool {
return t.X >= r.Xf && t.X <= r.Xt && t.Y >= r.Yf && t.Y <= r.Yt
}
// IsContainsRectangle tests if the Rect contains the other Rect.
func (r Rect) IsContainsRectangle(t Rect) bool {
return r.Xf <= t.Xf && r.Xt >= t.Xt && r.Yf <= t.Yf && r.Yt >= t.Yt
}
// IsIntersectsRect tests if the Rect intersects the other Rect.
func (r Rect) IsIntersectsRect(t Rect) bool {
return !(r.Xt < t.Xf || r.Xf > t.Xt || r.Yt < t.Yf || r.Yf > t.Yt)
}
// RectsIntersection returns the intersection Rect of two Rects.
func (r Rect) RectsIntersection(t Rect) (Rect, bool) {
if !r.IsIntersectsRect(t) {
return Rect{}, false
}
ir := NewRectangle(
math.Max(r.Xf, t.Xf),
math.Min(r.Xt, t.Xt),
math.Max(r.Yf, t.Yf),
math.Min(r.Yt, t.Yt),
)
if ir.Width() == 0 || ir.Height() == 0 {
return Rect{}, false
}
return ir, true
}
// Vertices returns the Points vertices of the Rect.
func (r Rect) Vertices() Points {
return Points{
topLeft0: {r.Xf, r.Yt},
topRight0: {r.Xt, r.Yt},
bottomRight0: {r.Xt, r.Yf},
bottomLeft0: {r.Xf, r.Yf},
}
}
// Edges returns the Lines edges of the Rect.
func (r Rect) Edges() Lines {
return Lines{
top: {Point{r.Xf, r.Yt}, Point{r.Xt, r.Yt}},
right: {Point{r.Xt, r.Yf}, Point{r.Xt, r.Yt}},
bottom: {Point{r.Xf, r.Yf}, Point{r.Xt, r.Yf}},
left: {Point{r.Xf, r.Yf}, Point{r.Xf, r.Yt}},
}
}
func (r Rect) String() string {
return fmt.Sprintf("[X:%.f>%.f,Y:%.f>%.f]", r.Xf, r.Xt, r.Yf, r.Yt)
}
func NewRectangle(xf, xt, yf, yt float64) Rect {
if xf > xt {
xf, xt = xt, xf
}
if yf > yt {
yf, yt = yt, yf
}
return Rect{
Xf: xf,
Xt: xt,
Yf: yf,
Yt: yt,
}
}
type Rects []Rect