...
1
2
3
4
5
6 package bezier
7
8 import "gonum.org/v1/plot/vg"
9
10 type point struct {
11 Point, Control vg.Point
12 }
13
14
15
16
17 type Curve []point
18
19
20 func New(cp ...vg.Point) Curve {
21 if len(cp) == 0 {
22 return nil
23 }
24 c := make(Curve, len(cp))
25 for i, p := range cp {
26 c[i].Point = p
27 }
28
29 var w vg.Length
30 for i, p := range c {
31 switch i {
32 case 0:
33 w = 1
34 case 1:
35 w = vg.Length(len(c)) - 1
36 default:
37 w *= vg.Length(len(c)-i) / vg.Length(i)
38 }
39 c[i].Control.X = p.Point.X * w
40 c[i].Control.Y = p.Point.Y * w
41 }
42
43 return c
44 }
45
46
47 func (c Curve) Point(t float64) vg.Point {
48 c[0].Point = c[0].Control
49 u := t
50 for i, p := range c[1:] {
51 c[i+1].Point = vg.Point{
52 X: p.Control.X * vg.Length(u),
53 Y: p.Control.Y * vg.Length(u),
54 }
55 u *= t
56 }
57
58 var (
59 t1 = 1 - t
60 tt = t1
61 )
62 p := c[len(c)-1].Point
63 for i := len(c) - 2; i >= 0; i-- {
64 p.X += c[i].Point.X * vg.Length(tt)
65 p.Y += c[i].Point.Y * vg.Length(tt)
66 tt *= t1
67 }
68
69 return p
70 }
71
72
73
74
75 func (c Curve) Curve(p []vg.Point) []vg.Point {
76 for i, nf := 0, float64(len(p)-1); i < len(p); i++ {
77 p[i] = c.Point(float64(i) / nf)
78 }
79 return p
80 }
81
View as plain text