Class: VectorSalad::Interpolate

Inherits:
Object
  • Object
show all
Defined in:
lib/vector_salad/interpolate.rb

Constant Summary collapse

TOLERANCE =

TOLERANCE = 10 # anything below 50 is roughly good-looking

0.2

Instance Method Summary collapse

Constructor Details

#initializeInterpolate

anything below 50 is roughly good-looking



11
12
13
# File 'lib/vector_salad/interpolate.rb', line 11

def initialize
  @nodes = []
end

Instance Method Details

#casteljau(curve) ⇒ Object



15
16
17
18
19
20
21
22
23
# File 'lib/vector_salad/interpolate.rb', line 15

def casteljau(curve)
  if flat_enough? curve
    @nodes << curve[3]
  else
    halves = subdivide(curve)
    casteljau(halves[0])
    casteljau(halves[1])
  end
end

#flat_enough?(curve) ⇒ Boolean

Early stopping function for the Casteljau algorithm. Is the curve flat enough for visual purposes?

Returns:

  • (Boolean)


27
28
29
30
31
32
33
34
# File 'lib/vector_salad/interpolate.rb', line 27

def flat_enough?(curve)
  ax = (3.0*curve[1][0] - 2.0*curve[0][0] - curve[3][0])**2
  ay = (3.0*curve[1][1] - 2.0*curve[0][1] - curve[3][1])**2
  bx = (3.0*curve[2][0] - curve[0][0] - 2.0*curve[3][0])**2
  by = (3.0*curve[2][1] - curve[0][1] - 2.0*curve[3][1])**2

  [ax, bx].max + [ay, by].max <= TOLERANCE
end

#midpoint(p, q) ⇒ Object



36
37
38
# File 'lib/vector_salad/interpolate.rb', line 36

def midpoint(p, q)
  [(p[0] + q[0]) / 2.0, (p[1] + q[1]) / 2.0]
end

#midpoints(points) ⇒ Object



40
41
42
43
44
45
46
# File 'lib/vector_salad/interpolate.rb', line 40

def midpoints(points)
  midpoints = Array.new(points.length - 1)
  midpoints.each_index do |i|
    midpoints[i] = midpoint(points[i], points[i+1])
  end
  midpoints
end

#subdivide(curve) ⇒ Object



48
49
50
51
52
53
54
55
# File 'lib/vector_salad/interpolate.rb', line 48

def subdivide(curve)
  first = midpoints(curve)
  second = midpoints(first)
  third = midpoints(second)

  [[curve[0], first[0], second[0], third[0]],
  [third[0], second[1], first[2], curve[3]]]
end