Class: VectorBeWinding::SubPath

Inherits:
Shape
  • Object
show all
Includes:
SpatialTree
Defined in:
lib/vector_be_winding/sub_path.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from SpatialTree

#children, #depth, #dump, #each, #insert_to_tree

Methods inherited from Shape

#containingness, #contains?, #intersectedness, #intersects?

Instance Attribute Details

#segmentsObject (readonly)

Returns the value of attribute segments.



5
6
7
# File 'lib/vector_be_winding/sub_path.rb', line 5

def segments
  @segments
end

#start_pointObject (readonly)

Returns the value of attribute start_point.



5
6
7
# File 'lib/vector_be_winding/sub_path.rb', line 5

def start_point
  @start_point
end

#svg_subpathObject (readonly)

Returns the value of attribute svg_subpath.



5
6
7
# File 'lib/vector_be_winding/sub_path.rb', line 5

def svg_subpath
  @svg_subpath
end

Class Method Details

.with_segments(segments) ⇒ Object



7
8
9
# 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) ⇒ Object



21
22
23
24
25
# 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) ⇒ Object



27
28
29
# 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

Instance Method Details

#areaObject

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



63
64
65
# 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) ⇒ Object



71
72
73
74
75
76
77
78
79
# 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_rectObject



50
51
52
53
54
55
56
57
58
59
# 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) ⇒ Object

Suppose all segments are connected



12
13
14
15
16
17
18
19
# 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) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# 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

#inspectObject



85
86
87
# File 'lib/vector_be_winding/sub_path.rb', line 85

def inspect
  "#<SubPath \"#{svg_subpath.to_command}\">"
end

#is_windingObject



81
82
83
# File 'lib/vector_be_winding/sub_path.rb', line 81

def is_winding
  children.all? { |c| c.is_winding && c.area * area < 0}
end

#reverseObject



67
68
69
# File 'lib/vector_be_winding/sub_path.rb', line 67

def reverse
  SubPath.with_segments(segments.map(&:reverse).reverse)
end

#to_commandObject



89
90
91
# File 'lib/vector_be_winding/sub_path.rb', line 89

def to_command
  @svg_subpath.to_command
end