perfect-shape 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 81aba6992bb9cb98b1ce01764cb4cd0ca8e88690c56066e8282b4c0876421925
4
- data.tar.gz: c63f14e43dfa8adff2bd525a77ca25ded5d1381953abb4a728770b22dab43323
3
+ metadata.gz: 7fdd723154a24a57aa233988884800a33af7b6094bcb93c5d9a75778fe2259b2
4
+ data.tar.gz: df02fc673c2d24490f7883282790c0f6135c7ed910679020d8cea8f1f969cfc3
5
5
  SHA512:
6
- metadata.gz: 6ff01e388f4fadc337792f45ddfc598fecaeb3816fe13d04f5db4a13ecc78c7e978e2ef9683e33e32711bda62373c77dd1f5f4c07d69cfc23e4867bfbba9ccca
7
- data.tar.gz: b32a4c65a4101ffa61cdab257fa1af05d59e7ee1f8e12ac8598dbad92a32dd33299bda92add7781e3f9028278051ebda36d9164cde116d79fc70f6d8b297f8ed
6
+ metadata.gz: cb680e84b8f0356378634d316ed06fff07944d1ab35fe1954359beccbe58e03e77256f4fbb008bc8ab448fa559d91e5a812e1b19b60cefc61161f44ae9047032
7
+ data.tar.gz: 1a32bf4f4bc3f572cbab061628e0302e0b38d49774f54d94ba8fb35a90cb67373d22de0ad2642da620ba5a85d20f5a6587faa518dab798aa1a75c8ef3638af90
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.0.7
4
+
5
+ - `PerfectShape::Shape#min_x`/`PerfectShape::Shape#min_y`/`PerfectShape::Shape#max_x`/`PerfectShape::Shape#max_y`/`PerfectShape::Shape#center_x`/`PerfectShape::Shape#center_y`/`PerfectShape::Shape#bounding_box`
6
+
3
7
  ## 0.0.6
4
8
 
5
9
  - `PerfectShape::Circle`
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
- # Perfect Shape 0.0.6
1
+ # Perfect Shape 0.0.7
2
2
  ## Geometric Algorithms
