go-hep.org/x/hep@v0.38.1/fastjet/internal/delaunay/point_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 "testing" 10 11 "gonum.org/v1/gonum/floats/scalar" 12 ) 13 14 func TestPointEquals(t *testing.T) { 15 tests := []struct { 16 x1, y1, x2, y2 float64 17 want bool 18 }{ 19 {5, 5, 5, 5, true}, 20 {0.5, 4, 1, 4, false}, 21 {-3, 20, 20, -3, false}, 22 {2.5, 4, 2.5, 4, true}, 23 } 24 for _, test := range tests { 25 p1 := NewPoint(test.x1, test.y1) 26 p2 := NewPoint(test.x2, test.y2) 27 got := p1.Equals(p2) 28 if got != test.want { 29 t.Errorf("%v == %v, got = %v, want = %v", p1, p2, got, test.want) 30 } 31 } 32 } 33 34 func TestDistance(t *testing.T) { 35 tests := []struct { 36 x1, y1, x2, y2 float64 37 want float64 38 }{ 39 {1, 1, 3, 3, 8}, 40 {0, 0, 0, 5, 25}, 41 } 42 for _, test := range tests { 43 p1 := NewPoint(test.x1, test.y1) 44 p2 := NewPoint(test.x2, test.y2) 45 got := p1.distance(p2) 46 if got != test.want { 47 t.Errorf("Distance between %v and %v, got = %v, want = %v", p1, p2, got, test.want) 48 } 49 } 50 } 51 52 func TestFindNearest(t *testing.T) { 53 const tol float64 = 0.001 54 tests := []struct { 55 p *Point 56 adjacentTriangles []*Triangle 57 wantDist float64 58 wantNeighbor *Point 59 }{ 60 { 61 NewPoint(0, 0), 62 []*Triangle{ 63 NewTriangle(NewPoint(0, 0), NewPoint(2, 0), NewPoint(0, 5)), 64 NewTriangle(NewPoint(3, 3), NewPoint(0, 0), NewPoint(0, 5)), 65 }, 66 2, 67 NewPoint(2, 0), 68 }, 69 } 70 for _, test := range tests { 71 test.p.adjacentTriangles = test.adjacentTriangles 72 test.p.findNearest() 73 gotNeighbor, gotDistance := test.p.NearestNeighbor() 74 if !scalar.EqualWithinAbs(gotDistance, test.wantDist, tol) || !test.wantNeighbor.Equals(gotNeighbor) { 75 t.Errorf("Nearest Neighbor for P%v with adjacent triangles %v, \n gotDist = %v, wantDist = %v, gotNeighbor = %v, wantNeighbor = %v", 76 test.p, test.adjacentTriangles, gotDistance, test.wantDist, gotNeighbor, test.wantNeighbor) 77 } 78 } 79 } 80 81 func TestFindSecondNearest(t *testing.T) { 82 tests := []struct { 83 p *Point 84 adjacentTriangles []*Triangle 85 wantDist float64 86 wantNeighbor *Point 87 }{ 88 { 89 NewPoint(0, 0), 90 []*Triangle{ 91 NewTriangle(NewPoint(0, 0), NewPoint(2, 0), NewPoint(0, 5)), 92 NewTriangle(NewPoint(3, 3), NewPoint(0, 0), NewPoint(0, 5)), 93 }, 94 math.Sqrt(18), 95 NewPoint(3, 3), 96 }, 97 { 98 // with a duplicate point for (0,0) 99 NewPoint(0, 0), 100 []*Triangle{ 101 NewTriangle(NewPoint(0, 0), NewPoint(2, 0), NewPoint(0, 5)), 102 NewTriangle(NewPoint(3, 3), NewPoint(0, 0), NewPoint(0, 5)), 103 }, 104 2, 105 NewPoint(2, 0), 106 }, 107 { 108 // with a duplicate point for (2,0) 109 NewPoint(0, 0), 110 []*Triangle{ 111 NewTriangle(NewPoint(0, 0), NewPoint(2, 0), NewPoint(0, 5)), 112 NewTriangle(NewPoint(3, 3), NewPoint(0, 0), NewPoint(0, 5)), 113 }, 114 2, 115 NewPoint(2, 0), 116 }, 117 { 118 // with a duplicate point for (2,0) 119 NewPoint(0, 0), 120 []*Triangle{ 121 NewTriangle(NewPoint(0, 5), NewPoint(0, 0), NewPoint(2, 0)), 122 NewTriangle(NewPoint(3, 3), NewPoint(0, 0), NewPoint(0, 5)), 123 }, 124 2, 125 NewPoint(2, 0), 126 }, 127 } 128 // set up the duplicate for (0,0) in test[1] 129 tests[1].p.dist2 = 0 130 tests[1].p.nearest = NewPoint(0, 0) 131 // set up a duplicate for (2,0) in test[2] 132 tests[2].adjacentTriangles[0].B.dist2 = 0 133 tests[2].adjacentTriangles[0].B.nearest = NewPoint(2, 0) 134 // set up a duplicate for (2,0) in test[3] 135 tests[3].adjacentTriangles[0].C.dist2 = 0 136 tests[3].adjacentTriangles[0].C.nearest = NewPoint(2, 0) 137 for _, test := range tests { 138 test.p.adjacentTriangles = test.adjacentTriangles 139 gotNeighbor, gotDistance := test.p.SecondNearestNeighbor() 140 if !scalar.EqualWithinAbs(gotDistance, test.wantDist, tol) || !test.wantNeighbor.Equals(gotNeighbor) { 141 t.Errorf("Second Nearest Neighbor for P%v with adjacent triangles %v, \n gotDist = %v, wantDist = %v, gotNeighbor = %v, wantNeighbor = %v", 142 test.p, test.adjacentTriangles, gotDistance, test.wantDist, gotNeighbor, test.wantNeighbor) 143 } 144 } 145 } 146 147 func TestSurroundingPoints(t *testing.T) { 148 p := NewPoint(0, 0) 149 points := []*Point{NewPoint(1, 0), NewPoint(0, 1), NewPoint(-1, 0), NewPoint(0, -1)} 150 triangles := []*Triangle{NewTriangle(p, points[0], points[1]), NewTriangle(p, points[1], points[2]), NewTriangle(p, points[2], points[3]), NewTriangle(p, points[3], points[0])} 151 p.adjacentTriangles = triangles 152 want := points 153 got := p.surroundingPoints() 154 if len(got) != len(want) { 155 t.Errorf("SurroundingPoints for %v, got = %d, want = %d", p, len(got), len(want)) 156 } 157 for i := range got { 158 if got[i] != want[i] { 159 t.Errorf("SurroundingPoints for %v, got[%d] = %v, want[%d] = %v", p, i, got, i, want) 160 } 161 } 162 } 163 164 func TestInTriangle(t *testing.T) { 165 tests := []struct { 166 x1, y1, x2, y2, x3, y3, x, y float64 167 want location 168 }{ 169 {2, 2, 5, 3, 6, 2, 5, 2.5, inside}, 170 {2, 2, 5, 3, 6, 2, 5, 2, onEdge}, 171 {2, 2, 5, 3, 6, 2, 4, 3, outside}, 172 {2, 2, 5, 3, 6, 2, 10, 2, outside}, 173 {5, 3, 2, 2, 6, 1.5, 5, 2.5, inside}, 174 {5, 3, 2, 2, 6, 1.5, 6, 2.5, outside}, 175 } 176 for _, test := range tests { 177 tri := NewTriangle(NewPoint(test.x1, test.y1), NewPoint(test.x2, test.y2), NewPoint(test.x3, test.y3)) 178 p := NewPoint(test.x, test.y) 179 got := p.inTriangle(tri) 180 if got != test.want { 181 t.Fatalf("Point %v in Triangle %v, got = %v, want = %v", p, tri, got, test.want) 182 } 183 } 184 } 185 186 func TestPointsRemove(t *testing.T) { 187 pts := points{NewPoint(0, 0), NewPoint(1, 1), NewPoint(2, 2), NewPoint(0, 0), NewPoint(3, 3)} 188 want := points{pts[1], pts[2], pts[4]} 189 got := pts.remove(NewPoint(0, 0)) 190 if len(got) != len(want) { 191 t.Errorf("got %d points, want %d", len(got), len(want)) 192 } 193 for i := range got { 194 if !want[i].Equals(got[i]) { 195 t.Errorf("got[%d] = %v, want[%d] = %v", i, got[i], i, want[i]) 196 } 197 } 198 } 199 200 func TestPolyArea(t *testing.T) { 201 tests := []struct { 202 points points 203 want float64 204 }{ 205 {points{NewPoint(0, 0), NewPoint(0, 1), NewPoint(1, 1), NewPoint(1, 0)}, 1}, 206 {points{NewPoint(0, 2), NewPoint(-1, 4), NewPoint(4, 5), NewPoint(5, -1), NewPoint(-2, 0)}, 27}, 207 } 208 for i, test := range tests { 209 got := test.points.polyArea() 210 if !scalar.EqualWithinAbs(got, test.want, tol) { 211 t.Errorf("test %d: got = %f, want = %f", i, got, test.want) 212 } 213 } 214 } 215 216 func TestFindClockwiseTriangle(t *testing.T) { 217 p := NewPoint(0, 0) 218 p1 := NewPoint(2, 0) 219 p2 := NewPoint(0, 3) 220 p3 := NewPoint(-2, 0) 221 p4 := NewPoint(0, -2) 222 t1 := NewTriangle(p, p1, p2) 223 t2 := NewTriangle(NewPoint(-4, 1), NewPoint(-4, 0), p3) 224 t3 := NewTriangle(p, p2, p3) 225 t4 := NewTriangle(p3, p4, p) 226 t5 := NewTriangle(p4, p1, p) 227 t6 := NewTriangle(p1, p2, NewPoint(5, 5)) 228 p.adjacentTriangles = triangles{t1, t3, t4, t5} 229 p1.adjacentTriangles = triangles{t1, t5, t6} 230 p2.adjacentTriangles = triangles{t1, t3, t6} 231 p3.adjacentTriangles = triangles{t2, t3} 232 p4.adjacentTriangles = triangles{t4, t5} 233 want := []*Triangle{t1, t5, t4, t3} 234 got := make([]*Triangle, len(p.adjacentTriangles)) 235 got[0] = p.adjacentTriangles[0] 236 for i := 1; i < len(got); i++ { 237 got[i] = p.findClockwiseTriangle(got[i-1]) 238 } 239 if len(got) != len(want) { 240 t.Fatalf("got = %d triangles, want = %d", len(got), len(want)) 241 } 242 for i := range got { 243 if !got[i].Equals(want[i]) { 244 t.Errorf("got[%d] = %v, want[%d] = %v", i, got[i], i, want[i]) 245 } 246 } 247 }