bezier_curve 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +44 -0
- data/Rakefile +8 -0
- data/lib/bezier_curve/n_point.rb +46 -0
- data/lib/bezier_curve/version.rb +7 -0
- data/lib/bezier_curve.rb +151 -0
- data/test/test_bezier_curve.rb +104 -0
- data/test/test_n_point.rb +51 -0
- metadata +51 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7bdfef0208f447bf444392f207505bcf076d56db
|
4
|
+
data.tar.gz: fffe1353eca9734c7b1e5a8076a0da179bfd0435
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7b57e98d8ffcd9ac90b1d969e3728890bc654493d56006d8ec5a5d39f4386e6b6eb5252a6272bfc8c10511130b5bf7f0cbaedcfb8c62ae2779dedf9092119818
|
7
|
+
data.tar.gz: e8f69f9b96cb70bed85e8f70167247e33ecd26dd9536061c822b0773f4391b8f274303fc95958d1afc881b549d6c42c6f39d52a787fc15e615b8842bf16b6e8a
|
data/README.md
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# bezier_curve
|
2
|
+
A bézier curve library for Ruby, supporting n-dimensional, nth-degree curves
|
3
|
+
|
4
|
+
A rather simple and small library that should do pretty much anything you need to do with a bezier curve. It supports arbitrary numbers of dimensions, and arbitrary numbers of control points. Even still, it is pretty easy to use. Here's a simple quadratic (1st degree) bezier curve, in 2-dimensional space:
|
5
|
+
|
6
|
+
# create the curve
|
7
|
+
curve = BezierCurve.new([0,0],[0,1],[1,1])
|
8
|
+
# determine its points for drawing purposes
|
9
|
+
curve.points
|
10
|
+
[[0, 0], [0.00390625, 0.12109375], ... [0.87890625, 0.99609375], 1, 1]
|
11
|
+
|
12
|
+
When outputting points, it automatically chooses a suitable angle tolerance which would make the resulting poly-line appear relatively smooth (no angle changes more than about 3 degrees). But you can choose your own tolerance:
|
13
|
+
|
14
|
+
# Extreme precision, less than 1 degree tolerance
|
15
|
+
curve.points(tolerance: Math::PI/180)
|
16
|
+
# just give me 5 points, quick:
|
17
|
+
curve.points(count: 5)
|
18
|
+
|
19
|
+
You can easily split a curve into two, at a given value of `t`
|
20
|
+
|
21
|
+
# split the curve at its midpoint
|
22
|
+
curve.split_at(0.5)
|
23
|
+
#=> [BezierCurve([0, 0], [0.0, 0.5], [0.25, 0.75]), BezierCurve([0.25, 0.75], [0.5, 1.0], [1, 1])]
|
24
|
+
|
25
|
+
You can also specify n-dimensional curves:
|
26
|
+
|
27
|
+
# a 4-dimensional curve of 2nd order
|
28
|
+
curve = BezierCurve.new([0,0,0,0], [1,1,2,2], [4,5,9,3])
|
29
|
+
# get its points
|
30
|
+
curve.points(count:3)
|
31
|
+
#=> [[0.0, 0.0, 0.0, 0.0], [1.5, 1.75, 3.25, 1.75], [4.0, 5.0, 9.0, 3.0]]
|
32
|
+
|
33
|
+
You can also specify any degree/order of curve you like:
|
34
|
+
|
35
|
+
# 2d curve, 6th degree
|
36
|
+
curve = BezierCurve.new([0,0],[1,1],[2,-1],[3,1],[4,-1],[5,1],[6,-1])
|
37
|
+
curve.degree
|
38
|
+
#=> 6
|
39
|
+
curve.points.size
|
40
|
+
#=> 35
|
41
|
+
|
42
|
+
Note that the complexity goes up exponentially for higher degree curves, so performance may suffer if used extensively; but the capability is there if you need it. In fact, if you want, you can really slow things down and do a 18-dimensional curve of the 300th order. The sky is the limit. Well, your processor and memory are the limit, but you get the idea.
|
43
|
+
|
44
|
+
I am interested in making this the most useful ruby library for working with bezier curves. If you need help, or have a suggestion for improvement, feel free to file an issue on Github (https://github.com/marcuserronius/bezier_curve/), or contact me directly.
|
data/Rakefile
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# bezier_curve/n_point.rb
|
2
|
+
|
3
|
+
# Extends an array to treat it as an n-dimensional point. Should not
|
4
|
+
# occlude any original Array methods
|
5
|
+
module NPoint
|
6
|
+
# calculates how far this point is from `other`
|
7
|
+
def dist_from(other)
|
8
|
+
raise "Dimension counts don't match! (%i and %i)" %[size,other.size] unless size == other.size
|
9
|
+
zip(other).map{|a,b|(a-b)**2}.inject{|a,b|a+b}**0.5
|
10
|
+
end
|
11
|
+
# calculates the angle formed by this point and two others
|
12
|
+
# in radians
|
13
|
+
def angle_to(a,b)
|
14
|
+
a,b = *[a,b].map(&:to_np)
|
15
|
+
d0,d1 = dist_from(a), a.dist_from(b)
|
16
|
+
z = self.to(a,1+d1/d0)
|
17
|
+
dz = z.dist_from(b)
|
18
|
+
Math.asin(dz/2/d1)*2
|
19
|
+
end
|
20
|
+
|
21
|
+
# calculates the new point on the vector of self->other, scaled by `t`.
|
22
|
+
# t=0 returns `self`, t=.5 is the midpoint, t=1 is `other`.
|
23
|
+
def to(other, t)
|
24
|
+
self.zip(other).map{|a,b|t*(b-a)+a}.to_np
|
25
|
+
end
|
26
|
+
|
27
|
+
# convert to NPoint; returns self
|
28
|
+
def to_np
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
32
|
+
# get the x value
|
33
|
+
def x() self[0]; end
|
34
|
+
# get the y value
|
35
|
+
def y() self[1]; end
|
36
|
+
# get the z value
|
37
|
+
def z() self[2]; end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
class Array
|
42
|
+
# add n-point functions to a copy of this array
|
43
|
+
def to_np
|
44
|
+
dup.extend NPoint
|
45
|
+
end
|
46
|
+
end
|
data/lib/bezier_curve.rb
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
# bezier_curve.rb
|
2
|
+
# A bézier curve library for Ruby, supporting n-dimensional,
|
3
|
+
# nth-degree curves.
|
4
|
+
|
5
|
+
require 'bezier_curve/version'
|
6
|
+
require 'bezier_curve/n_point'
|
7
|
+
|
8
|
+
# A bezier curve. Usage:
|
9
|
+
# c = BezierCurve.new([0,0], [0,1], [1,1])
|
10
|
+
# c.first #=> [0,0]
|
11
|
+
# c.last #=> [1,1]
|
12
|
+
# c[0.375] #=> [t=.375]
|
13
|
+
# c.points #=> an array of points that make a fairly smooth curve
|
14
|
+
# c.points(tolerance:Math::PI/20)
|
15
|
+
# #=> returns points with given tolerance for smoothness
|
16
|
+
# c.points(count: 10) #=> returns 10 points, for evenly spaced values of `t`
|
17
|
+
class BezierCurve
|
18
|
+
# create a new curve, from a list of points.
|
19
|
+
def initialize(*controls)
|
20
|
+
# check for argument errors
|
21
|
+
ZeroDimensionError.check! controls
|
22
|
+
DifferingDimensionError.check! controls
|
23
|
+
InsufficientPointsError.check! controls
|
24
|
+
|
25
|
+
@controls = controls.map(&:to_np)
|
26
|
+
end
|
27
|
+
|
28
|
+
attr_reader :controls
|
29
|
+
|
30
|
+
# the first control point
|
31
|
+
def first() controls.first; end
|
32
|
+
alias_method :start, :first
|
33
|
+
# the last control point
|
34
|
+
def last() controls.last; end
|
35
|
+
alias_method :end, :last
|
36
|
+
|
37
|
+
# the degree of the curve
|
38
|
+
def degree
|
39
|
+
controls.size - 1
|
40
|
+
end
|
41
|
+
alias_method :order, :degree
|
42
|
+
# the number of dimensions given
|
43
|
+
def dimensions
|
44
|
+
controls[0].size
|
45
|
+
end
|
46
|
+
|
47
|
+
# find the point for a given value of `t`.
|
48
|
+
def index(t)
|
49
|
+
pts = controls
|
50
|
+
while pts.size > 1
|
51
|
+
pts = (0..pts.size-2).map do |i|
|
52
|
+
pts[i].zip(pts[i+1]).map{|a,b| t*(b-a)+a}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
pts[0].to_np
|
56
|
+
end
|
57
|
+
alias_method :[], :index
|
58
|
+
|
59
|
+
# divide this bezier curve into two curves, at the given `t`
|
60
|
+
def split_at(t)
|
61
|
+
pts = controls
|
62
|
+
a,b = [pts.first],[pts.last]
|
63
|
+
while pts.size > 1
|
64
|
+
pts = (0..pts.size-2).map do |i|
|
65
|
+
pts[i].zip(pts[i+1]).map{|a,b| t*(b-a)+a}
|
66
|
+
end
|
67
|
+
a<<pts.first
|
68
|
+
b<<pts.last
|
69
|
+
end
|
70
|
+
[BezierCurve.new(*a), BezierCurve.new(*b.reverse)]
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
# Returns a list of points on this curve. If you specify `count`,
|
75
|
+
# returns that many points, evenly spread over values of `t`.
|
76
|
+
# If you specify `tolerance`, no adjoining line segments will
|
77
|
+
# deviate from 180 by an angle of more than the value given (in
|
78
|
+
# radians). If unspecified, defaults to `tolerance: 1/64pi` (~3 deg)
|
79
|
+
def points(count:nil, tolerance:Math::PI/64)
|
80
|
+
if count
|
81
|
+
(0...count).map{|i| index i/(count-1.0)}
|
82
|
+
else
|
83
|
+
lines = subdivide(tolerance)
|
84
|
+
lines.map{|seg|seg.first} + [lines.last.last]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# recursively subdivides the curve until each is straight within the
|
89
|
+
# given tolerance value, in radians
|
90
|
+
def subdivide(tolerance)
|
91
|
+
if is_straight?(tolerance)
|
92
|
+
[self]
|
93
|
+
else
|
94
|
+
a,b = split_at(0.5)
|
95
|
+
a.subdivide(tolerance) + b.subdivide(tolerance)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
# test this curve to see of it can be considered straight, optionally
|
101
|
+
# within the given angular tolerance, in radians
|
102
|
+
def is_straight?(tolerance)
|
103
|
+
# sanity check for tolerance in radians
|
104
|
+
if first.angle_to(index(0.5), last) <= tolerance
|
105
|
+
# maximum wavyness is `degree` - 1; split at `degree` points
|
106
|
+
pts = points(count:degree)
|
107
|
+
# size-3, because we ignore the last 2 points as starting points;
|
108
|
+
# check all angles against `tolerance`
|
109
|
+
(0..pts.size-3).all? do |i|
|
110
|
+
pts[i].angle_to(pts[i+1], pts[i+2]) < tolerance
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Indicates an error where the control points are in zero dimensions.
|
116
|
+
# Sounds silly, but you never know when software is generating the
|
117
|
+
# points.
|
118
|
+
class ZeroDimensionError < ArgumentError
|
119
|
+
def initialize
|
120
|
+
super "Points given must have at least one dimension"
|
121
|
+
end
|
122
|
+
def self.check! pointset
|
123
|
+
raise new.tap{|e|e.backtrace.shift} if
|
124
|
+
pointset[0].size == 0
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
# Indicates that the points do not all have the same number of
|
129
|
+
# dimensions, which makes them impossible to use.
|
130
|
+
class DifferingDimensionError < ArgumentError
|
131
|
+
def initialize
|
132
|
+
super "All points must have the same number of dimensions"
|
133
|
+
end
|
134
|
+
def self.check! pointset
|
135
|
+
raise new.tap{|e|e.backtrace.shift} if
|
136
|
+
pointset[1..-1].any?{|pt| pointset[0].size != pt.size}
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
# Indicates that there aren't enough control points; minimum of two
|
141
|
+
# for a first-degree bezier.
|
142
|
+
class InsufficientPointsError < ArgumentError
|
143
|
+
def initialize
|
144
|
+
super "All points must have the same number of dimensions"
|
145
|
+
end
|
146
|
+
def self.check! pointset
|
147
|
+
raise new.tap{|e|e.backtrace.shift} if
|
148
|
+
pointset.size <= 1
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# test functionality of BezierCurve class
|
2
|
+
require 'test/unit'
|
3
|
+
require 'bezier_curve'
|
4
|
+
|
5
|
+
class TestBezierCurve < Test::Unit::TestCase
|
6
|
+
# shorthand to create a bezier curve
|
7
|
+
def bc(*args)
|
8
|
+
BezierCurve.new(*args)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_degree
|
12
|
+
assert_equal 2, bc([0,0],[0,1],[1,1]).degree
|
13
|
+
assert_equal 3, bc([0,0],[0,1],[1,0],[1,1]).degree
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_dimensions
|
17
|
+
assert_equal 2, bc([0,0],[0,1],[1,1]).dimensions
|
18
|
+
assert_equal 3, bc([0,0,0],[0,1,1],[1,1,2]).dimensions
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_index
|
22
|
+
# simple curves that cross the origin
|
23
|
+
# degree 1
|
24
|
+
assert_equal [0,0], bc([1,1],[-1,-1])[0.5]
|
25
|
+
assert_equal [0,0,0], bc([1,1,1],[-1,-1,-1])[0.5]
|
26
|
+
assert_equal [0,0,0,0], bc([1,1,1,1],[-1,-1,-1,-1])[0.5]
|
27
|
+
assert_equal [0,0,0,0,0], bc([1,1,1,1,1],[-1,-1,-1,-1,-1])[0.5]
|
28
|
+
# degree 2 (quadratic)
|
29
|
+
assert_equal [0,0], bc([1,1],[0,-1],[-1,1])[0.5]
|
30
|
+
assert_equal [0,0,0], bc([1,1,1],[0,0,-1],[-1,-1,1])[0.5]
|
31
|
+
assert_equal [0,0,0,0], bc([1,1,1,1],[0,0,0,-1],[-1,-1,-1,1])[0.5]
|
32
|
+
assert_equal [0,0,0,0,0], bc([1,1,1,1,1],[0,0,0,0,-1],[-1,-1,-1,-1,1])[0.5]
|
33
|
+
# degree 3 (cubic)
|
34
|
+
assert_equal [0,0], bc([1,1],[-1,1],[1,-1],[-1,-1])[0.5]
|
35
|
+
assert_equal [0,0,0], bc([1,1,1],[-1,1,1],[1,-1,-1],[-1,-1,-1])[0.5]
|
36
|
+
assert_equal [0,0,0,0], bc([1,1,1,1],[-1,1,1,1],[1,-1,-1,-1],[-1,-1,-1,-1])[0.5]
|
37
|
+
assert_equal [0,0,0,0,0], bc([1,1,1,1,1],[-1,1,1,1,1],[1,-1,-1,-1,-1],[-1,-1,-1,-1,-1])[0.5]
|
38
|
+
end
|
39
|
+
def test_split_at
|
40
|
+
# not going to test specific points, just that the resulting curves are the same
|
41
|
+
# degree 1
|
42
|
+
c = bc([23,42],[13,7])
|
43
|
+
_c1, _c2 = *c.split_at(0.25)
|
44
|
+
assert_equal c.points(count:9), _c1.points(count:3)[0,2] + _c2.points(count:7)
|
45
|
+
# degree 2
|
46
|
+
c = bc([23,42],[13,7])
|
47
|
+
_c1, _c2 = *c.split_at(0.25)
|
48
|
+
assert_equal c.points(count:9), _c1.points(count:3)[0,2] + _c2.points(count:7)
|
49
|
+
# degree 3
|
50
|
+
c = bc([23,42,],[13,7],[12,54])
|
51
|
+
_c1, _c2 = *c.split_at(0.25)
|
52
|
+
assert_equal c.points(count:9), _c1.points(count:3)[0,2] + _c2.points(count:7)
|
53
|
+
# degree 4
|
54
|
+
c = bc([23,42],[13,7],[12,54],[103,144])
|
55
|
+
_c1, _c2 = *c.split_at(0.25)
|
56
|
+
assert_equal c.points(count:9), _c1.points(count:3)[0,2] + _c2.points(count:7)
|
57
|
+
# degree 5
|
58
|
+
c = bc([23,42],[13,7],[12,54],[103,144],[512,360])
|
59
|
+
_c1, _c2 = *c.split_at(0.25)
|
60
|
+
assert_equal c.points(count:9), _c1.points(count:3)[0,2] + _c2.points(count:7)
|
61
|
+
end
|
62
|
+
# does this really need testing? I really hope not. Oh well.
|
63
|
+
def test_points_count
|
64
|
+
# 1d,o1
|
65
|
+
[2,3,5,8,13,23].each do |n|
|
66
|
+
assert_equal n, bc([0,0],[1,1]).points(count:n).count
|
67
|
+
end
|
68
|
+
# 2d,o2
|
69
|
+
[2,3,5,8,13,23].each do |n|
|
70
|
+
assert_equal n, bc([0,0,0],[1,1,1],[2,2,2]).points(count:n).count
|
71
|
+
end
|
72
|
+
# 3d,o3
|
73
|
+
[2,3,5,8,13,23].each do |n|
|
74
|
+
assert_equal n, bc(*4.times.map{|n|Array.new(4).fill(n)}).points(count:n).count
|
75
|
+
end
|
76
|
+
# 4d,o4
|
77
|
+
[2,3,5,8,13,23].each do |n|
|
78
|
+
assert_equal n, bc(*5.times.map{|n|Array.new(5).fill(n)}).points(count:n).count
|
79
|
+
end
|
80
|
+
# 5d,o5
|
81
|
+
[2,3,5,8,13,23].each do |n|
|
82
|
+
assert_equal n, bc(*6.times.map{|n|Array.new(6).fill(n)}).points(count:n).count
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_points_tolerance
|
87
|
+
pi = Math::PI
|
88
|
+
# just make sure all points are under tolerance
|
89
|
+
# 2d/o
|
90
|
+
p = bc([1,0],[3,2],[7,9]).points(tolerance:pi/53)
|
91
|
+
assert_true (0..p.count-3).all?{|i|p[i].angle_to(p[i+1],p[i+2]).abs < pi/53}
|
92
|
+
# 3d/o
|
93
|
+
p = bc([1,0,2],[3,2,5],[7,9,8],[13,17,12]).points(tolerance:pi/53)
|
94
|
+
assert_true (0..p.count-3).all?{|i|p[i].angle_to(p[i+1],p[i+2]).abs < pi/53}
|
95
|
+
# 4d/o
|
96
|
+
p = bc([1,0,2,-1],[3,2,5,4],[7,9,8,6],[13,17,12,15],[20,21,32,25]).points(tolerance:pi/53)
|
97
|
+
assert_true (0..p.count-3).all?{|i|p[i].angle_to(p[i+1],p[i+2]).abs < pi/53}
|
98
|
+
# 5d/o
|
99
|
+
p = bc([1,0,2,-1,3],[3,2,5,4,6],[7,9,8,6,5],[13,17,12,15,14],[20,21,32,25,23],[34,33,47,39,52]).points(tolerance:pi/53)
|
100
|
+
assert_true (0..p.count-3).all?{|i|p[i].angle_to(p[i+1],p[i+2]).abs < pi/53}
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# test functionality of NPoint module
|
2
|
+
require 'test/unit'
|
3
|
+
require 'bezier_curve/n_point'
|
4
|
+
|
5
|
+
class TestNPoint < Test::Unit::TestCase
|
6
|
+
def test_to_np
|
7
|
+
np = [9,8,7].to_np
|
8
|
+
|
9
|
+
assert_kind_of NPoint, np, "Array#to_np should return an NPoint"
|
10
|
+
assert_same np.to_np, np, "NPoint#to_np should return self"
|
11
|
+
end
|
12
|
+
def test_x
|
13
|
+
np = [9,8,7].to_np
|
14
|
+
assert_equal 9, np.x
|
15
|
+
end
|
16
|
+
def test_y
|
17
|
+
np = [9,8,7].to_np
|
18
|
+
assert_equal 8, np.y
|
19
|
+
end
|
20
|
+
def test_z
|
21
|
+
np = [9,8,7].to_np
|
22
|
+
assert_equal 7, np.z
|
23
|
+
end
|
24
|
+
def test_to
|
25
|
+
a, b = [1,1,1].to_np, [5,5,5].to_np
|
26
|
+
|
27
|
+
assert_equal [3,3,3], a.to(b,0.5)
|
28
|
+
assert_equal [-1,-1,-1], a.to(b,-0.5)
|
29
|
+
assert_equal [7,7,7], a.to(b,1.5)
|
30
|
+
end
|
31
|
+
def test_dist_from
|
32
|
+
# various numbers of dimensions
|
33
|
+
assert_equal 3, [3].to_np.dist_from([6])
|
34
|
+
assert_equal (3**2*2)**0.5, [3,3].to_np.dist_from([6,6])
|
35
|
+
assert_equal (3**2*3)**0.5, [3,3,3].to_np.dist_from([6,6,6])
|
36
|
+
assert_equal (3**2*4)**0.5, [3,3,3,3].to_np.dist_from([6,6,6,6])
|
37
|
+
assert_equal (3**2*5)**0.5, [3,3,3,3,3].to_np.dist_from([6,6,6,6,6])
|
38
|
+
|
39
|
+
# across the origin
|
40
|
+
assert_in_delta 8**0.5, [1,1].to_np.dist_from([-1,-1]), 0.00001
|
41
|
+
end
|
42
|
+
def test_angle_to
|
43
|
+
pi = Math::PI
|
44
|
+
pi_eps = (pi.next_float-pi)*16
|
45
|
+
assert_in_epsilon pi/2, [1,0].to_np.angle_to([0,0],[0,1]), pi_eps
|
46
|
+
assert_in_epsilon pi, [1,1].to_np.angle_to([0,0],[1,1]), pi_eps
|
47
|
+
assert_in_epsilon 0, [1,1].to_np.angle_to([0,0],[-1,-1]), pi_eps
|
48
|
+
assert_in_epsilon pi/4, [-1,0].to_np.angle_to([0,0],[1,1]), pi_eps
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
metadata
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bezier_curve
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.8.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mark Hubbart
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-06-18 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: A bézier curve library for Ruby, supporting n-dimensional, nth-degree
|
14
|
+
curves
|
15
|
+
email: mark.hubbart@gmail.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- README.md
|
21
|
+
- Rakefile
|
22
|
+
- lib/bezier_curve.rb
|
23
|
+
- lib/bezier_curve/n_point.rb
|
24
|
+
- lib/bezier_curve/version.rb
|
25
|
+
- test/test_bezier_curve.rb
|
26
|
+
- test/test_n_point.rb
|
27
|
+
homepage: https://github.com/marcuserronius/bezier_curve
|
28
|
+
licenses:
|
29
|
+
- MIT
|
30
|
+
metadata: {}
|
31
|
+
post_install_message:
|
32
|
+
rdoc_options: []
|
33
|
+
require_paths:
|
34
|
+
- lib
|
35
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
requirements: []
|
46
|
+
rubyforge_project:
|
47
|
+
rubygems_version: 2.4.5
|
48
|
+
signing_key:
|
49
|
+
specification_version: 4
|
50
|
+
summary: N-dimensional, nth-degree bézier curves
|
51
|
+
test_files: []
|