github.com/searKing/golang/go@v1.2.117/exp/image/rectangle_test.go (about) 1 // Copyright 2023 The searKing Author. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package image_test 6 7 import ( 8 "fmt" 9 "strconv" 10 "testing" 11 12 image_ "github.com/searKing/golang/go/exp/image" 13 ) 14 15 func TestRectangle(t *testing.T) { 16 // in checks that every point in f is in g. 17 in := func(f, g image_.Rectangle[float32]) error { 18 if !f.In(g) { 19 return fmt.Errorf("f=%s, f.In(%s): got false, want true", f, g) 20 } 21 for y := f.Min.Y; y < f.Max.Y; y++ { 22 for x := f.Min.X; x < f.Max.X; x++ { 23 p := image_.Pt[float32](x, y) 24 if !p.In(g) { 25 return fmt.Errorf("p=%s, p.In(%s): got false, want true", p, g) 26 } 27 } 28 } 29 return nil 30 } 31 32 rects := []image_.Rectangle[float32]{ 33 image_.Rect[float32](0, 0, 10, 10), 34 image_.Rect[float32](10, 0, 20, 10), 35 image_.Rect[float32](1, 2, 3, 4), 36 image_.Rect[float32](4, 6, 10, 10), 37 image_.Rect[float32](2, 3, 12, 5), 38 image_.Rect[float32](-1, -2, 0, 0), 39 image_.Rect[float32](-1, -2, 4, 6), 40 image_.Rect[float32](-10, -20, 30, 40), 41 image_.Rect[float32](8, 8, 8, 8), 42 image_.Rect[float32](88, 88, 88, 88), 43 image_.Rect[float32](6, 5, 4, 3), 44 } 45 46 // r.Eq(s) should be equivalent to every point in r being in s, and every 47 // point in s being in r. 48 for _, r := range rects { 49 for _, s := range rects { 50 got := r.Eq(s) 51 want := in(r, s) == nil && in(s, r) == nil 52 if got != want { 53 t.Errorf("Eq: r=%s, s=%s: got %t, want %t", r, s, got, want) 54 } 55 } 56 } 57 58 // The intersection should be the largest rectangle a such that every point 59 // in a is both in r and in s. 60 for _, r := range rects { 61 for _, s := range rects { 62 a := r.Intersect(s) 63 if err := in(a, r); err != nil { 64 t.Errorf("Intersect: r=%s, s=%s, a=%s, a not in r: %v", r, s, a, err) 65 } 66 if err := in(a, s); err != nil { 67 t.Errorf("Intersect: r=%s, s=%s, a=%s, a not in s: %v", r, s, a, err) 68 } 69 if isZero, overlaps := a == (image_.Rectangle[float32]{}), r.Overlaps(s); isZero == overlaps { 70 t.Errorf("Intersect: r=%s, s=%s, a=%s: isZero=%t same as overlaps=%t", 71 r, s, a, isZero, overlaps) 72 } 73 largerThanA := [4]image_.Rectangle[float32]{a, a, a, a} 74 largerThanA[0].Min.X-- 75 largerThanA[1].Min.Y-- 76 largerThanA[2].Max.X++ 77 largerThanA[3].Max.Y++ 78 for i, b := range largerThanA { 79 if b.Empty() { 80 // b isn't actually larger than a. 81 continue 82 } 83 if in(b, r) == nil && in(b, s) == nil { 84 t.Errorf("Intersect: r=%s, s=%s, a=%s, b=%s, i=%d: intersection could be larger", 85 r, s, a, b, i) 86 } 87 } 88 } 89 } 90 91 // The union should be the smallest rectangle a such that every point in r 92 // is in a and every point in s is in a. 93 for _, r := range rects { 94 for _, s := range rects { 95 a := r.Union(s) 96 if err := in(r, a); err != nil { 97 t.Errorf("Union: r=%s, s=%s, a=%s, r not in a: %v", r, s, a, err) 98 } 99 if err := in(s, a); err != nil { 100 t.Errorf("Union: r=%s, s=%s, a=%s, s not in a: %v", r, s, a, err) 101 } 102 if a.Empty() { 103 // You can't get any smaller than a. 104 continue 105 } 106 smallerThanA := [4]image_.Rectangle[float32]{a, a, a, a} 107 smallerThanA[0].Min.X++ 108 smallerThanA[1].Min.Y++ 109 smallerThanA[2].Max.X-- 110 smallerThanA[3].Max.Y-- 111 for i, b := range smallerThanA { 112 if in(r, b) == nil && in(s, b) == nil { 113 t.Errorf("Union: r=%s, s=%s, a=%s, b=%s, i=%d: union could be smaller", 114 r, s, a, b, i) 115 } 116 } 117 } 118 } 119 } 120 121 func TestRectangle_Border(t *testing.T) { 122 r := image_.Rect(100, 200, 400, 300) 123 124 insets := []int{ 125 -100, 126 -1, 127 +0, 128 +1, 129 +20, 130 +49, 131 +50, 132 +51, 133 +149, 134 +150, 135 +151, 136 } 137 138 for _, inset := range insets { 139 border := r.Border(inset) 140 141 outer, inner := r, r.Inset(inset) 142 if inset < 0 { 143 outer, inner = inner, outer 144 } 145 146 got := 0 147 for _, b := range border { 148 got += b.Area() 149 } 150 want := outer.Area() - inner.Area() 151 if got != want { 152 t.Errorf("inset=%d: total area: got %d, want %d", inset, got, want) 153 } 154 155 for i, bi := range border { 156 for j, bj := range border { 157 if i <= j { 158 continue 159 } 160 if !bi.Intersect(bj).Empty() { 161 t.Errorf("inset=%d: %v and %v overlap", inset, bi, bj) 162 } 163 } 164 } 165 166 for _, b := range border { 167 if got := outer.Intersect(b); got != b { 168 t.Errorf("inset=%d: outer intersection: got %v, want %v", inset, got, b) 169 } 170 if got := inner.Intersect(b); !got.Empty() { 171 t.Errorf("inset=%d: inner intersection: got %v, want empty", inset, got) 172 } 173 } 174 } 175 } 176 177 func TestRectangle_BorderPoint(t *testing.T) { 178 r := image_.Rect(100, 200, 400, 300) 179 180 insets := []image_.Point[int]{ 181 image_.Pt(-100, -100), 182 image_.Pt(-1, -1), 183 image_.Pt(+0, +0), 184 image_.Pt(+1, +1), 185 image_.Pt(+20, +20), 186 image_.Pt(+49, +49), 187 image_.Pt(+50, +50), 188 image_.Pt(+51, +51), 189 image_.Pt(+149, +149), 190 image_.Pt(+150, +150), 191 image_.Pt(+151, +151), 192 } 193 194 for _, inset := range insets { 195 border := r.BorderPoint(inset) 196 197 outer, inner := r, r.InsetPoint(inset) 198 if outer.Area() < inner.Area() { 199 outer, inner = inner, outer 200 } 201 202 got := 0 203 for _, b := range border { 204 got += b.Area() 205 } 206 want := outer.Area() - inner.Area() 207 if got != want { 208 t.Errorf("inset=%d: total area: got %d, want %d", inset, got, want) 209 } 210 211 for i, bi := range border { 212 for j, bj := range border { 213 if i <= j { 214 continue 215 } 216 if !bi.Intersect(bj).Empty() { 217 t.Errorf("inset=%d: %v and %v overlap", inset, bi, bj) 218 } 219 } 220 } 221 222 for _, b := range border { 223 if got := outer.Intersect(b); got != b { 224 t.Errorf("inset=%d: outer intersection: got %v, want %v", inset, got, b) 225 } 226 if got := inner.Intersect(b); !got.Empty() { 227 t.Errorf("inset=%d: inner intersection: got %v, want empty", inset, got) 228 } 229 } 230 } 231 } 232 233 func TestRectangle_BorderRectangle(t *testing.T) { 234 r := image_.Rect(100, 200, 400, 300) 235 236 insets := []image_.Rectangle[int]{ 237 image_.Rect(-100, -100, -100, -100), 238 image_.Rect(-1, -1, -1, -1), 239 image_.Rect(+0, +0, +0, +0), 240 image_.Rect(+1, +1, +1, +1), 241 image_.Rect(+20, +20, +20, +20), 242 image_.Rect(+49, +49, +49, +49), 243 image_.Rect(+50, +50, +50, +50), 244 image_.Rect(+51, +51, +51, +51), 245 image_.Rect(+149, +149, +149, +149), 246 image_.Rect(+150, +150, +150, +150), 247 image_.Rect(+151, +151, +151, +151), 248 } 249 250 for _, inset := range insets { 251 border := r.BorderRectangle(inset) 252 253 outer, inner := r, r.InsetRectangle(inset) 254 if outer.Area() < inner.Area() { 255 outer, inner = inner, outer 256 } 257 258 got := 0 259 for _, b := range border { 260 got += b.Area() 261 } 262 want := outer.Area() - inner.Area() 263 if got != want { 264 t.Errorf("inset=%d: total area: got %d, want %d", inset, got, want) 265 } 266 267 for i, bi := range border { 268 for j, bj := range border { 269 if i <= j { 270 continue 271 } 272 if !bi.Intersect(bj).Empty() { 273 t.Errorf("inset=%d: %v and %v overlap", inset, bi, bj) 274 } 275 } 276 } 277 278 for _, b := range border { 279 if got := outer.Intersect(b); got != b { 280 t.Errorf("inset=%d: outer intersection: got %v, want %v", inset, got, b) 281 } 282 if got := inner.Intersect(b); !got.Empty() { 283 t.Errorf("inset=%d: inner intersection: got %v, want empty", inset, got) 284 } 285 } 286 } 287 } 288 289 func TestRectangle_FlexIn(t *testing.T) { 290 tests := []struct { 291 r image_.Rectangle[int] 292 box image_.Rectangle[int] 293 want image_.Rectangle[int] 294 }{ 295 {image_.Rectangle[int]{}, image_.Rectangle[int]{}, image_.Rectangle[int]{}}, 296 {image_.Rect(0, 0, 10, 10), image_.Rectangle[int]{}, image_.Rectangle[int]{}}, 297 {image_.Rect(0, 0, 10, 10), image_.Rect(1, 2, 3, 4), image_.Rect(1, 2, 3, 4)}, 298 {image_.Rect(0, 0, 10, 10), image_.Rect(-1, -2, 13, 14), image_.Rect(0, 0, 10, 10)}, 299 {image_.Rect(0, 0, 10, 10), image_.Rect(1, -2, 3, 14), image_.Rect(1, 0, 3, 10)}, 300 {image_.Rect(0, 0, 10, 10), image_.Rect(1, 2, 13, 14), image_.Rect(1, 2, 11, 12)}, 301 {image_.Rect(0, 0, 10, 10), image_.Rect(1, 2, 13, 10), image_.Rect(1, 2, 11, 10)}, 302 {image_.Rect(0, 0, 10, 10), image_.Rect(20, 20, 20, 20), image_.Rect(20, 20, 20, 20)}, 303 {image_.Rect(0, 0, 10, 10), image_.Rect(1, 20, 3, 20), image_.Rect(1, 20, 3, 20)}, 304 } 305 for i, tt := range tests { 306 t.Run(strconv.Itoa(i), func(t *testing.T) { 307 got := tt.r.FlexIn(tt.box) 308 if got != tt.want { 309 t.Errorf("(%v).FlexIn(%v) got (%v), want (%v)", tt.r, tt.box, got, tt.want) 310 } 311 }) 312 } 313 }