class VectorBeWinding::SubPath

Attributes

segments[R]
start_point[R]
svg_subpath[R]

Public Class Methods

with_segments(segments) click to toggle source
# File lib/vector_be_winding/sub_path.rb, line 7
def self.with_segments(segments)
  SubPath.new.init_with_segment(segments)
end
with_string(path_string) click to toggle source
# File lib/vector_be_winding/sub_path.rb, line 21
def self.with_string(path_string)
  path = Savage::Parser.parse(path_string)
  raise "No subpaths: ${path_string}" if path.subpaths.empty?
  SubPath.with_svg(path.subpaths.last)
end
with_svg(svg_subpath, start_point = nil) click to toggle source
# File lib/vector_be_winding/sub_path.rb, line 27
def self.with_svg(svg_subpath, start_point = nil)
  SubPath.new.init_with_svg(svg_subpath, start_point)
end

Public Instance Methods

area() click to toggle source

Calculate direction area of this path. It's positive iff the path forms clockwise.

# File lib/vector_be_winding/sub_path.rb, line 63
def area()
  segments.map { |seg| seg.area(start_point) }.reduce(:+)
end
be_winding(sign = 1) click to toggle source
# File lib/vector_be_winding/sub_path.rb, line 71
def be_winding(sign = 1)
  wound = if area * sign >= 0
            SubPath.with_svg(svg_subpath)
          else
            reverse
          end
  wound.children.concat(children.map { |c| c.be_winding(-sign) })
  wound
end
bounding_rect() click to toggle source
# File lib/vector_be_winding/sub_path.rb, line 50
def bounding_rect
  unless @bounding_rect
    rect = Rect.with_vectors(start_point, start_point)
    segments.each { |segment|
      rect |= segment.bounding_rect
    }
    @bounding_rect = rect
  end
  @bounding_rect
end
init_with_segment(segments) click to toggle source

Suppose all segments are connected

# File lib/vector_be_winding/sub_path.rb, line 12
def init_with_segment(segments)
  raise "No segments" if segments.empty?
  @segments = segments
  @start_point = segments.first.start_point
  @svg_subpath = Savage::SubPath.new(start_point.x, start_point.y)
  @svg_subpath.directions.concat(segments.map(&:direction))
  self
end
init_with_svg(svg_subpath, start_point = nil) click to toggle source
# File lib/vector_be_winding/sub_path.rb, line 31
def init_with_svg(svg_subpath, start_point = nil)
  start_point ||= Vector.new(0,0)
  @svg_subpath = svg_subpath
  @segments = []

  point = start_point
  @svg_subpath.directions.each { |dir|
    segment = Segment.new(dir, point, start_point, segments.last)
    point = segment.end_point
    if segment.direction.kind_of?(Savage::Directions::MoveTo)
      start_point = point
    else
      @segments << segment
    end
  }
  @start_point = start_point
  self
end
inspect() click to toggle source
# File lib/vector_be_winding/sub_path.rb, line 85
def inspect
  "#<SubPath \"#{svg_subpath.to_command}\">"
end
is_winding() click to toggle source
# File lib/vector_be_winding/sub_path.rb, line 81
def is_winding
  children.all? { |c| c.is_winding && c.area * area < 0}
end
reverse() click to toggle source
# File lib/vector_be_winding/sub_path.rb, line 67
def reverse
  SubPath.with_segments(segments.map(&:reverse).reverse)
end
to_command() click to toggle source
# File lib/vector_be_winding/sub_path.rb, line 89
def to_command
  @svg_subpath.to_command
end