class Draught::ArcBuilder

Constants

CIRCLE_RADIANS
LARGEST_SEGMENT_RADIANS

Largest arc segment representable by a single Cubic Bézier is 90º There's enough jitter in floating point maths that we round the result to 12 d.p. which means we avoid requiring two segments to represent an arc of 90.000000000000000001º

Attributes

radians[R]
radius[R]
starting_angle[R]

Public Class Methods

deg_to_rad(degrees) click to toggle source
# File lib/draught/arc_builder.rb, line 19
def self.deg_to_rad(degrees)
  degrees * (Math::PI / 180)
end
degrees(args = {}) click to toggle source
# File lib/draught/arc_builder.rb, line 28
def self.degrees(args = {})
  new_args = {radius: args[:radius]}
  new_args[:radians] = deg_to_rad(args.fetch(:angle))
  new_args[:starting_angle] = deg_to_rad(args.fetch(:starting_angle, 0))
  new(new_args)
end
new(args = {}) click to toggle source
# File lib/draught/arc_builder.rb, line 35
def initialize(args = {})
  @radius = args.fetch(:radius)
  @starting_angle = args.fetch(:starting_angle, 0)
  @radians = args.fetch(:radians)
end
radians(args = {}) click to toggle source
# File lib/draught/arc_builder.rb, line 23
def self.radians(args = {})
  new_args = args.merge(radians: args[:angle])
  new(new_args)
end

Public Instance Methods

curve() click to toggle source
# File lib/draught/arc_builder.rb, line 49
def curve
  @curve ||= Curve.new({
    point: segments.last.end_point,
    cubic_beziers: segments.map { |s| s.cubic_bezier }
  }).transform(transformer)
end
path() click to toggle source
# File lib/draught/arc_builder.rb, line 41
def path
  @path ||= Path.new([start_point, curve])
end
start_point() click to toggle source
# File lib/draught/arc_builder.rb, line 45
def start_point
  @start_point ||= untranslated_start_point.transform(transformer)
end

Private Instance Methods

negative?() click to toggle source
# File lib/draught/arc_builder.rb, line 92
def negative?
  !positive?
end
positive?() click to toggle source
# File lib/draught/arc_builder.rb, line 96
def positive?
  radians >= 0
end
positive_radians() click to toggle source
# File lib/draught/arc_builder.rb, line 76
def positive_radians
  radians.abs
end
segments() click to toggle source
# File lib/draught/arc_builder.rb, line 62
def segments
  @segments ||= begin
    remaining_angle = positive_radians
    start = starting_angle
    segments = []
    while remaining_angle > LARGEST_SEGMENT_RADIANS
      remaining_angle = remaining_angle - LARGEST_SEGMENT_RADIANS
      segments << SegmentBuilder.new(LARGEST_SEGMENT_RADIANS, start, radius)
      start = positive_radians + starting_angle - remaining_angle
    end
    segments << SegmentBuilder.new(remaining_angle, start, radius)
  end
end
transformer() click to toggle source
# File lib/draught/arc_builder.rb, line 80
def transformer
  @transformer ||= begin
    transformations = [translation_transformer]
    transformations << Transformations.x_axis_reflect if negative?
    Transformations::Composer.compose(*transformations)
  end
end
translation_transformer() click to toggle source
# File lib/draught/arc_builder.rb, line 88
def translation_transformer
  @translation_transformer ||= Vector.translation_to_zero(untranslated_start_point).to_transform
end
untranslated_start_point() click to toggle source
# File lib/draught/arc_builder.rb, line 58
def untranslated_start_point
  segments.first.first_point
end