Class: Ruby2D::Polygon
- Inherits:
-
Object
- Object
- Ruby2D::Polygon
- Includes:
- Renderable
- Defined in:
- lib/ruby2d/polygon.rb
Overview
A closed polygon defined by N vertices (N >= 3), filled or stroked.
Constant Summary
Constants included from Interactive
Interactive::OBJECT_EVENTS, Interactive::OBJECT_EVENT_FILTER_PREDICATES
Instance Attribute Summary collapse
-
#fill ⇒ Object
Returns the value of attribute fill.
-
#rotate ⇒ Object
Returns the value of attribute rotate.
-
#stroke_color ⇒ Object
(also: #stroke_colour)
Returns the value of attribute stroke_color.
-
#stroke_width ⇒ Object
Returns the value of attribute stroke_width.
Attributes included from Renderable
#color, #padding_bottom, #padding_left, #padding_right, #padding_top, #visible, #x_align, #y_align, #z
Class Method Summary collapse
-
.render(points:, rotate: 0, rx: nil, ry: nil, color: nil, colour: nil, opacity: nil, fill: true, stroke_width: 0, stroke_color: nil, stroke_colour: nil) ⇒ Object
Render a polygon without creating an instance.
Instance Method Summary collapse
-
#color=(color) ⇒ Object
Set the fill color (single or per-vertex array).
-
#contains?(x, y) ⇒ Boolean
Test whether (x, y) lies inside the polygon, using the even-odd ray-cast rule (shared by every filled polygonal shape — see
_point_in_polygon?). - #height ⇒ Object
-
#initialize(points:, z: 0, rotate: 0, rx: nil, ry: nil, color: nil, colour: nil, opacity: nil, fill: true, stroke_width: 0, stroke_color: nil, stroke_colour: nil, add: true, visible: true) ⇒ Polygon
constructor
Create a polygon points is an array of [x, y] pairs with N >= 3 vertices.
-
#points ⇒ Object
The vertices as an array of [x, y] pairs.
-
#rx ⇒ Object
Get the rotation center x coordinate.
-
#rx=(val) ⇒ Object
Set the rotation center x coordinate.
-
#ry ⇒ Object
Get the rotation center y coordinate.
-
#ry=(val) ⇒ Object
Set the rotation center y coordinate.
-
#vertex_count ⇒ Object
Number of vertices.
-
#width ⇒ Object
Bounding-box width and height (extent across all vertices).
-
#x ⇒ Object
Centroid x (average of vertex x coordinates).
-
#x=(new_x) ⇒ Object
Set the centroid x coordinate, translating all vertices.
-
#y ⇒ Object
Centroid y (average of vertex y coordinates).
-
#y=(new_y) ⇒ Object
Set the centroid y coordinate, translating all vertices.
Methods included from Renderable
#_alignment_anchor_dx, #_alignment_anchor_dy, #_apply_padding, #_extract_alignment, #_point_in_polygon?, #_point_on_segment?, #_require_numeric_position, #_resolve_alignment, #_unrotate, #_validate_dimensions, #add, #colour=, flatten_color, flatten_per_vertex, flatten_points, flatten_resolved_color, #hide, #opacity, #opacity=, #padding=, #remove, resolve_color_or_default, resolve_single_color, #show
Methods included from Interactive
#_fire_event, #interactive?, #off, #on
Constructor Details
#initialize(points:, z: 0, rotate: 0, rx: nil, ry: nil, color: nil, colour: nil, opacity: nil, fill: true, stroke_width: 0, stroke_color: nil, stroke_colour: nil, add: true, visible: true) ⇒ Polygon
Create a polygon points is an array of [x, y] pairs with N >= 3 vertices
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/ruby2d/polygon.rb', line 14 def initialize(points:, z: 0, rotate: 0, rx: nil, ry: nil, color: nil, colour: nil, opacity: nil, fill: true, stroke_width: 0, stroke_color: nil, stroke_colour: nil, add: true, visible: true) raise ArgumentError, 'Polygon requires at least 3 points' if points.length < 3 raise ArgumentError, 'points must be an array of [x, y] pairs' \ unless points.all? { |p| p.is_a?(Array) && p.length == 2 } @coordinates = points.flat_map { |x, y| [x.to_f, y.to_f] } @z = z @rotate = rotate @_user_rx = rx @_user_ry = ry self.color = color || colour || 'white' self.opacity = opacity unless opacity.nil? @fill = fill @stroke_width = stroke_width self.stroke_color = stroke_color || stroke_colour || (color || colour) self.stroke_color.opacity = opacity unless opacity.nil? @visible = visible self.add if add end |
Instance Attribute Details
#fill ⇒ Object
Returns the value of attribute fill.
8 9 10 |
# File 'lib/ruby2d/polygon.rb', line 8 def fill @fill end |
#rotate ⇒ Object
Returns the value of attribute rotate.
8 9 10 |
# File 'lib/ruby2d/polygon.rb', line 8 def rotate @rotate end |
#stroke_color ⇒ Object Also known as: stroke_colour
Returns the value of attribute stroke_color.
9 10 11 |
# File 'lib/ruby2d/polygon.rb', line 9 def stroke_color @stroke_color end |
#stroke_width ⇒ Object
Returns the value of attribute stroke_width.
8 9 10 |
# File 'lib/ruby2d/polygon.rb', line 8 def stroke_width @stroke_width end |
Class Method Details
.render(points:, rotate: 0, rx: nil, ry: nil, color: nil, colour: nil, opacity: nil, fill: true, stroke_width: 0, stroke_color: nil, stroke_colour: nil) ⇒ Object
Render a polygon without creating an instance
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/ruby2d/polygon.rb', line 147 def self.render(points:, rotate: 0, rx: nil, ry: nil, color: nil, colour: nil, opacity: nil, fill: true, stroke_width: 0, stroke_color: nil, stroke_colour: nil) Window.render_ready_check raise ArgumentError, 'Polygon requires at least 3 points' if points.length < 3 n = points.length coords = Renderable.flatten_points(points) fill_input = color || colour pvc = Renderable.flatten_color(fill_input, n, opacity, label: self) if rotate != 0 ccx = 0.0; ccy = 0.0 n.times do |i| ccx += coords[i * 2] ccy += coords[i * 2 + 1] end ccx /= n ccy /= n coords = rotate_coords(coords, rotate, rx || ccx, ry || ccy) end Ext.draw_polygon(coords, pvc) if fill # Flatten the stroke colors only when actually stroking; an explicitly # given stroke color is still validated at stroke_width 0 to match the # instance constructor. if stroke_width > 0 pvs = Renderable.flatten_color(stroke_color || stroke_colour || fill_input, n, opacity, label: self) Ext.stroke_path(coords, stroke_width, pvs, true) elsif stroke_color || stroke_colour Renderable.flatten_color(stroke_color || stroke_colour, n, opacity, label: self) end end |
Instance Method Details
#color=(color) ⇒ Object
Set the fill color (single or per-vertex array). Per-vertex array length must match vertex_count.
128 129 130 131 132 133 134 135 136 |
# File 'lib/ruby2d/polygon.rb', line 128 def color=(color) cs = Color.set(color) if cs.is_a?(Color::Set) && cs.length != vertex_count raise ArgumentError, "`#{self.class}` requires #{vertex_count} colors, one for each vertex. #{cs.length} were given." end @color = cs @_cc = nil end |
#contains?(x, y) ⇒ Boolean
Test whether (x, y) lies inside the polygon, using the even-odd ray-cast
rule (shared by every filled polygonal shape — see _point_in_polygon?).
Matches the rendered fill for non-self-intersecting polygons (convex and
concave); self-intersecting input isn't fully supported by the renderer, so
the test can diverge from the drawn pixels there.
63 64 65 66 |
# File 'lib/ruby2d/polygon.rb', line 63 def contains?(x, y) x, y = _unrotate(x, y) _point_in_polygon?(@coordinates, x, y) end |
#height ⇒ Object
53 54 55 56 |
# File 'lib/ruby2d/polygon.rb', line 53 def height ys = @coordinates.each_slice(2).map(&:last) ys.max - ys.min end |
#points ⇒ Object
The vertices as an array of [x, y] pairs
43 44 45 |
# File 'lib/ruby2d/polygon.rb', line 43 def points @coordinates.each_slice(2).to_a end |
#rx ⇒ Object
Get the rotation center x coordinate
107 108 109 |
# File 'lib/ruby2d/polygon.rb', line 107 def rx @_user_rx.nil? ? x : @_user_rx end |
#rx=(val) ⇒ Object
Set the rotation center x coordinate
117 118 119 |
# File 'lib/ruby2d/polygon.rb', line 117 def rx=(val) @_user_rx = val end |
#ry ⇒ Object
Get the rotation center y coordinate
112 113 114 |
# File 'lib/ruby2d/polygon.rb', line 112 def ry @_user_ry.nil? ? y : @_user_ry end |
#ry=(val) ⇒ Object
Set the rotation center y coordinate
122 123 124 |
# File 'lib/ruby2d/polygon.rb', line 122 def ry=(val) @_user_ry = val end |
#vertex_count ⇒ Object
Number of vertices
38 39 40 |
# File 'lib/ruby2d/polygon.rb', line 38 def vertex_count @coordinates.length / 2 end |
#width ⇒ Object
Bounding-box width and height (extent across all vertices)
48 49 50 51 |
# File 'lib/ruby2d/polygon.rb', line 48 def width xs = @coordinates.each_slice(2).map(&:first) xs.max - xs.min end |
#x ⇒ Object
Centroid x (average of vertex x coordinates)
69 70 71 72 73 74 |
# File 'lib/ruby2d/polygon.rb', line 69 def x sum = 0.0 n = vertex_count n.times { |i| sum += @coordinates[i * 2] } sum / n end |
#x=(new_x) ⇒ Object
Set the centroid x coordinate, translating all vertices
85 86 87 88 89 90 91 92 93 |
# File 'lib/ruby2d/polygon.rb', line 85 def x=(new_x) _require_numeric_position(:x, new_x) dx = new_x - x i = 0 while i < @coordinates.length @coordinates[i] += dx i += 2 end end |
#y ⇒ Object
Centroid y (average of vertex y coordinates)
77 78 79 80 81 82 |
# File 'lib/ruby2d/polygon.rb', line 77 def y sum = 0.0 n = vertex_count n.times { |i| sum += @coordinates[i * 2 + 1] } sum / n end |
#y=(new_y) ⇒ Object
Set the centroid y coordinate, translating all vertices
96 97 98 99 100 101 102 103 104 |
# File 'lib/ruby2d/polygon.rb', line 96 def y=(new_y) _require_numeric_position(:y, new_y) dy = new_y - y i = 1 while i < @coordinates.length @coordinates[i] += dy i += 2 end end |