class DYI::Shape::Path::ArcCommand
Attributes
rotation[R]
rx[R]
ry[R]
Public Class Methods
new(relative, preceding_command, rx, ry, rotation, is_large_arc, is_clockwise, point)
click to toggle source
# File lib/dyi/shape/path.rb, line 945 def initialize(relative, preceding_command, rx, ry, rotation, is_large_arc, is_clockwise, point) raise ArgumentError, 'preceding_command is nil' if preceding_command.nil? @relative = relative @preceding_command = preceding_command @point = Coordinate.new(point) @rotation = rotation @is_large_arc = is_large_arc @is_clockwise = is_clockwise @rx = Length.new(rx).abs @ry = Length.new(ry).abs l = (modified_mid_point.x.to_f / @rx.to_f) ** 2 + (modified_mid_point.y.to_f / @ry.to_f) ** 2 if 1 < l @rx *= Math.sqrt(l) @ry *= Math.sqrt(l) end end
Private Class Methods
commands(relative, preceding_command, *args)
click to toggle source
# File lib/dyi/shape/path.rb, line 1060 def commands(relative, preceding_command, *args) raise ArgumentError, "number of arguments must be a multipule of 6" if args.size % 6 != 0 cmd = preceding_command args.each_slice(6).inject([]) do |cmds, ars| if ars[0].zero? || ars[1].zero? cmds << (cmd = LineCommand.new(relative, cmd, ars.last)) else cmds << (cmd = new(relative, cmd, *ars)) end end end
Public Instance Methods
center_point()
click to toggle source
# File lib/dyi/shape/path.rb, line 1009 def center_point st_pt = relative? ? Coordinate::ZERO : preceding_point Matrix.rotate(rotation).transform(modified_center_point) + (st_pt + point) * 0.5 end
clockwise?()
click to toggle source
# File lib/dyi/shape/path.rb, line 966 def clockwise? @is_clockwise end
instructions_char()
click to toggle source
# File lib/dyi/shape/path.rb, line 1005 def instructions_char relative? ? 'a' : 'A' end
large_arc?()
click to toggle source
# File lib/dyi/shape/path.rb, line 962 def large_arc? @is_large_arc end
to_compatible_commands(preceding_command)
click to toggle source
# File lib/dyi/shape/path.rb, line 970 def to_compatible_commands(preceding_command) return LineCommand.new(relative?, preceding_command, point) if rx.zero? || ry.zero? division_count = (center_angle / 30.0).ceil division_angle = center_angle / division_count * (clockwise? ? 1 : -1) current_point = start_angle_point compat_commands = [] division_count.times do |i| end_point = if i == division_count - 1 end_angle_point else Matrix.rotate(division_angle).transform(current_point) end control_point1 = control_point_of_curve(current_point, division_angle, true) control_point2 = control_point_of_curve(end_point, division_angle, false) path_point = (i == division_count - 1) ? point : transform_orginal_shape(end_point) if relative? control_point1 += preceding_point control_point2 += preceding_point path_point += preceding_point end preceding_command = CurveCommand.absolute_commands(preceding_command, control_point1, control_point2, path_point).first compat_commands << preceding_command current_point = end_point end compat_commands end
to_concise_syntax_fragments()
click to toggle source
# File lib/dyi/shape/path.rb, line 1000 def to_concise_syntax_fragments [used_same_command? ? rx.to_s : instructions_char + rx.to_s, ry, rotation, large_arc? ? 1 : 0, clockwise? ? 1 : 0, point.to_s] end
Private Instance Methods
center_angle()
click to toggle source
# File lib/dyi/shape/path.rb, line 1039 def center_angle angle = DYI::Util.acos(start_angle_point.x.to_f * end_angle_point.x.to_f + start_angle_point.y.to_f * end_angle_point.y.to_f) large_arc? ? 360.0 - angle : angle end
control_point_of_curve(point, center_angle, is_start_point)
click to toggle source
# File lib/dyi/shape/path.rb, line 1053 def control_point_of_curve(point, center_angle, is_start_point) handle_length = DYI::Util.tan(center_angle / 4.0) * 4.0 / 3.0 handle = is_start_point ? handle_length : -handle_length transform_matrix.transform(Matrix.new(1, handle, -handle, 1, 0, 0).transform(point)) end
end_angle_point()
click to toggle source
# File lib/dyi/shape/path.rb, line 1034 def end_angle_point Coordinate.new((-modified_mid_point.x - modified_center_point.x) / rx, (-modified_mid_point.y - modified_center_point.y) / ry) end
modified_center_point()
click to toggle source
# File lib/dyi/shape/path.rb, line 1021 def modified_center_point pt = modified_mid_point Coordinate.new(pt.y * (rx / ry), -pt.x * (ry / rx)) * Math.sqrt(((rx.to_f * ry.to_f) ** 2 - (rx.to_f * pt.y.to_f) ** 2 - (ry.to_f * pt.x.to_f) ** 2) / ((rx.to_f * pt.y.to_f) ** 2 + (ry.to_f * pt.x.to_f) ** 2)) * ((large_arc? == clockwise?) ? -1 : 1) end
modified_mid_point()
click to toggle source
# File lib/dyi/shape/path.rb, line 1016 def modified_mid_point st_pt = relative? ? Coordinate::ZERO : preceding_point Matrix.rotate(-rotation).transform((st_pt - point) * 0.5) end
start_angle_point()
click to toggle source
# File lib/dyi/shape/path.rb, line 1029 def start_angle_point Coordinate.new((modified_mid_point.x - modified_center_point.x) / rx, (modified_mid_point.y - modified_center_point.y) / ry) end
transform_matrix()
click to toggle source
# File lib/dyi/shape/path.rb, line 1045 def transform_matrix Matrix.translate(center_point.x.to_f, center_point.y.to_f).rotate(rotation).scale(rx.to_f, ry.to_f) end
transform_orginal_shape(modified_point)
click to toggle source
# File lib/dyi/shape/path.rb, line 1049 def transform_orginal_shape(modified_point) transform_matrix.transform(modified_point) end