Class: Curve

Inherits:
Array
  • Object
show all
Defined in:
lib/curve.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(cr) ⇒ Curve

Returns a new instance of Curve.



4
5
6
# File 'lib/curve.rb', line 4

def initialize(cr)
  @cr = cr
end

Instance Attribute Details

#crObject

Returns the value of attribute cr.



2
3
4
# File 'lib/curve.rb', line 2

def cr
  @cr
end

Instance Method Details

#debugObject



43
44
45
46
47
48
49
50
51
52
53
# File 'lib/curve.rb', line 43

def debug
  each do |point|
    cr.circle(point.x, point.y, 3)
    cr.fill
    cr.line_width = 1
    # cr.move_to(*point.trailing_point.map {|n| n + 2})
    cr.move_to(*point.trailing_point)
    cr.line_to(*point.leading_point)
    cr.stroke
  end
end

#drawObject



8
9
10
# File 'lib/curve.rb', line 8

def draw
  draw_control_points(self)
end

#draw_control_points(control_points) ⇒ Object



12
13
14
15
16
17
18
19
20
# File 'lib/curve.rb', line 12

def draw_control_points(control_points)
  cr.move_to(*control_points.first.point)
  cx1, cy1 = control_points.first.leading_point
  control_points[1..-1].each do |point|
    cx2, cy2 = point.trailing_point
    cr.curve_to(cx1, cy1, cx2, cy2, point.x, point.y)
    cx1, cy1 = point.leading_point
  end
end

#draw_outlineObject



33
34
35
36
37
38
39
40
41
# File 'lib/curve.rb', line 33

def draw_outline
  there = offset_line(-2, false)
  there.first.d1 = 5
  back = offset_line(2, true)
  back.last.d2 = 2
  draw_control_points(there + back + [there.first])
  cr.stroke
  # cr.fill
end

#logarithmic_spiral(center_x, center_y, theta_one, delta_theta, a, b) ⇒ Object



80
81
82
83
84
# File 'lib/curve.rb', line 80

def logarithmic_spiral(center_x, center_y, theta_one, delta_theta, a, b)
  spiral(center_x, center_y, theta_one, delta_theta, Math.atan(1/b)) do |theta|
    (a*Math::E)**(b*theta)
  end
end

#offset_line(distance, flip) ⇒ Object



22
23
24
25
26
27
28
29
30
31
# File 'lib/curve.rb', line 22

def offset_line(distance, flip)
  offset_line = self.map do |p|
    p.move_away_from_line(distance)
  end
  offset_line.each_with_index do |p, i|
    p.d1 *= (p.distance(offset_line[i-1])/self[i].distance(self[i-1])) * 1.1 unless i == 0
    p.d2 *= (p.distance(offset_line[i+1])/self[i].distance(self[i+1])) * 1.1 unless i + 1 == length
  end
  flip ? offset_line.map(&:flip).reverse : offset_line
end

#point(x, y, theta, d1, d2 = d1) ⇒ Object



55
56
57
58
# File 'lib/curve.rb', line 55

def point(x, y, theta, d1, d2=d1)
  p [x, y, theta, d1, d2]
  push(ControlPoint.new(x, y, theta, d1, d2))
end

#spiral(center_x, center_y, theta_one, delta_theta, phi, &algorithm) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/curve.rb', line 60

def spiral(center_x, center_y, theta_one, delta_theta, phi, &algorithm)
  control_points_per_rotation = 8
  control_points = (control_points_per_rotation * delta_theta.abs / Math::PI / 2).to_i
  radians_between_points = delta_theta / (control_points-1)
  (0...control_points).each do |i|
    theta = theta_one + radians_between_points * i
    radius = algorithm.call(theta)
    x, y = center_x + radius * Math.cos(theta), center_y + radius * Math.sin(theta)
    tangent = theta + phi
    influence = radius * 0.285 * (delta_theta / delta_theta.abs)
    if i == control_points - 1
      point(x, y, tangent, influence, influence * 2)
    elsif i == 0
      point(x, y, tangent, influence * 3, influence)
    else
      point(x, y, tangent, influence)
    end
  end
end