perfect-shape 1.0.6 → 1.0.8

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: 7cd9bf6e78e556604f5a9ff5b26e7b952ca8c61424aac789238c2d5d8961b1c8
4
- data.tar.gz: a76a11a91632b22a3b3b136d55ded17ba17b10b940de7186c912bf5cb0642cc7
3
+ metadata.gz: c42cbc601c834a3f5f5b22a270885329c3bfbac8379f4e978d0a8499a7b5b958
4
+ data.tar.gz: 7aa4083ba8bbededcd7a50058b82482d605cf772f92065a5aa7a435173e2b997
5
5
  SHA512:
6
- metadata.gz: 54ca03287c4efe1f2a88ab8ad9a3372c29313460f433be17e7300428ea34264d6fcfbd3bc54dedb3953959295a97669e89553fa450f04ab62e99779638501826
7
- data.tar.gz: 4c254bfaa37c9d4254ec2df488a0989a580c5907594b992be1d024d3ddda1f790b5340e3f9205214454f167400b9af182d4ad71cf913336203af411a13d220e6
6
+ metadata.gz: 29684cca244b520035eccc0539da8d8747794c746ea6995f984c745175b4cb8cfbb116ff7a678b6841a81022b8391d0a88d0546334725eab21620c659650fc87
7
+ data.tar.gz: 4803503efdee68e4f97b16f36277f13e266a6bdc4f48dde4b3bc41568f48a7e764ccb5af24ec7fde4a358cdd5fc4e35ecb5a45a4a473042e6b647f7a9d5a5064
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Change Log
2
2
 
3
+ ## 1.0.8
4
+
5
+ - Fix issue with a closed path crashing in `Path#contain?` if the first basic shape is a point array instead of a `PerfectShape::Point` object
6
+
7
+ ## 1.0.7
8
+
9
+ - Support constructing `PerfectShape::Path` without a point at the beginning
10
+ - Support `first_point` method on all shapes to return first point in a shape
11
+ - Fix issue in using `Path#contain?` with `outline: true` when `line_to_complex_shapes: true` and path starts with a `Line` instead of a point.
12
+
3
13
  ## 1.0.6
4
14
 
5
15
  - Fix issue with `Path#contain?` algorithm not working correclty when `Path` contains non-basic shapes because `shapes.count` is checked instead of `basic_shapes.count`
