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  }