3
3
  [![Gem Version](https://badge.fury.io/rb/perfect-shape.svg)](http://badge.fury.io/rb/perfect-shape)
4
4
 
5
- `PerfectShape` is a collection of pure Ruby geometric algorithms that are mostly useful for GUI (Graphical User Interface) manipulation like checking containment of a mouse click point in popular geometry shapes such as rectangle, square, arc (open, chord, and pie), ellipse, circle, polygon, polyline, polyquad, polycubic, and paths containing lines, bezier curves, and quadratic curves.
5
+ `PerfectShape` is a collection of pure Ruby geometric algorithms that are mostly useful for GUI (Graphical User Interface) manipulation like checking containment of a mouse click point in popular geometry shapes such as rectangle, square, arc (open, chord, and pie), ellipse, circle, polygon (ray casting algorithm/even-odd rule), polyline, polyquad, polycubic, and paths containing lines, bezier curves, and quadratic curves.
6
6
 
7
7
  Additionally, `PerfectShape::Math` contains some purely mathematical algorithms.
8
8
 
@@ -13,13 +13,13 @@ To ensure high accuracy, this library does all its mathematical operations with
13
13
  Run:
14
14
 
15
15
  ```
16
- gem install perfect-shape -v 0.0.6
16
+ gem install perfect-shape -v 0.0.7
17
17
  ```
18
18
 
19
19
  Or include in Bundler `Gemfile`:
20
20
 
21
21
  ```ruby
22
- gem 'perfect-shape', '~> 0.0.6'
22
+ gem 'perfect-shape', '~> 0.0.7'
23
23
  ```
24
24
 
25
25
  And, run:
@@ -43,6 +43,15 @@ Module
43
43
 
44
44
  Class
45
45
 
46
+ - `#min_x`: min x
47
+ - `#min_y`: min y
48
+ - `#max_x`: max x
49
+ - `#max_y`: max y
50
+ - `#width`: width
51
+ - `#height`: height
52
+ - `#center_x`: center x
53
+ - `#center_y`: center y
54
+ - `#bounding_box`: bounding box is a rectangle with x = min x, y = min y, and width/height just as those of shape
46
55
  - `#normalize_point(x_or_point, y = nil)`: normalizes point into an `Array` of (x,y) coordinates
47
56
 
48
57
  ### `PerfectShape::RectangularShape`
@@ -54,8 +63,13 @@ Module
54
63
  - `#y`: top-left y
55
64
  - `#width`: width
56
65
  - `#height`: height
66
+ - `#min_x`: min x
67
+ - `#min_y`: min y
68
+ - `#max_x`: max x
69
+ - `#max_y`: max y
57
70
  - `#center_x`: center x
58
71
  - `#center_y`: center y
72
+ - `#bounding_box`: bounding box is a rectangle with x = min x, y = min y, and width/height of shape
59
73
 
60
74
  ### `PerfectShape::Line`
61
75
 
@@ -79,6 +93,11 @@ Includes `PerfectShape::RectangularShape`
79
93
  - `#height`: height
80
94
  - `#center_x`: center x
81
95
  - `#center_y`: center y
96
+ - `#min_x`: min x
97
+ - `#min_y`: min y
98
+ - `#max_x`: max x
99
+ - `#max_y`: max y
100
+ - `#bounding_box`: bounding box is a rectangle with x = min x, y = min y, and width/height of shape
82
101
  - `#contain?(x_or_point, y=nil)`: checks if point is inside
83
102
 
84
103
  ### `PerfectShape::Square`
@@ -96,6 +115,11 @@ Extends `PerfectShape::Rectangle`
96
115
  - `#height`: height (equal to length)
97
116
  - `#center_x`: center x
98
117
  - `#center_y`: center y
118
+ - `#min_x`: min x
119
+ - `#min_y`: min y
120
+ - `#max_x`: max x
121
+ - `#max_y`: max y
122
+ - `#bounding_box`: bounding box is a rectangle with x = min x, y = min y, and width/height of shape
99
123
  - `#contain?(x_or_point, y=nil)`: checks if point is inside
100
124
 
101
125
  ### `PerfectShape::Arc`
@@ -122,6 +146,11 @@ Open Arc | Chord Arc | Pie Arc
122
146
  - `#center_y`: center y
123
147
  - `#radius_x`: radius along the x-axis
124
148
  - `#radius_y`: radius along the y-axis
149
+ - `#min_x`: min x
150
+ - `#min_y`: min y
151
+ - `#max_x`: max x
152
+ - `#max_y`: max y
153
+ - `#bounding_box`: bounding box is a rectangle with x = min x, y = min y, and width/height of shape
125
154
  - `#contain?(x_or_point, y=nil)`: checks if point is inside
126
155
 
127
156
  ### `PerfectShape::Ellipse`
@@ -143,6 +172,11 @@ Extends `PerfectShape::Arc`
143
172
  - `#type`: always `:open`
144
173
  - `#start`: always `0`
145
174
  - `#extent`: always `360`
175
+ - `#min_x`: min x
176
+ - `#min_y`: min y
177
+ - `#max_x`: max x
178
+ - `#max_y`: max y
179
+ - `#bounding_box`: bounding box is a rectangle with x = min x, y = min y, and width/height of shape
146
180
  - `#contain?(x_or_point, y=nil)`: checks if point is inside
147
181
 
148
182
  ### `PerfectShape::Circle`
@@ -166,8 +200,32 @@ Extends `PerfectShape::Ellipse`
166
200
  - `#type`: always `:open`
167
201
  - `#start`: always `0`
168
202
  - `#extent`: always `360`
203
+ - `#min_x`: min x
204
+ - `#min_y`: min y
205
+ - `#max_x`: max x
206
+ - `#max_y`: max y
207
+ - `#bounding_box`: bounding box is a rectangle with x = min x, y = min y, and width/height of shape
169
208
  - `#contain?(x_or_point, y=nil)`: checks if point is inside
170
209
 
210
+ ### `PerfectShape::Polygon`
211
+
212
+ Class
213
+ Extends `PerfectShape::Shape`
214
+
215
+ ![polygon](images/polygon.png)
216
+
217
+ - `::new(points: nil)`: constructs a polygon with `points` as `Array` of `Array`s of (x,y) pairs or flattened `Array` of alternating x and y coordinates
218
+ - `#min_x`: min x
219
+ - `#min_y`: min y
220
+ - `#max_x`: max x
221
+ - `#max_y`: max y
222
+ - `#width`: width (from min x to max x)
223
+ - `#height`: height (from min y to max y)
224
+ - `#center_x`: center x
225
+ - `#center_y`: center y
226
+ - `#bounding_box`: bounding box is a rectangle with x = min x, y = min y, and width/height of shape
227
+ - `#contain?(x_or_point, y=nil)`: checks if point is inside using the [Ray Casting Algorithm](https://en.wikipedia.org/wiki/Point_in_polygon) (aka [Even-Odd Rule](https://en.wikipedia.org/wiki/Even%E2%80%93odd_rule))
228
+
171
229
  ## Process
172
230
 
173
231
  [Glimmer Process](https://github.com/AndyObtiva/glimmer/blob/master/PROCESS.md)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.6
1
+ 0.0.7
data/lib/perfect-shape.rb CHANGED
@@ -22,6 +22,7 @@
22
22
  $LOAD_PATH.unshift File.expand_path('.', __dir__)
23
23
 
24
24
  require 'bigdecimal'
25
+ require 'equalizer'
25
26
 
26
27
  # Perfect Shape algorithms are mostly ported from java.awt.geom: https://docs.oracle.com/javase/8/docs/api/java/awt/geom/package-summary.html
27
28
  module PerfectShape
@@ -27,6 +27,7 @@ module PerfectShape
27
27
  # Mostly ported from java.awt.geom: https://docs.oracle.com/javase/8/docs/api/java/awt/geom/Arc2D.html
28
28
  class Arc < Shape
29
29
  include RectangularShape
30
+ include Equalizer.new(:type, :x, :y, :width, :height, :start, :extent)
30
31
 
31
32
  TYPES = [:open, :chord, :pie]
32
33
  attr_accessor :type
@@ -64,6 +64,7 @@ module PerfectShape
64
64
  # the ellipse, {@code false} if the point lies outside of the
65
65
  # ellipse's bounds.
66
66
  def contain?(x_or_point, y = nil)
67
+ # This is implemented again even though super would have just worked to have an optimized algorithm for Ellipse.
67
68
  x, y = normalize_point(x_or_point, y)
68
69
  return unless x && y
69
70
  ellw = self.width
@@ -0,0 +1,151 @@
1
+ # Copyright (c) 2021 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ require 'perfect_shape/shape'
23
+
24
+ module PerfectShape
25
+ # Mostly ported from java.awt.geom: https://docs.oracle.com/javase/8/docs/api/java/awt/Polygon.html
26
+ class Polygon < Shape
27
+ attr_reader :points
28
+
29
+ def initialize(points: nil)
30
+ self.points = points || []
31
+ end
32
+
33
+ # Sets points, normalizing to an Array of Arrays of (x,y) pairs as BigDecimal
34
+ def points=(the_points)
35
+ unless the_points.first.is_a?(Array)
36
+ xs = the_points.each_with_index.select {|n, i| i.even?}.map(&:first)
37
+ ys = the_points.each_with_index.select {|n, i| i.odd?}.map(&:first)
38
+ the_points = xs.zip(ys)
39
+ end
40
+ @points = the_points.map {|pair| [BigDecimal(pair.first.to_s), BigDecimal(pair.last.to_s)]}
41
+ end
42
+
43
+ def min_x
44
+ points.map(&:first).min
45
+ end
46
+
47
+ def min_y
48
+ points.map(&:last).min
49
+ end
50
+
51
+ def max_x
52
+ points.map(&:first).max
53
+ end
54
+
55
+ def max_y
56
+ points.map(&:last).max
57
+ end
58
+
59
+ def width
60
+ max_x - min_x if min_x && max_x
61
+ end
62
+
63
+ def height
64
+ max_y - min_y if min_y && max_y
65
+ end
66
+
67
+ # Checks if polygon contains point denoted by point (two-number Array or x, y args)
68
+ # using the Ray Casting Algorithm (aka Even-Odd Rule): https://en.wikipedia.org/wiki/Point_in_polygon
69
+ #
70
+ # @param x The X coordinate of the point to test.
71
+ # @param y The Y coordinate of the point to test.
72
+ #
73
+ # @return {@code true} if the point lies within the bound of
74
+ # the polygon, {@code false} if the point lies outside of the
75
+ # polygon's bounds.
76
+ def contain?(x_or_point, y = nil)
77
+ x, y = normalize_point(x_or_point, y)
78
+ return unless x && y
79
+ npoints = points.count
80
+ xpoints = points.map(&:first)
81
+ ypoints = points.map(&:last)
82
+ return false if npoints <= 2 || !bounding_box.contain?(x, y)
83
+ hits = 0
84
+
85
+ lastx = xpoints[npoints - 1]
86
+ lasty = ypoints[npoints - 1]
87
+
88
+ # Walk the edges of the polygon
89
+ npoints.times do |i|
90
+ curx = xpoints[i]
91
+ cury = ypoints[i]
92
+
93
+ if cury == lasty
94
+ lastx = curx
95
+ lasty = cury
96
+ next
97
+ end
98
+
99
+ if curx < lastx
100
+ if x >= lastx
101
+ lastx = curx
102
+ lasty = cury
103
+ next
104
+ end
105
+ leftx = curx
106
+ else
107
+ if x >= curx
108
+ lastx = curx
109
+ lasty = cury
110
+ next
111
+ end
112
+ leftx = lastx
113
+ end
114
+
115
+ if cury < lasty
116
+ if y < cury || y >= lasty
117
+ lastx = curx
118
+ lasty = cury
119
+ next
120
+ end
121
+ if x < leftx
122
+ hits += 1
123
+ lastx = curx
124
+ lasty = cury
125
+ next
126
+ end
127
+ test1 = x - curx
128
+ test2 = y - cury
129
+ else
130
+ if y < lasty || y >= cury
131
+ lastx = curx
132
+ lasty = cury
133
+ next
134
+ end
135
+ if x < leftx
136
+ hits += 1
137
+ lastx = curx
138
+ lasty = cury
139
+ next
140
+ end
141
+ test1 = x - lastx
142
+ test2 = y - lasty
143
+ end
144
+
145
+ hits += 1 if (test1 < (test2 / (lasty - cury) * (lastx - curx)))
146
+ end
147
+
148
+ (hits & 1) != 0
149
+ end
150
+ end
151
+ end
@@ -26,7 +26,8 @@ module PerfectShape
26
26
  # Mostly ported from java.awt.geom: https://docs.oracle.com/javase/8/docs/api/java/awt/geom/Rectangle2D.html
27
27
  class Rectangle < Shape
28
28
  include RectangularShape
29
-
29
+ include Equalizer.new(:x, :y, :width, :height)
30
+
30
31
  # Checks if rectangle contains point denoted by point (two-number Array or x, y args)
31
32
  #
32
33
  # @param x The X coordinate of the point to test.
@@ -54,12 +54,20 @@ module PerfectShape
54
54
  @height = BigDecimal(value.to_s)
55
55
  end
56
56
 
57
- def center_x
58
- @x + (@width/BigDecimal('2.0')) if @x && @width
57
+ def min_x
58
+ @x
59
59
  end
60
60
 
61
- def center_y
62
- @y + (@height/BigDecimal('2.0')) if @y && @height
61
+ def min_y
62
+ @y
63
+ end
64
+
65
+ def max_x
66
+ @x + width if @x && width
67
+ end
68
+
69
+ def max_y
70
+ @y + height if @y && height
63
71
  end
64
72
  end
65
73
  end
@@ -22,6 +22,48 @@
22
22
  module PerfectShape
23
23
  # Superclass of all shapes
24
24
  class Shape
25
+ # Subclasses must implement
26
+ def min_x
27
+ end
28
+
29
+ # Subclasses must implement
30
+ def min_y
31
+ end
32
+
33
+ # Subclasses must implement
34
+ def max_x
35
+ end
36
+
37
+ # Subclasses must implement
38
+ def max_y
39
+ end
40
+
41
+ # Subclasses must implement
42
+ def width
43
+ end
44
+
45
+ # Subclasses must implement
46
+ def height
47
+ end
48
+
49
+ # center_x is min_x + width/2.0 by default
50
+ # Returns nil if min_x or width are nil
51
+ def center_x
52
+ min_x + width / BigDecimal('2.0') if min_x && width
53
+ end
54
+
55
+ # center_y is min_y + height/2.0 by default
56
+ # Returns nil if min_y or height are nil
57
+ def center_y
58
+ min_y + height / BigDecimal('2.0') if min_y && height
59
+ end
60
+
61
+ # Rectangle with x = self.min_x, y = self.min_y, width = self.width, height = self.height
62
+ def bounding_box
63
+ require 'perfect_shape/rectangle'
64
+ Rectangle.new(x: min_x, y: min_y, width: width, height: height)
65
+ end
66
+
25
67
  # Normalizes point args whether two-number Array or x, y args returning
26
68
  # normalized point array of two BigDecimal's
27
69
  #
@@ -2,17 +2,17 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: perfect-shape 0.0.6 ruby lib
5
+ # stub: perfect-shape 0.0.7 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "perfect-shape".freeze
9
- s.version = "0.0.6"
9
+ s.version = "0.0.7"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib".freeze]
13
13
  s.authors = ["Andy Maleh".freeze]
14
- s.date = "2021-12-16"
15
- s.description = "Perfect Shape is a collection of pure Ruby geometric algorithms that are mostly useful for GUI manipulation like checking containment of a mouse click point in popular geometry shapes such as rectangle, square, arc (open, chord, and pie), ellipse, circle, polygon, polyline, polyquad, polycubic, and paths containing lines, bezier curves, and quadratic curves. Additionally, it contains some purely mathematical algorithms like IEEEremainder (also known as IEEE-754 remainder).".freeze
14
+ s.date = "2021-12-17"
15
+ s.description = "Perfect Shape is a collection of pure Ruby geometric algorithms that are mostly useful for GUI manipulation like checking containment of a mouse click point in popular geometry shapes such as rectangle, square, arc (open, chord, and pie), ellipse, circle, polygon (Ray Casting Algorithm aka Even-Odd Rule), polyline, polyquad, polycubic, and paths containing lines, bezier curves, and quadratic curves. Additionally, it contains some purely mathematical algorithms like IEEEremainder (also known as IEEE-754 remainder).".freeze
16
16
  s.email = "andy.am@gmail.com".freeze
17
17
  s.extra_rdoc_files = [
18
18
  "CHANGELOG.md",
@@ -30,6 +30,7 @@ Gem::Specification.new do |s|
30
30
  "lib/perfect_shape/ellipse.rb",
31
31
  "lib/perfect_shape/line.rb",
32
32
  "lib/perfect_shape/math.rb",
33
+ "lib/perfect_shape/polygon.rb",
33
34
  "lib/perfect_shape/rectangle.rb",
34
35
  "lib/perfect_shape/rectangular_shape.rb",
35
36
  "lib/perfect_shape/shape.rb",
@@ -46,12 +47,14 @@ Gem::Specification.new do |s|
46
47
  end
47
48
 
48
49
  if s.respond_to? :add_runtime_dependency then
50
+ s.add_runtime_dependency(%q<equalizer>.freeze, ["= 0.0.11"])
49
51
  s.add_development_dependency(%q<rdoc>.freeze, ["~> 3.12"])
50
52
  s.add_development_dependency(%q<juwelier>.freeze, ["~> 2.1.0"])
51
53
  s.add_development_dependency(%q<minitest>.freeze, ["~> 5.14.4"])
52
54
  s.add_development_dependency(%q<puts_debuggerer>.freeze, ["~> 0.13.1"])
53
55
  s.add_development_dependency(%q<rake-tui>.freeze, ["> 0"])
54
56
  else
57
+ s.add_dependency(%q<equalizer>.freeze, ["= 0.0.11"])
55
58
  s.add_dependency(%q<rdoc>.freeze, ["~> 3.12"])
56
59
  s.add_dependency(%q<juwelier>.freeze, ["~> 2.1.0"])
57
60
  s.add_dependency(%q<minitest>.freeze, ["~> 5.14.4"])
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: perfect-shape
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Maleh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-16 00:00:00.000000000 Z
11
+ date: 2021-12-17 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: equalizer
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 0.0.11
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 0.0.11
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: rdoc
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -83,9 +97,10 @@ dependencies:
83
97
  description: Perfect Shape is a collection of pure Ruby geometric algorithms that
84
98
  are mostly useful for GUI manipulation like checking containment of a mouse click
85
99
  point in popular geometry shapes such as rectangle, square, arc (open, chord, and
86
- pie), ellipse, circle, polygon, polyline, polyquad, polycubic, and paths containing
87
- lines, bezier curves, and quadratic curves. Additionally, it contains some purely
88
- mathematical algorithms like IEEEremainder (also known as IEEE-754 remainder).
100
+ pie), ellipse, circle, polygon (Ray Casting Algorithm aka Even-Odd Rule), polyline,
101
+ polyquad, polycubic, and paths containing lines, bezier curves, and quadratic curves.
102
+ Additionally, it contains some purely mathematical algorithms like IEEEremainder
103
+ (also known as IEEE-754 remainder).
89
104
  email: andy.am@gmail.com
90
105
  executables: []
91
106
  extensions: []
@@ -104,6 +119,7 @@ files:
104
119
  - lib/perfect_shape/ellipse.rb
105
120
  - lib/perfect_shape/line.rb
106
121
  - lib/perfect_shape/math.rb
122
+ - lib/perfect_shape/polygon.rb
107
123
  - lib/perfect_shape/rectangle.rb
108
124
  - lib/perfect_shape/rectangular_shape.rb
109
125
  - lib/perfect_shape/shape.rb