data/README.md CHANGED
@@ -1,8 +1,10 @@
1
- # Perfect Shape 1.0.6
1
+ # Perfect Shape 1.0.8
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
  [![Test](https://github.com/AndyObtiva/perfect-shape/actions/workflows/ruby.yml/badge.svg)](https://github.com/AndyObtiva/perfect-shape/actions/workflows/ruby.yml)
5
5
 
6
+ ([Used by Fukuoka 2022 Special Award Winning Glimmer DSL for LibUI Ruby Desktop Development GUI Library](https://github.com/AndyObtiva/glimmer-dsl-libui))
7
+
6
8
  [`PerfectShape`](https://rubygems.org/gems/perfect-shape) is a collection of pure Ruby geometric algorithms that are mostly useful for GUI (Graphical User Interface) manipulation like checking viewport rectangle intersection or containment of a mouse click [point](#perfectshapepoint) in popular geometry shapes such as [rectangle](#perfectshaperectangle), [square](#perfectshapesquare), [arc](#perfectshapearc) (open, chord, and pie), [ellipse](#perfectshapeellipse), [circle](#perfectshapecircle), [polygon](#perfectshapepolygon), and [paths](#perfectshapepath) containing [lines](#perfectshapeline), [quadratic bézier curves](#perfectshapequadraticbeziercurve), and [cubic bezier curves](#perfectshapecubicbeziercurve), potentially with [affine transforms](#perfectshapeaffinetransform) applied like translation, scale, rotation, shear/skew, and inversion (including both the [Ray Casting Algorithm](https://en.wikipedia.org/wiki/Point_in_polygon#Ray_casting_algorithm), aka [Even-odd Rule](https://en.wikipedia.org/wiki/Even%E2%80%93odd_rule), and the [Winding Number Algorithm](https://en.wikipedia.org/wiki/Point_in_polygon#Winding_number_algorithm), aka [Nonzero Rule](https://en.wikipedia.org/wiki/Nonzero-rule)).
7
9
 
8
10
  Additionally, [`PerfectShape::Math`](#perfectshapemath) contains some purely mathematical algorithms, like [IEEE 754-1985 Remainder](https://en.wikipedia.org/wiki/IEEE_754-1985).
@@ -14,13 +16,13 @@ To ensure accuracy and precision, this library does all its mathematical operati
14
16
  Run:
15
17
 
16
18
  ```
17
- gem install perfect-shape -v 1.0.6
19
+ gem install perfect-shape -v 1.0.8
18
20
  ```
19
21
 
20
22
  Or include in Bundler `Gemfile`:
21
23
 
22
24
  ```ruby
23
- gem 'perfect-shape', '~> 1.0.6'
25
+ gem 'perfect-shape', '~> 1.0.8'
24
26
  ```
25
27
 
26
28
  And, run:
@@ -68,6 +70,7 @@ Module
68
70
  - `#y`: top-left y
69
71
  - `#min_x`: min x (x by default)
70
72
  - `#min_y`: min y (y by default)
73
+ - `#first_point`: first point for shape including this module (always assumes top-left corner)
71
74
 
72
75
  ### `PerfectShape::RectangularShape`
73
76
 
@@ -96,6 +99,7 @@ Module
96
99
  - `#min_y`: min y of all points
97
100
  - `#max_x`: max x of all points
98
101
  - `#max_y`: max y of all points
102
+ - `#first_point`: first point for shape including this module
99
103
 
100
104
  ### `PerfectShape::AffineTransform`
101
105
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.6
1
+ 1.0.8
@@ -55,6 +55,10 @@ module PerfectShape
55
55
  @points
56
56
  end
57
57
 
58
+ def first_point
59
+ points.first.to_a
60
+ end
61
+
58
62
  def min_x
59
63
  points.map(&:first).min
60
64
  end
@@ -64,14 +64,20 @@ module PerfectShape
64
64
 
65
65
  def points
66
66
  the_points = []
67
- basic_shapes.each do |shape|
67
+ basic_shapes.each_with_index do |shape, i|
68
68
  case shape
69
69
  when Point
70
70
  the_points << shape.to_a
71
71
  when Array
72
72
  the_points << shape.map {|n| BigDecimal(n.to_s)}
73
73
  when Line
74
- the_points << shape.points.last.to_a
74
+ if i == 0
75
+ shape.points.each do |point|
76
+ the_points << point.to_a
77
+ end
78
+ else
79
+ the_points << shape.points.last.to_a
80
+ end
75
81
  when QuadraticBezierCurve
76
82
  shape.points.each do |point|
77
83
  the_points << point.to_a
@@ -82,7 +88,11 @@ module PerfectShape
82
88
  end
83
89
  end
84
90
  end
85
- the_points << basic_shapes.first.to_a if closed?
91
+ if closed?
92
+ first_basic_shape = basic_shapes.first
93
+ closing_point = first_basic_shape.is_a?(Array) ? first_basic_shape : first_basic_shape.first_point
94
+ the_points << closing_point
95
+ end
86
96
  the_points
87
97
  end
88
98
 
@@ -91,14 +101,14 @@ module PerfectShape
91
101
  end
92
102
 
93
103
  def drawing_types
94
- the_drawing_shapes = basic_shapes.map do |shape|
104
+ the_drawing_shapes = basic_shapes.each_with_index.flat_map do |shape, i|
95
105
  case shape
96
106
  when Point
97
107
  :move_to
98
108
  when Array
99
109
  :move_to
100
110
  when Line
101
- :line_to
111
+ (i == 0) ? [:move_to, :line_to] : :line_to
102
112
  when QuadraticBezierCurve
103
113
  :quad_to
104
114
  when CubicBezierCurve
@@ -245,7 +255,8 @@ module PerfectShape
245
255
  # added to represent the line connecting the last point to the first
246
256
  def disconnected_shapes
247
257
  # TODO it seems basic_shapes.first should always return a point, but there is a case with CompositeShape that results in a line (shape) not point returned
248
- initial_point = start_point = basic_shapes.first.to_a.map {|n| BigDecimal(n.to_s)}
258
+ first_point = basic_shapes.first.is_a?(Array) ? basic_shapes.first : basic_shapes.first.first_point
259
+ initial_point = start_point = first_point.map {|n| BigDecimal(n.to_s)}
249
260
  final_point = nil
250
261
  the_disconnected_shapes = basic_shapes.drop(1).map do |shape|
251
262
  case shape
@@ -389,9 +400,10 @@ module PerfectShape
389
400
  # decomposed from complex shapes like Arc, Ellipse, and Circle by calling their `#to_path_shapes` method
390
401
  def basic_shapes
391
402
  the_shapes = []
392
- @shapes.each do |shape|
403
+ @shapes.each_with_index do |shape, i|
393
404
  if shape.respond_to?(:to_path_shapes)
394
405
  shape_basic_shapes = shape.to_path_shapes
406
+ the_shapes << shape.first_point if i == 0
395
407
  if @line_to_complex_shapes
396
408
  first_basic_shape = shape_basic_shapes.shift
397
409
  new_first_basic_shape = PerfectShape::Line.new(points: [first_basic_shape.to_a])
@@ -31,6 +31,10 @@ module PerfectShape
31
31
  self.y = y
32
32
  end
33
33
 
34
+ def first_point
35
+ [x, y]
36
+ end
37
+
34
38
  # Sets x, normalizing to BigDecimal
35
39
  def x=(value)
36
40
  @x = BigDecimal(value.to_s)
@@ -2,16 +2,16 @@
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 1.0.6 ruby lib
5
+ # stub: perfect-shape 1.0.8 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "perfect-shape".freeze
9
- s.version = "1.0.6"
9
+ s.version = "1.0.8"
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 = "2022-11-05"
14
+ s.date = "2023-05-27"
15
15
  s.description = "Perfect Shape is a collection of pure Ruby geometric algorithms that are mostly useful for GUI manipulation like checking viewport rectangle intersection or containment of a mouse click point in popular geometry shapes such as rectangle, square, arc (open, chord, and pie), ellipse, circle, polygon, and paths containing lines, quadratic b\u00E9zier curves, and cubic bezier curves, potentially with affine transforms applied like translation, scale, rotation, shear/skew, and inversion (including both the Ray Casting Algorithm, aka Even-odd Rule, and the Winding Number Algorithm, aka Nonzero Rule). 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 = [
@@ -47,7 +47,7 @@ Gem::Specification.new do |s|
47
47
  ]
48
48
  s.homepage = "http://github.com/AndyObtiva/perfect-shape".freeze
49
49
  s.licenses = ["MIT".freeze]
50
- s.rubygems_version = "3.3.16".freeze
50
+ s.rubygems_version = "3.3.1".freeze
51
51
  s.summary = "Perfect Shape - Geometric Algorithms".freeze
52
52
 
53
53
  if s.respond_to? :specification_version then
@@ -60,6 +60,7 @@ Gem::Specification.new do |s|
60
60
  s.add_development_dependency(%q<rdoc>.freeze, ["~> 3.12"])
61
61
  s.add_development_dependency(%q<juwelier>.freeze, ["~> 2.1.0"])
62
62
  s.add_development_dependency(%q<minitest>.freeze, ["~> 5.14.4"])
63
+ s.add_development_dependency(%q<minitest-focus>.freeze, ["~> 1.3.1"])
63
64
  s.add_development_dependency(%q<puts_debuggerer>.freeze, ["~> 0.13.1"])
64
65
  s.add_development_dependency(%q<rake-tui>.freeze, ["> 0"])
65
66
  else
@@ -68,6 +69,7 @@ Gem::Specification.new do |s|
68
69
  s.add_dependency(%q<rdoc>.freeze, ["~> 3.12"])
69
70
  s.add_dependency(%q<juwelier>.freeze, ["~> 2.1.0"])
70
71
  s.add_dependency(%q<minitest>.freeze, ["~> 5.14.4"])
72
+ s.add_dependency(%q<minitest-focus>.freeze, ["~> 1.3.1"])
71
73
  s.add_dependency(%q<puts_debuggerer>.freeze, ["~> 0.13.1"])
72
74
  s.add_dependency(%q<rake-tui>.freeze, ["> 0"])
73
75
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: perfect-shape
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.6
4
+ version: 1.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Maleh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-11-05 00:00:00.000000000 Z
11
+ date: 2023-05-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: matrix
@@ -92,6 +92,20 @@ dependencies:
92
92
  - - "~>"
93
93
  - !ruby/object:Gem::Version
94
94
  version: 5.14.4
95
+ - !ruby/object:Gem::Dependency
96
+ name: minitest-focus
97
+ requirement: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - "~>"
100
+ - !ruby/object:Gem::Version
101
+ version: 1.3.1
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - "~>"
107
+ - !ruby/object:Gem::Version
108
+ version: 1.3.1
95
109
  - !ruby/object:Gem::Dependency
96
110
  name: puts_debuggerer
97
111
  requirement: !ruby/object:Gem::Requirement
@@ -180,7 +194,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
180
194
  - !ruby/object:Gem::Version
181
195
  version: '0'
182
196
  requirements: []
183
- rubygems_version: 3.3.16
197
+ rubygems_version: 3.3.1
184
198
  signing_key:
185
199
  specification_version: 4
186
200
  summary: Perfect Shape - Geometric Algorithms