...

Source file src/gonum.org/v1/plot/tools/bezier/bezier_test.go

Documentation: gonum.org/v1/plot/tools/bezier

     1  // Copyright ©2013 The Gonum 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 bezier
     6  
     7  import (
     8  	"math"
     9  	"reflect"
    10  	"testing"
    11  
    12  	"gonum.org/v1/plot/vg"
    13  )
    14  
    15  const tol = 1e-12
    16  
    17  func approxEqual(a, b vg.Point, tol float64) bool {
    18  	return (math.Abs(float64(a.X-b.X)) <= tol || (math.IsNaN(float64(a.X)) && math.IsNaN(float64(b.X)))) &&
    19  		(math.Abs(float64(a.Y-b.Y)) <= tol || (math.IsNaN(float64(a.Y)) && math.IsNaN(float64(b.Y))))
    20  }
    21  
    22  func TestNew(t *testing.T) {
    23  	for i, test := range []struct {
    24  		ctrls []vg.Point
    25  		curve Curve
    26  	}{
    27  		{
    28  			ctrls: nil,
    29  			curve: nil,
    30  		},
    31  		{
    32  			ctrls: []vg.Point{{X: 1, Y: 2}, {X: 3, Y: 4}, {X: 5, Y: 6}, {X: 7, Y: 8}},
    33  			curve: Curve{
    34  				{Point: vg.Point{X: 1, Y: 2}, Control: vg.Point{X: 1, Y: 2}},
    35  				{Point: vg.Point{X: 3, Y: 4}, Control: vg.Point{X: 9, Y: 12}},
    36  				{Point: vg.Point{X: 5, Y: 6}, Control: vg.Point{X: 15, Y: 18}},
    37  				{Point: vg.Point{X: 7, Y: 8}, Control: vg.Point{X: 7, Y: 8}},
    38  			},
    39  		},
    40  		{
    41  			ctrls: []vg.Point{{X: 0, Y: 0}, {X: 0, Y: 1}, {X: 1, Y: 1}, {X: 1, Y: 0}},
    42  			curve: Curve{
    43  				{Point: vg.Point{X: 0, Y: 0}, Control: vg.Point{X: 0, Y: 0}},
    44  				{Point: vg.Point{X: 0, Y: 1}, Control: vg.Point{X: 0, Y: 3}},
    45  				{Point: vg.Point{X: 1, Y: 1}, Control: vg.Point{X: 3, Y: 3}},
    46  				{Point: vg.Point{X: 1, Y: 0}, Control: vg.Point{X: 1, Y: 0}},
    47  			},
    48  		},
    49  		{
    50  			ctrls: []vg.Point{{X: 0, Y: 0}, {X: 0, Y: 1}, {X: 1, Y: 0}, {X: 1, Y: 1}},
    51  			curve: Curve{
    52  				{Point: vg.Point{X: 0, Y: 0}, Control: vg.Point{X: 0, Y: 0}},
    53  				{Point: vg.Point{X: 0, Y: 1}, Control: vg.Point{X: 0, Y: 3}},
    54  				{Point: vg.Point{X: 1, Y: 0}, Control: vg.Point{X: 3, Y: 0}},
    55  				{Point: vg.Point{X: 1, Y: 1}, Control: vg.Point{X: 1, Y: 1}},
    56  			},
    57  		},
    58  	} {
    59  		bc := New(test.ctrls...)
    60  		if !reflect.DeepEqual(bc, test.curve) {
    61  			t.Errorf("unexpected result for test %d:\ngot: %+v\nwant:%+v", i, bc, test.ctrls)
    62  		}
    63  	}
    64  }
    65  
    66  func TestPoint(t *testing.T) {
    67  	type tPoints []struct {
    68  		t     float64
    69  		point vg.Point
    70  	}
    71  	for i, test := range []struct {
    72  		ctrls []vg.Point
    73  		tPoints
    74  	}{
    75  		{
    76  			ctrls: []vg.Point{{X: 1, Y: 2}, {X: 3, Y: 4}, {X: 5, Y: 6}, {X: 7, Y: 8}},
    77  			tPoints: tPoints{
    78  				{t: 0, point: vg.Point{X: 1, Y: 2}},
    79  				{t: 0.1, point: vg.Point{X: 1.6, Y: 2.6}},
    80  				{t: 0.2, point: vg.Point{X: 2.2, Y: 3.2}},
    81  				{t: 0.3, point: vg.Point{X: 2.8, Y: 3.8}},
    82  				{t: 0.4, point: vg.Point{X: 3.4, Y: 4.4}},
    83  				{t: 0.5, point: vg.Point{X: 4, Y: 5}},
    84  				{t: 0.6, point: vg.Point{X: 4.6, Y: 5.6}},
    85  				{t: 0.7, point: vg.Point{X: 5.2, Y: 6.2}},
    86  				{t: 0.8, point: vg.Point{X: 5.8, Y: 6.8}},
    87  				{t: 0.9, point: vg.Point{X: 6.4, Y: 7.4}},
    88  				{t: 1, point: vg.Point{X: 7, Y: 8}},
    89  			},
    90  		},
    91  		{
    92  			ctrls: []vg.Point{{X: 0, Y: 0}, {X: 0, Y: 1}, {X: 1, Y: 1}, {X: 1, Y: 0}},
    93  			tPoints: tPoints{
    94  				{t: 0, point: vg.Point{X: 0, Y: 0}},
    95  				{t: 0.1, point: vg.Point{X: 0.028, Y: 0.27}},
    96  				{t: 0.2, point: vg.Point{X: 0.104, Y: 0.48}},
    97  				{t: 0.3, point: vg.Point{X: 0.216, Y: 0.63}},
    98  				{t: 0.4, point: vg.Point{X: 0.352, Y: 0.72}},
    99  				{t: 0.5, point: vg.Point{X: 0.5, Y: 0.75}},
   100  				{t: 0.6, point: vg.Point{X: 0.648, Y: 0.72}},
   101  				{t: 0.7, point: vg.Point{X: 0.784, Y: 0.63}},
   102  				{t: 0.8, point: vg.Point{X: 0.896, Y: 0.48}},
   103  				{t: 0.9, point: vg.Point{X: 0.972, Y: 0.27}},
   104  				{t: 1, point: vg.Point{X: 1, Y: 0}},
   105  			},
   106  		},
   107  		{
   108  			ctrls: []vg.Point{{X: 0, Y: 0}, {X: 0, Y: 1}, {X: 1, Y: 0}, {X: 1, Y: 1}},
   109  			tPoints: tPoints{
   110  				{t: 0, point: vg.Point{X: 0, Y: 0}},
   111  				{t: 0.1, point: vg.Point{X: 0.028, Y: 0.244}},
   112  				{t: 0.2, point: vg.Point{X: 0.104, Y: 0.392}},
   113  				{t: 0.3, point: vg.Point{X: 0.216, Y: 0.468}},
   114  				{t: 0.4, point: vg.Point{X: 0.352, Y: 0.496}},
   115  				{t: 0.5, point: vg.Point{X: 0.5, Y: 0.5}},
   116  				{t: 0.6, point: vg.Point{X: 0.648, Y: 0.504}},
   117  				{t: 0.7, point: vg.Point{X: 0.784, Y: 0.532}},
   118  				{t: 0.8, point: vg.Point{X: 0.896, Y: 0.608}},
   119  				{t: 0.9, point: vg.Point{X: 0.972, Y: 0.756}},
   120  				{t: 1, point: vg.Point{X: 1, Y: 1}},
   121  			},
   122  		},
   123  	} {
   124  		bc := New(test.ctrls...)
   125  		for j, tPoint := range test.tPoints {
   126  			got := bc.Point(tPoint.t)
   127  			want := test.tPoints[j].point
   128  			if !approxEqual(got, want, tol) {
   129  				t.Errorf("unexpected point for test %d part %d %+v: got:%+v want:%+v", i, j, test.ctrls, got, want)
   130  			}
   131  		}
   132  	}
   133  }
   134  
   135  func TestCurve(t *testing.T) {
   136  	for i, test := range []struct {
   137  		ctrls  []vg.Point
   138  		points []vg.Point
   139  	}{
   140  		{
   141  			ctrls: []vg.Point{{X: 1, Y: 2}, {X: 3, Y: 4}, {X: 5, Y: 6}, {X: 7, Y: 8}},
   142  			points: []vg.Point{
   143  				{X: 1, Y: 2},
   144  				{X: 1.6, Y: 2.6},
   145  				{X: 2.2, Y: 3.2},
   146  				{X: 2.8, Y: 3.8},
   147  				{X: 3.4, Y: 4.4},
   148  				{X: 4, Y: 5},
   149  				{X: 4.6, Y: 5.6},
   150  				{X: 5.2, Y: 6.2},
   151  				{X: 5.8, Y: 6.8},
   152  				{X: 6.4, Y: 7.4},
   153  				{X: 7, Y: 8},
   154  			},
   155  		},
   156  		{
   157  			ctrls: []vg.Point{{X: 0, Y: 0}, {X: 0, Y: 1}, {X: 1, Y: 1}, {X: 1, Y: 0}},
   158  			points: []vg.Point{
   159  				{X: 0, Y: 0},
   160  				{X: 0.028, Y: 0.27},
   161  				{X: 0.104, Y: 0.48},
   162  				{X: 0.216, Y: 0.63},
   163  				{X: 0.352, Y: 0.72},
   164  				{X: 0.5, Y: 0.75},
   165  				{X: 0.648, Y: 0.72},
   166  				{X: 0.784, Y: 0.63},
   167  				{X: 0.896, Y: 0.48},
   168  				{X: 0.972, Y: 0.27},
   169  				{X: 1, Y: 0},
   170  			},
   171  		},
   172  		{
   173  			ctrls: []vg.Point{{X: 0, Y: 0}, {X: 0, Y: 1}, {X: 1, Y: 0}, {X: 1, Y: 1}},
   174  			points: []vg.Point{
   175  				{X: 0, Y: 0},
   176  				{X: 0.028, Y: 0.244},
   177  				{X: 0.104, Y: 0.392},
   178  				{X: 0.216, Y: 0.468},
   179  				{X: 0.352, Y: 0.496},
   180  				{X: 0.5, Y: 0.5},
   181  				{X: 0.648, Y: 0.504},
   182  				{X: 0.784, Y: 0.532},
   183  				{X: 0.896, Y: 0.608},
   184  				{X: 0.972, Y: 0.756},
   185  				{X: 1, Y: 1},
   186  			},
   187  		},
   188  		{
   189  			ctrls:  []vg.Point{{X: 0, Y: 0}, {X: 0, Y: 1}, {X: 1, Y: 0}, {X: 1, Y: 1}},
   190  			points: []vg.Point{},
   191  		},
   192  		{
   193  			ctrls: []vg.Point{{X: 0, Y: 0}, {X: 0, Y: 1}, {X: 1, Y: 0}, {X: 1, Y: 1}},
   194  			points: []vg.Point{
   195  				{X: vg.Length(math.NaN()), Y: vg.Length(math.NaN())},
   196  			},
   197  		}, {
   198  			ctrls: []vg.Point{{X: 0, Y: 0}, {X: 0, Y: 1}, {X: 1, Y: 0}, {X: 1, Y: 1}},
   199  			points: []vg.Point{
   200  				{X: 0, Y: 0},
   201  				{X: 1, Y: 1},
   202  			},
   203  		},
   204  	} {
   205  		bc := New(test.ctrls...).Curve(make([]vg.Point, len(test.points)))
   206  		for j, got := range bc {
   207  			want := test.points[j]
   208  			if !approxEqual(got, want, tol) {
   209  				t.Errorf("unexpected point for test %d part %d %+v: got:%+v want:%+v", i, j, test.ctrls, got, want)
   210  			}
   211  		}
   212  	}
   213  }
   214  

View as plain text