Class: VectorBeWinding::Segment
- Defined in:
- lib/vector_be_winding/segment.rb
Instance Attribute Summary collapse
-
#control ⇒ Object
readonly
Returns the value of attribute control.
-
#control_1 ⇒ Object
readonly
Returns the value of attribute control_1.
-
#direction ⇒ Object
readonly
Returns the value of attribute direction.
-
#end_point ⇒ Object
readonly
Returns the value of attribute end_point.
-
#large_arc ⇒ Object
readonly
Returns the value of attribute large_arc.
-
#radius ⇒ Object
readonly
Returns the value of attribute radius.
-
#rotation ⇒ Object
readonly
Returns the value of attribute rotation.
-
#start_point ⇒ Object
readonly
Returns the value of attribute start_point.
-
#sweep ⇒ Object
readonly
Returns the value of attribute sweep.
Instance Method Summary collapse
-
#area(p) ⇒ Object
Calculate direction area of the triangle (p, start_point, end_point) It must be positive iff the three points forms clockwise order.
- #bounding_rect ⇒ Object
- #control_2 ⇒ Object
- #create_vector(x, y, absolute) ⇒ Object
-
#initialize(direction, start_point, end_point_hint, prev_segment = nil) ⇒ Segment
constructor
A new instance of Segment.
- #reverse ⇒ Object
- #reverse_dir ⇒ Object
Methods inherited from Shape
#containingness, #contains?, #intersectedness, #intersects?
Constructor Details
#initialize(direction, start_point, end_point_hint, prev_segment = nil) ⇒ Segment
Returns a new instance of Segment.
7 8 9 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 |
# File 'lib/vector_be_winding/segment.rb', line 7 def initialize(direction, start_point, end_point_hint, prev_segment = nil) @direction = direction @start_point = start_point @end_point = if @direction.kind_of?(::Savage::Directions::PointTarget) create_vector(@direction.target.x, @direction.target.y, @direction.absolute?) elsif @direction.kind_of?(::Savage::Directions::HorizontalTo) create_vector(@direction.target, nil, @direction.absolute?) elsif @direction.kind_of?(::Savage::Directions::VerticalTo) create_vector(nil, @direction.target, @direction.absolute?) elsif @direction.kind_of?(::Savage::Directions::ClosePath) end_point_hint else raise "Unknown direction: #{@direction}" end if @direction.instance_of?(::Savage::Directions::QuadraticCurveTo) control = @direction.control || prev_segment.control&.reflect(start_point) || start_point @control = create_vector(control.x, control.y, @direction.absolute?) elsif @direction.instance_of?(::Savage::Directions::CubicCurveTo) control = @direction.control control_1 = @direction.control_1 || prev_segment.control&.reflect(start_point) || start_point @control = create_vector(control.x, control.y, @direction.absolute?) @control_1 = create_vector(control_1.x, control_1.y, @direction.absolute?) elsif @direction.instance_of?(::Savage::Directions::ArcTo) @radius = @direction.radius @rotation = @direction.rotation @large_arc = @direction.large_arc @sweep = @direction.sweep end end |
Instance Attribute Details
#control ⇒ Object (readonly)
Returns the value of attribute control.
3 4 5 |
# File 'lib/vector_be_winding/segment.rb', line 3 def control @control end |
#control_1 ⇒ Object (readonly)
Returns the value of attribute control_1.
3 4 5 |
# File 'lib/vector_be_winding/segment.rb', line 3 def control_1 @control_1 end |
#direction ⇒ Object (readonly)
Returns the value of attribute direction.
3 4 5 |
# File 'lib/vector_be_winding/segment.rb', line 3 def direction @direction end |
#end_point ⇒ Object (readonly)
Returns the value of attribute end_point.
3 4 5 |
# File 'lib/vector_be_winding/segment.rb', line 3 def end_point @end_point end |
#large_arc ⇒ Object (readonly)
Returns the value of attribute large_arc.
3 4 5 |
# File 'lib/vector_be_winding/segment.rb', line 3 def large_arc @large_arc end |
#radius ⇒ Object (readonly)
Returns the value of attribute radius.
3 4 5 |
# File 'lib/vector_be_winding/segment.rb', line 3 def radius @radius end |
#rotation ⇒ Object (readonly)
Returns the value of attribute rotation.
3 4 5 |
# File 'lib/vector_be_winding/segment.rb', line 3 def rotation @rotation end |
#start_point ⇒ Object (readonly)
Returns the value of attribute start_point.
3 4 5 |
# File 'lib/vector_be_winding/segment.rb', line 3 def start_point @start_point end |
#sweep ⇒ Object (readonly)
Returns the value of attribute sweep.
3 4 5 |
# File 'lib/vector_be_winding/segment.rb', line 3 def sweep @sweep end |
Instance Method Details
#area(p) ⇒ Object
Calculate direction area of the triangle (p, start_point, end_point) It must be positive iff the three points forms clockwise order.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/vector_be_winding/segment.rb', line 62 def area(p) if @direction.kind_of?(::Savage::Directions::QuadraticCurveTo) # Approximate with triangle (start_point - p).cross(control - start_point) + (control - p).cross(end_point - control) elsif @direction.kind_of?(::Savage::Directions::CubicCurveTo) # Approximate with quadrangle (start_point - p).cross(control_1 - start_point) + (control_1 - p).cross(control_2 - control_1) + (control_2 - p).cross(end_point - control_2) elsif @direction.kind_of?(::Savage::Directions::ArcTo) # Very rough approximation. TODO: Be more precise (start_point - p).cross(end_point - start_point) / 2.0 + (sweep ? 1 : -1) else (start_point - p).cross(end_point - start_point) / 2.0 end end |
#bounding_rect ⇒ Object
55 56 57 58 |
# File 'lib/vector_be_winding/segment.rb', line 55 def bounding_rect @bounding_rect ||= Rect.new(start_point.x, start_point.y, end_point.x, end_point.y) end |
#control_2 ⇒ Object
43 44 45 |
# File 'lib/vector_be_winding/segment.rb', line 43 def control_2 control end |
#create_vector(x, y, absolute) ⇒ Object
47 48 49 50 51 52 53 |
# File 'lib/vector_be_winding/segment.rb', line 47 def create_vector(x, y, absolute) if absolute Vector.new(x || start_point.x, y || start_point.y) else start_point + Vector.new(x || 0, y || 0) end end |
#reverse ⇒ Object
80 81 82 |
# File 'lib/vector_be_winding/segment.rb', line 80 def reverse Segment.new(reverse_dir, end_point, start_point) end |
#reverse_dir ⇒ Object
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/vector_be_winding/segment.rb', line 84 def reverse_dir case @direction.command_code.upcase when 'Z', 'L' ::Savage::Directions::LineTo.new(start_point.x, start_point.y, true) when 'M' nil # Unable to reverse when 'H' ::Savage::Directions::HorizontalTo.new(start_point.x, true) when 'V' ::Savage::Directions::VerticalTo.new(start_point.y, true) when 'Q', 'T' ::Savage::Directions::QuadraticCurveTo.new( control.x, control.y, start_point.x, start_point.y, true) when 'C', 'S' ::Savage::Directions::CubicCurveTo.new( control.x, control.y, control_1.x, control_1.y, start_point.x, start_point.y, true) when 'A' ::Savage::Directions::ArcTo.new( radius.x, radius.y, rotation, large_arc, !sweep, start_point.x, start_point.y, true) else raise "Unknown direction: #{@direction}" end end |