go-hep.org/x/hep@v0.38.1/fastjet/internal/delaunay/delaunay_test.go (about) 1 // Copyright ©2017 The go-hep Authors. 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 delaunay 6 7 import ( 8 "math" 9 "math/rand" 10 "slices" 11 "testing" 12 ) 13 14 const tol = 1e-3 15 16 func TestHierarchicalDelaunayDuplicates(t *testing.T) { 17 // NewPoint(x, y) 18 p1 := NewPoint(0, 0) 19 p2 := NewPoint(0, 2) 20 p3 := NewPoint(1, 0) 21 p4 := NewPoint(4, 4) 22 p5 := NewPoint(1, 0) // p5 is a duplicate 23 ps := []*Point{ 24 p1, 25 p2, 26 p3, 27 p4, 28 p5, 29 } 30 d := HierarchicalDelaunay() 31 for _, p := range ps { 32 d.Insert(p) 33 } 34 exp := []*Triangle{ 35 NewTriangle(p1, p2, p3), 36 NewTriangle(p2, p3, p4), 37 } 38 ts := d.Triangles() 39 got, want := len(ts), len(exp) 40 if got != want { 41 t.Errorf("got=%d delaunay triangles, want=%d", got, want) 42 } 43 for i := range ts { 44 ok := false 45 for j := range exp { 46 if ts[i].Equals(exp[j]) { 47 ok = true 48 // remove triangles that have been matched from slice, 49 // in case there are duplicate triangles. 50 exp = slices.Delete(exp, j, j+1) 51 break 52 } 53 } 54 if !ok { 55 t.Errorf("Triangle T%s not as expected", ts[i]) 56 } 57 } 58 var ( 59 nn []*Point 60 nd []float64 61 ) 62 for _, p := range ps { 63 n, d := p.NearestNeighbor() 64 nn = append(nn, n) 65 nd = append(nd, d) 66 } 67 expN := []*Point{p3, p1, p5, p2, p3} 68 expD := []float64{1.0, 2.0, 0, 4.4721, 0} 69 got, want = len(nn), len(expN) 70 if got != want { 71 t.Errorf("got=%d nearest neighbors, want=%d", got, want) 72 } 73 for i := range nn { 74 if !nn[i].Equals(expN[i]) { 75 t.Errorf("got=N%s nearest neighbor, want=N%s", nn[i], expN[i]) 76 } 77 if math.Abs(nd[i]-expD[i]) > tol { 78 t.Errorf("got=%f distance, want=%f for point P%s with neighbour N%s", nd[i], expD[i], ps[i], nn[i]) 79 } 80 } 81 } 82 83 func TestHierarchicalDelaunayInsertSmall(t *testing.T) { 84 // NewPoint(x, y) 85 p1 := NewPoint(0, 0) 86 p2 := NewPoint(0, 2) 87 p3 := NewPoint(1, 0) 88 p4 := NewPoint(4, 4) 89 ps := []*Point{ 90 p1, 91 p2, 92 p3, 93 p4, 94 } 95 d := HierarchicalDelaunay() 96 for _, p := range ps { 97 d.Insert(p) 98 } 99 exp := []*Triangle{ 100 NewTriangle(p1, p2, p3), 101 NewTriangle(p2, p3, p4), 102 } 103 ts := d.Triangles() 104 got, want := len(ts), len(exp) 105 if got != want { 106 t.Errorf("got=%d delaunay triangles, want=%d", got, want) 107 } 108 for i := range ts { 109 ok := false 110 for j := range exp { 111 if ts[i].Equals(exp[j]) { 112 ok = true 113 // remove triangles that have been matched from slice, 114 // in case there are duplicate triangles. 115 exp = slices.Delete(exp, j, j+1) 116 break 117 } 118 } 119 if !ok { 120 t.Errorf("Triangle T%s not as expected", ts[i]) 121 } 122 } 123 var ( 124 nn []*Point 125 nd []float64 126 ) 127 for _, p := range ps { 128 n, d := p.NearestNeighbor() 129 nn = append(nn, n) 130 nd = append(nd, d) 131 } 132 expN := []*Point{p3, p1, p1, p2} 133 expD := []float64{1.0, 2.0, 1.0, 4.4721} 134 got, want = len(nn), len(expN) 135 if got != want { 136 t.Errorf("got=%d nearest neighbors, want=%d", got, want) 137 } 138 for i := range nn { 139 if !nn[i].Equals(expN[i]) { 140 t.Errorf("got=N%s nearest neighbor, want=N%s", nn[i], expN[i]) 141 } 142 if math.Abs(nd[i]-expD[i]) > tol { 143 t.Errorf("got=%f distance, want=%f for point P%s with neighbour N%s", nd[i], expD[i], ps[i], nn[i]) 144 } 145 } 146 } 147 148 func TestHierarchicalDelaunayInsertMedium(t *testing.T) { 149 // NewPoint(x, y) 150 p1 := NewPoint(-1.5, 3.2) 151 p2 := NewPoint(1.8, 3.3) 152 p3 := NewPoint(-3.7, 1.5) 153 p4 := NewPoint(-1.5, 1.3) 154 p5 := NewPoint(0.8, 1.2) 155 p6 := NewPoint(3.3, 1.5) 156 p7 := NewPoint(-4, -1) 157 p8 := NewPoint(-2.3, -0.7) 158 p9 := NewPoint(0, -0.5) 159 p10 := NewPoint(2, -1.5) 160 p11 := NewPoint(3.7, -0.8) 161 p12 := NewPoint(-3.5, -2.9) 162 p13 := NewPoint(-0.9, -3.9) 163 p14 := NewPoint(2, -3.5) 164 p15 := NewPoint(3.5, -2.25) 165 ps := []*Point{p1, p2, p3, p4, p5, p6, p7, p8, 166 p9, p10, p11, p12, p13, p14, p15} 167 d := HierarchicalDelaunay() 168 for _, p := range ps { 169 d.Insert(p) 170 } 171 ts := d.Triangles() 172 exp := []*Triangle{ 173 NewTriangle(p1, p3, p4), 174 NewTriangle(p1, p4, p5), 175 NewTriangle(p1, p5, p2), 176 NewTriangle(p2, p5, p6), 177 NewTriangle(p3, p4, p8), 178 NewTriangle(p3, p8, p7), 179 NewTriangle(p4, p8, p9), 180 NewTriangle(p4, p9, p5), 181 NewTriangle(p5, p9, p10), 182 NewTriangle(p5, p10, p6), 183 NewTriangle(p6, p10, p11), 184 NewTriangle(p7, p8, p12), 185 NewTriangle(p8, p12, p13), 186 NewTriangle(p8, p13, p9), 187 NewTriangle(p9, p13, p10), 188 NewTriangle(p10, p13, p14), 189 NewTriangle(p10, p14, p15), 190 NewTriangle(p10, p15, p11), 191 } 192 got, want := len(ts), len(exp) 193 if got != want { 194 t.Errorf("got=%d delaunay triangles, want=%d", got, want) 195 } 196 for i := range ts { 197 ok := false 198 for j := range exp { 199 if ts[i].Equals(exp[j]) { 200 ok = true 201 // remove triangles that have been matched from slice, 202 // in case there are duplicate triangles. 203 exp = slices.Delete(exp, j, j+1) 204 break 205 } 206 } 207 if !ok { 208 t.Errorf("Triangle T%s not as expected", ts[i]) 209 } 210 } 211 var ( 212 nn []*Point 213 nd []float64 214 ) 215 for _, p := range ps { 216 n, d := p.NearestNeighbor() 217 nn = append(nn, n) 218 nd = append(nd, d) 219 } 220 expN := []*Point{p4, p5, p4, p1, p9, p11, p8, p7, p5, p15, p15, p7, p12, p15, p11} 221 expD := []float64{1.9, 2.326, 2.209, 1.9, 1.879, 2.335, 1.726, 1.726, 1.879, 1.677, 1.464, 1.965, 2.786, 1.953, 1.464} 222 got, want = len(nn), len(expN) 223 if got != want { 224 t.Errorf("got=%d nearest neighbors, want=%d", got, want) 225 } 226 for i := range nn { 227 if !nn[i].Equals(expN[i]) { 228 t.Errorf("got=N%s nearest neighbor, want=N%s", nn[i], expN[i]) 229 } 230 if math.Abs(nd[i]-expD[i]) > tol { 231 t.Errorf("got=%f distance, want=%f for point P%s with neighbour N%s", nd[i], expD[i], ps[i], nn[i]) 232 } 233 } 234 } 235 236 func grid(nx, ny int, angle float64) []*Point { 237 s := math.Sin(angle) 238 c := math.Cos(angle) 239 var points []*Point 240 for xi := range nx { 241 tx := float64(xi) 242 for yi := range ny { 243 ty := float64(yi) 244 x := tx*c - ty*s 245 y := tx*s + ty*c 246 points = append(points, NewPoint(x, y)) 247 } 248 } 249 return points 250 } 251 252 func TestHierarchicalDelaunayGrid(t *testing.T) { 253 const degrees = math.Pi / 180 254 const n = 10 255 ps := grid(n, n, 10*degrees) 256 d := HierarchicalDelaunay() 257 for _, p := range ps { 258 d.Insert(p) 259 } 260 } 261 262 func TestHierarchicalDelaunayGridRotated(t *testing.T) { 263 const degrees = math.Pi / 180 264 const n = 10 265 ps := grid(n, n, 60*degrees) 266 d := HierarchicalDelaunay() 267 for _, p := range ps { 268 d.Insert(p) 269 } 270 } 271 272 func benchmarkHierarchicalDelaunayInsertion(i int, b *testing.B) { 273 ps := make([]*Point, i) 274 for j := range i { 275 x := rand.Float64() * 1000 276 y := rand.Float64() * 1000 277 ps[j] = NewPoint(x, y) 278 } 279 b.ReportAllocs() 280 b.ResetTimer() 281 for n := 0; n < b.N; n++ { 282 d := HierarchicalDelaunay() 283 for _, p := range ps { 284 d.Insert(p) 285 } 286 } 287 } 288 289 func BenchmarkHierarchicalDelaunayInsertion50(b *testing.B) { 290 benchmarkHierarchicalDelaunayInsertion(50, b) 291 } 292 293 func BenchmarkHierarchicalDelaunayInsertion100(b *testing.B) { 294 benchmarkHierarchicalDelaunayInsertion(100, b) 295 } 296 297 func BenchmarkHierarchicalDelaunayInsertion150(b *testing.B) { 298 benchmarkHierarchicalDelaunayInsertion(150, b) 299 } 300 301 func BenchmarkHierarchicalDelaunayInsertion200(b *testing.B) { 302 benchmarkHierarchicalDelaunayInsertion(200, b) 303 } 304 305 func BenchmarkHierarchicalDelaunayInsertion250(b *testing.B) { 306 benchmarkHierarchicalDelaunayInsertion(250, b) 307 } 308 309 func BenchmarkHierarchicalDelaunayInsertion300(b *testing.B) { 310 benchmarkHierarchicalDelaunayInsertion(300, b) 311 } 312 313 func BenchmarkHierarchicalDelaunayInsertion350(b *testing.B) { 314 benchmarkHierarchicalDelaunayInsertion(350, b) 315 } 316 317 func BenchmarkHierarchicalDelaunayInsertion400(b *testing.B) { 318 benchmarkHierarchicalDelaunayInsertion(400, b) 319 } 320 321 func BenchmarkHierarchicalDelaunayInsertion450(b *testing.B) { 322 benchmarkHierarchicalDelaunayInsertion(450, b) 323 } 324 325 func BenchmarkHierarchicalDelaunayInsertion500(b *testing.B) { 326 benchmarkHierarchicalDelaunayInsertion(500, b) 327 } 328 329 func BenchmarkHierarchicalDelaunayInsertion550(b *testing.B) { 330 benchmarkHierarchicalDelaunayInsertion(550, b) 331 } 332 333 func BenchmarkHierarchicalDelaunayInsertion600(b *testing.B) { 334 benchmarkHierarchicalDelaunayInsertion(600, b) 335 } 336 337 func BenchmarkHierarchicalDelaunayInsertion650(b *testing.B) { 338 benchmarkHierarchicalDelaunayInsertion(650, b) 339 } 340 341 func BenchmarkHierarchicalDelaunayInsertion700(b *testing.B) { 342 benchmarkHierarchicalDelaunayInsertion(700, b) 343 } 344 345 func BenchmarkHierarchicalDelaunayInsertion750(b *testing.B) { 346 benchmarkHierarchicalDelaunayInsertion(750, b) 347 } 348 349 func BenchmarkHierarchicalDelaunayInsertion800(b *testing.B) { 350 benchmarkHierarchicalDelaunayInsertion(800, b) 351 } 352 353 func BenchmarkHierarchicalDelaunayInsertion850(b *testing.B) { 354 benchmarkHierarchicalDelaunayInsertion(850, b) 355 } 356 357 func BenchmarkHierarchicalDelaunayInsertion900(b *testing.B) { 358 benchmarkHierarchicalDelaunayInsertion(900, b) 359 } 360 361 func BenchmarkHierarchicalDelaunayInsertion950(b *testing.B) { 362 benchmarkHierarchicalDelaunayInsertion(950, b) 363 } 364 365 func BenchmarkHierarchicalDelaunayInsertion1000(b *testing.B) { 366 benchmarkHierarchicalDelaunayInsertion(1000, b) 367 } 368 369 func TestHierarchicalDelaunayRemovalSmall(t *testing.T) { 370 // NewPoint(x, y) 371 p1 := NewPoint(0, 0) 372 p2 := NewPoint(0, 2) 373 p3 := NewPoint(1, 0) 374 p4 := NewPoint(4, 4) 375 // point to be removed later 376 pE := NewPoint(3, 2) 377 ps := []*Point{ 378 p1, 379 p2, 380 p3, 381 pE, 382 p4, 383 } 384 d := HierarchicalDelaunay() 385 for _, p := range ps { 386 d.Insert(p) 387 } 388 d.Remove(pE) 389 exp := []*Triangle{ 390 NewTriangle(p1, p2, p3), 391 NewTriangle(p2, p3, p4), 392 } 393 ts := d.Triangles() 394 got, want := len(ts), len(exp) 395 if got != want { 396 t.Errorf("got=%d delaunay triangles, want=%d", got, want) 397 } 398 for i := range ts { 399 ok := false 400 for j := range exp { 401 if ts[i].Equals(exp[j]) { 402 ok = true 403 // remove triangles that have been matched from slice, 404 // in case there are duplicate triangles. 405 exp = slices.Delete(exp, j, j+1) 406 break 407 } 408 } 409 if !ok { 410 t.Errorf("Triangle T%s not as expected", ts[i]) 411 } 412 } 413 var ( 414 nn []*Point 415 nd []float64 416 ) 417 for _, p := range ps { 418 if p.Equals(pE) { 419 continue 420 } 421 n, d := p.NearestNeighbor() 422 nn = append(nn, n) 423 nd = append(nd, d) 424 } 425 expN := []*Point{p3, p1, p1, p2} 426 expD := []float64{1.0, 2.0, 1.0, 4.4721} 427 got, want = len(nn), len(expN) 428 if got != want { 429 t.Errorf("got=%d nearest neighbors, want=%d", got, want) 430 } 431 for i := range nn { 432 if !nn[i].Equals(expN[i]) { 433 t.Errorf("got=N%s nearest neighbor, want=N%s", nn[i], expN[i]) 434 } 435 if math.Abs(nd[i]-expD[i]) > tol { 436 t.Errorf("got=%f distance, want=%f for point P%s with neighbour N%s", nd[i], expD[i], ps[i], nn[i]) 437 } 438 } 439 } 440 441 func TestHierarchicalDelaunayRemovalMedium(t *testing.T) { 442 // NewPoint(x, y) 443 p1 := NewPoint(-1.5, 3.2) 444 p2 := NewPoint(1.8, 3.3) 445 p3 := NewPoint(-3.7, 1.5) 446 p4 := NewPoint(-1.5, 1.3) 447 p5 := NewPoint(0.8, 1.2) 448 p6 := NewPoint(3.3, 1.5) 449 p7 := NewPoint(-4, -1) 450 p8 := NewPoint(-2.3, -0.7) 451 p9 := NewPoint(0, -0.5) 452 p10 := NewPoint(2, -1.5) 453 p11 := NewPoint(3.7, -0.8) 454 p12 := NewPoint(-3.5, -2.9) 455 p13 := NewPoint(-0.9, -3.9) 456 p14 := NewPoint(2, -3.5) 457 p15 := NewPoint(3.5, -2.25) 458 // points to be removed later 459 pE1 := NewPoint(0, 0) 460 pE2 := NewPoint(-2.3, -0.6) 461 pE3 := NewPoint(2, 1.2) 462 pE4 := NewPoint(-2.8, -0.5) 463 ps := []*Point{p1, p2, p3, p4, p5, p6, pE3, pE4, 464 p9, p10, p11, p12, p13, p14} 465 d := HierarchicalDelaunay() 466 for _, p := range ps { 467 d.Insert(p) 468 } 469 d.Remove(pE4) 470 d.Insert(pE1) 471 d.Remove(pE3) 472 d.Insert(p15) 473 d.Insert(pE2) 474 d.Remove(pE1) 475 d.Insert(p7) 476 d.Insert(p8) 477 d.Remove(pE2) 478 ts := d.Triangles() 479 exp := []*Triangle{ 480 NewTriangle(p1, p3, p4), 481 NewTriangle(p1, p4, p5), 482 NewTriangle(p1, p5, p2), 483 NewTriangle(p2, p5, p6), 484 NewTriangle(p3, p4, p8), 485 NewTriangle(p3, p8, p7), 486 NewTriangle(p4, p8, p9), 487 NewTriangle(p4, p9, p5), 488 NewTriangle(p5, p9, p10), 489 NewTriangle(p5, p10, p6), 490 NewTriangle(p6, p10, p11), 491 NewTriangle(p7, p8, p12), 492 NewTriangle(p8, p12, p13), 493 NewTriangle(p8, p13, p9), 494 NewTriangle(p9, p13, p10), 495 NewTriangle(p10, p13, p14), 496 NewTriangle(p10, p14, p15), 497 NewTriangle(p10, p15, p11), 498 } 499 got, want := len(ts), len(exp) 500 if got != want { 501 t.Errorf("got=%d delaunay triangles, want=%d", got, want) 502 } 503 for i := range ts { 504 ok := false 505 for j := range exp { 506 if ts[i].Equals(exp[j]) { 507 ok = true 508 // remove triangles that have been matched from slice, 509 // in case there are duplicate triangles. 510 exp = slices.Delete(exp, j, j+1) 511 break 512 } 513 } 514 if !ok { 515 t.Errorf("Triangle T%s not as expected", ts[i]) 516 } 517 } 518 var ( 519 nn []*Point 520 nd []float64 521 ) 522 pts := []*Point{p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15} 523 for _, p := range pts { 524 n, d := p.NearestNeighbor() 525 nn = append(nn, n) 526 nd = append(nd, d) 527 } 528 expN := []*Point{p4, p5, p4, p1, p9, p11, p8, p7, p5, p15, p15, p7, p12, p15, p11} 529 expD := []float64{1.9, 2.326, 2.209, 1.9, 1.879, 2.335, 1.726, 1.726, 1.879, 1.677, 1.464, 1.965, 2.786, 1.953, 1.464} 530 got, want = len(nn), len(expN) 531 if got != want { 532 t.Errorf("got=%d nearest neighbors, want=%d", got, want) 533 } 534 for i := range nn { 535 if !nn[i].Equals(expN[i]) { 536 t.Errorf("got=N%s nearest neighbor, want=N%s", nn[i], expN[i]) 537 } 538 if math.Abs(nd[i]-expD[i]) > tol { 539 t.Errorf("got=%f distance, want=%f for point P%s with neighbour N%s", nd[i], expD[i], ps[i], nn[i]) 540 } 541 } 542 } 543 544 func benchmarkHierarchicalDelaunayRemoval(i int, b *testing.B) { 545 ps := make([]*Point, i) 546 for j := range i { 547 x := rand.Float64() * 1000 548 y := rand.Float64() * 1000 549 ps[j] = NewPoint(x, y) 550 } 551 b.ReportAllocs() 552 b.ResetTimer() 553 for n := 0; n < b.N; n++ { 554 d := HierarchicalDelaunay() 555 for _, p := range ps { 556 d.Insert(p) 557 } 558 for _, p := range ps { 559 d.Remove(p) 560 } 561 } 562 } 563 564 func BenchmarkHierarchicalDelaunayInsertionAndRemoval50(b *testing.B) { 565 benchmarkHierarchicalDelaunayRemoval(50, b) 566 } 567 568 func BenchmarkHierarchicalDelaunayInsertionAndRemovall00(b *testing.B) { 569 benchmarkHierarchicalDelaunayRemoval(100, b) 570 } 571 572 func BenchmarkHierarchicalDelaunayInsertionAndRemoval150(b *testing.B) { 573 benchmarkHierarchicalDelaunayRemoval(150, b) 574 } 575 576 func BenchmarkHierarchicalDelaunayInsertionAndRemoval200(b *testing.B) { 577 benchmarkHierarchicalDelaunayRemoval(200, b) 578 } 579 580 func BenchmarkHierarchicalDelaunayInsertionAndRemoval250(b *testing.B) { 581 benchmarkHierarchicalDelaunayRemoval(250, b) 582 } 583 584 func BenchmarkHierarchicalDelaunayInsertionAndRemoval300(b *testing.B) { 585 benchmarkHierarchicalDelaunayRemoval(300, b) 586 } 587 588 func BenchmarkHierarchicalDelaunayInsertionAndRemoval350(b *testing.B) { 589 benchmarkHierarchicalDelaunayRemoval(350, b) 590 } 591 592 func BenchmarkHierarchicalDelaunayInsertionAndRemoval400(b *testing.B) { 593 benchmarkHierarchicalDelaunayRemoval(400, b) 594 } 595 596 func BenchmarkHierarchicalDelaunayInsertionAndRemoval450(b *testing.B) { 597 benchmarkHierarchicalDelaunayRemoval(450, b) 598 } 599 600 func BenchmarkHierarchicalDelaunayInsertionAndRemoval500(b *testing.B) { 601 benchmarkHierarchicalDelaunayRemoval(500, b) 602 } 603 604 func BenchmarkHierarchicalDelaunayInsertionAndRemoval550(b *testing.B) { 605 benchmarkHierarchicalDelaunayRemoval(550, b) 606 } 607 608 func BenchmarkHierarchicalDelaunayInsertionAndRemoval600(b *testing.B) { 609 benchmarkHierarchicalDelaunayRemoval(600, b) 610 } 611 612 func BenchmarkHierarchicalDelaunayInsertionAndRemoval650(b *testing.B) { 613 benchmarkHierarchicalDelaunayRemoval(650, b) 614 } 615 616 func BenchmarkHierarchicalDelaunayInsertionAndRemoval700(b *testing.B) { 617 benchmarkHierarchicalDelaunayRemoval(700, b) 618 } 619 620 func BenchmarkHierarchicalDelaunayInsertionAndRemoval750(b *testing.B) { 621 benchmarkHierarchicalDelaunayRemoval(750, b) 622 } 623 624 func BenchmarkHierarchicalDelaunayInsertionAndRemoval800(b *testing.B) { 625 benchmarkHierarchicalDelaunayRemoval(800, b) 626 } 627 628 func BenchmarkHierarchicalDelaunayInsertionAndRemoval850(b *testing.B) { 629 benchmarkHierarchicalDelaunayRemoval(850, b) 630 } 631 632 func BenchmarkHierarchicalDelaunayInsertionAndRemoval900(b *testing.B) { 633 benchmarkHierarchicalDelaunayRemoval(900, b) 634 } 635 636 func BenchmarkHierarchicalDelaunayInsertionAndRemoval950(b *testing.B) { 637 benchmarkHierarchicalDelaunayRemoval(950, b) 638 } 639 640 func BenchmarkHierarchicalDelaunayInsertionAndRemoval1000(b *testing.B) { 641 benchmarkHierarchicalDelaunayRemoval(1000, b) 642 } 643 644 func TestVoronoiCell(t *testing.T) { 645 p := NewPoint(0, 0) 646 p1 := NewPoint(2, 0) 647 p2 := NewPoint(0, 3) 648 p3 := NewPoint(-2, 0) 649 p4 := NewPoint(0, -2) 650 t1 := NewTriangle(p, p1, p2) 651 t2 := NewTriangle(NewPoint(-4, 1), NewPoint(-4, 0), p3) 652 t3 := NewTriangle(p, p2, p3) 653 t4 := NewTriangle(p3, p4, p) 654 t5 := NewTriangle(p4, p1, p) 655 t6 := NewTriangle(p1, p2, NewPoint(5, 5)) 656 p.adjacentTriangles = triangles{t1, t3, t4, t5} 657 p1.adjacentTriangles = triangles{t1, t5, t6} 658 p2.adjacentTriangles = triangles{t1, t3, t6} 659 p3.adjacentTriangles = triangles{t2, t3} 660 p4.adjacentTriangles = triangles{t4, t5} 661 d := &Delaunay{root: NewTriangle(NewPoint(-100, -100), NewPoint(100, -100), NewPoint(0, 100))} 662 wantPoints := []*Point{NewPoint(1, 1.5), NewPoint(1, -1), NewPoint(-1, -1), NewPoint(-1, 1.5)} 663 wantArea := 5.0 664 gotPoints, gotArea := d.VoronoiCell(p) 665 if wantArea != gotArea { 666 t.Errorf("area got = %f, want = %f", gotArea, wantArea) 667 } 668 if len(wantPoints) != len(gotPoints) { 669 t.Fatalf("got = %d points, want = %d", len(gotPoints), len(wantPoints)) 670 } 671 for i, got := range gotPoints { 672 if !got.Equals(wantPoints[i]) { 673 t.Errorf("vornoi point got = %v, want = %v", got, wantPoints[i]) 674 } 675 } 676 } 677 678 func TestVoronoiCellBorder(t *testing.T) { 679 p := NewPoint(0, 0) 680 p1 := NewPoint(2, 0) 681 p2 := NewPoint(0, 3) 682 p3 := NewPoint(-2, 0) 683 p4 := NewPoint(0, -2) 684 t1 := NewTriangle(p, p1, p2) 685 t2 := NewTriangle(NewPoint(-4, 1), NewPoint(-4, 0), p3) 686 t3 := NewTriangle(p, p2, p3) 687 t4 := NewTriangle(p3, p4, p) 688 t5 := NewTriangle(p4, p1, p) 689 t6 := NewTriangle(p1, p2, NewPoint(5, 5)) 690 p.adjacentTriangles = triangles{t1, t3, t4, t5} 691 p1.adjacentTriangles = triangles{t1, t5, t6} 692 p2.adjacentTriangles = triangles{t1, t3, t6} 693 p3.adjacentTriangles = triangles{t2, t3} 694 p4.adjacentTriangles = triangles{t4, t5} 695 d := &Delaunay{root: NewTriangle(NewPoint(-100, 100), NewPoint(100, 100), p4)} 696 wantPoints := []*Point{NewPoint(-1, -1), NewPoint(-1, 1.5), NewPoint(1, 1.5), NewPoint(1, -1)} 697 wantArea := math.Inf(1) 698 gotPoints, gotArea := d.VoronoiCell(p) 699 if wantArea != gotArea { 700 t.Errorf("area got = %f, want = %f", gotArea, wantArea) 701 } 702 if len(wantPoints) != len(gotPoints) { 703 t.Fatalf("got = %d points, want = %d", len(gotPoints), len(wantPoints)) 704 } 705 for i, got := range gotPoints { 706 if !got.Equals(wantPoints[i]) { 707 t.Errorf("vornoi point got = %v, want = %v", got, wantPoints[i]) 708 } 709 } 710 }