Class: Prawn::SVG::Calculators::PathLength
- Inherits:
-
Object
- Object
- Prawn::SVG::Calculators::PathLength
- Defined in:
- lib/prawn/svg/calculators/path_length.rb
Defined Under Namespace
Classes: Segment
Constant Summary collapse
- SUBDIVISION_TOLERANCE =
0.01- LOOKUP_TABLE_STEPS =
64
Instance Attribute Summary collapse
-
#total_length ⇒ Object
readonly
Returns the value of attribute total_length.
Instance Method Summary collapse
-
#initialize(commands) ⇒ PathLength
constructor
A new instance of PathLength.
- #point_at(distance) ⇒ Object
Constructor Details
#initialize(commands) ⇒ PathLength
Returns a new instance of PathLength.
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/prawn/svg/calculators/path_length.rb', line 10 def initialize(commands) @segments = [] @total_length = 0.0 current_point = nil subpath_start = nil commands.each do |command| case command when Prawn::SVG::Pathable::Move current_point = command.destination subpath_start = current_point when Prawn::SVG::Pathable::Close if current_point && subpath_start && current_point != subpath_start add_line_segment(current_point, subpath_start) current_point = subpath_start end when Prawn::SVG::Pathable::Line if current_point add_line_segment(current_point, command.destination) current_point = command.destination end when Prawn::SVG::Pathable::Curve if current_point add_curve_segment(current_point, command.point1, command.point2, command.destination) current_point = command.destination end end end end |
Instance Attribute Details
#total_length ⇒ Object (readonly)
Returns the value of attribute total_length.
8 9 10 |
# File 'lib/prawn/svg/calculators/path_length.rb', line 8 def total_length @total_length end |
Instance Method Details
#point_at(distance) ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/prawn/svg/calculators/path_length.rb', line 44 def point_at(distance) return nil if distance.negative? || distance > @total_length || @segments.empty? @segments.each do |segment| start_distance = segment.cumulative_length - segment.segment_length next unless distance <= segment.cumulative_length local_distance = distance - start_distance case segment.type when :line t = segment.segment_length.positive? ? local_distance / segment.segment_length : 0.0 x = segment.start_point[0] + (t * (segment.end_point[0] - segment.start_point[0])) y = segment.start_point[1] + (t * (segment.end_point[1] - segment.start_point[1])) dx = segment.end_point[0] - segment.start_point[0] dy = segment.end_point[1] - segment.start_point[1] angle = Math.atan2(dy, dx) * 180.0 / Math::PI return [x, y, angle] when :curve t = find_t_for_distance(segment, local_distance) p0, p1, p2, p3 = segment.start_point, *segment.control_points, segment.end_point x, y = evaluate_cubic(p0, p1, p2, p3, t) dx, dy = evaluate_cubic_derivative(p0, p1, p2, p3, t) angle = Math.atan2(dy, dx) * 180.0 / Math::PI return [x, y, angle] end end # Exactly at the end segment = @segments.last [segment.end_point[0], segment.end_point[1], end_angle(segment)] end |