github.com/utopiagio/gio@v0.0.8/internal/f32/f32.go (about) 1 // SPDX-License-Identifier: Unlicense OR MIT 2 3 /* 4 Package f32 is an internal version of the public package f32 with 5 extra types for internal use. 6 */ 7 package f32 8 9 import ( 10 "image" 11 "math" 12 13 "github.com/utopiagio/gio/f32" 14 ) 15 16 type Point = f32.Point 17 18 type Affine2D = f32.Affine2D 19 20 var NewAffine2D = f32.NewAffine2D 21 22 // A Rectangle contains the points (X, Y) where Min.X <= X < Max.X, 23 // Min.Y <= Y < Max.Y. 24 type Rectangle struct { 25 Min, Max Point 26 } 27 28 // String return a string representation of r. 29 func (r Rectangle) String() string { 30 return r.Min.String() + "-" + r.Max.String() 31 } 32 33 // Rect is a shorthand for Rectangle{Point{x0, y0}, Point{x1, y1}}. 34 // The returned Rectangle has x0 and y0 swapped if necessary so that 35 // it's correctly formed. 36 func Rect(x0, y0, x1, y1 float32) Rectangle { 37 if x0 > x1 { 38 x0, x1 = x1, x0 39 } 40 if y0 > y1 { 41 y0, y1 = y1, y0 42 } 43 return Rectangle{Point{x0, y0}, Point{x1, y1}} 44 } 45 46 // Pt is shorthand for Point{X: x, Y: y}. 47 var Pt = f32.Pt 48 49 // Size returns r's width and height. 50 func (r Rectangle) Size() Point { 51 return Point{X: r.Dx(), Y: r.Dy()} 52 } 53 54 // Dx returns r's width. 55 func (r Rectangle) Dx() float32 { 56 return r.Max.X - r.Min.X 57 } 58 59 // Dy returns r's Height. 60 func (r Rectangle) Dy() float32 { 61 return r.Max.Y - r.Min.Y 62 } 63 64 // Intersect returns the intersection of r and s. 65 func (r Rectangle) Intersect(s Rectangle) Rectangle { 66 if r.Min.X < s.Min.X { 67 r.Min.X = s.Min.X 68 } 69 if r.Min.Y < s.Min.Y { 70 r.Min.Y = s.Min.Y 71 } 72 if r.Max.X > s.Max.X { 73 r.Max.X = s.Max.X 74 } 75 if r.Max.Y > s.Max.Y { 76 r.Max.Y = s.Max.Y 77 } 78 if r.Empty() { 79 return Rectangle{} 80 } 81 return r 82 } 83 84 // Union returns the union of r and s. 85 func (r Rectangle) Union(s Rectangle) Rectangle { 86 if r.Empty() { 87 return s 88 } 89 if s.Empty() { 90 return r 91 } 92 if r.Min.X > s.Min.X { 93 r.Min.X = s.Min.X 94 } 95 if r.Min.Y > s.Min.Y { 96 r.Min.Y = s.Min.Y 97 } 98 if r.Max.X < s.Max.X { 99 r.Max.X = s.Max.X 100 } 101 if r.Max.Y < s.Max.Y { 102 r.Max.Y = s.Max.Y 103 } 104 return r 105 } 106 107 // Canon returns the canonical version of r, where Min is to 108 // the upper left of Max. 109 func (r Rectangle) Canon() Rectangle { 110 if r.Max.X < r.Min.X { 111 r.Min.X, r.Max.X = r.Max.X, r.Min.X 112 } 113 if r.Max.Y < r.Min.Y { 114 r.Min.Y, r.Max.Y = r.Max.Y, r.Min.Y 115 } 116 return r 117 } 118 119 // Empty reports whether r represents the empty area. 120 func (r Rectangle) Empty() bool { 121 return r.Min.X >= r.Max.X || r.Min.Y >= r.Max.Y 122 } 123 124 // Add offsets r with the vector p. 125 func (r Rectangle) Add(p Point) Rectangle { 126 return Rectangle{ 127 Point{r.Min.X + p.X, r.Min.Y + p.Y}, 128 Point{r.Max.X + p.X, r.Max.Y + p.Y}, 129 } 130 } 131 132 // Sub offsets r with the vector -p. 133 func (r Rectangle) Sub(p Point) Rectangle { 134 return Rectangle{ 135 Point{r.Min.X - p.X, r.Min.Y - p.Y}, 136 Point{r.Max.X - p.X, r.Max.Y - p.Y}, 137 } 138 } 139 140 // Round returns the smallest integer rectangle that 141 // contains r. 142 func (r Rectangle) Round() image.Rectangle { 143 return image.Rectangle{ 144 Min: image.Point{ 145 X: int(floor(r.Min.X)), 146 Y: int(floor(r.Min.Y)), 147 }, 148 Max: image.Point{ 149 X: int(ceil(r.Max.X)), 150 Y: int(ceil(r.Max.Y)), 151 }, 152 } 153 } 154 155 // fRect converts a rectangle to a f32internal.Rectangle. 156 func FRect(r image.Rectangle) Rectangle { 157 return Rectangle{ 158 Min: FPt(r.Min), Max: FPt(r.Max), 159 } 160 } 161 162 // Fpt converts an point to a f32.Point. 163 func FPt(p image.Point) Point { 164 return Point{ 165 X: float32(p.X), Y: float32(p.Y), 166 } 167 } 168 169 func ceil(v float32) int { 170 return int(math.Ceil(float64(v))) 171 } 172 173 func floor(v float32) int { 174 return int(math.Floor(float64(v))) 175 }