perfect-shape 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +27 -8
- data/VERSION +1 -1
- data/lib/perfect_shape/arc.rb +90 -26
- data/lib/perfect_shape/math.rb +22 -0
- data/lib/perfect_shape/rectangular_shape.rb +8 -0
- data/lib/perfect_shape/square.rb +8 -10
- data/perfect-shape.gemspec +4 -4
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 165108ad6899bfc0e001ba5ebbf2447a82e8173b03cdb3b08cf16b79f4287147
|
4
|
+
data.tar.gz: b2357efaa2e903edd66a212b06add8e6b3f6cec4a060f36b43eeb2f16bdb8072
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ded5da995dd9517acf3987c18f1410b1704c23b349a082791fdae91dd3f63bab91df89d5aa0b7b63b67f8d699e86b98905f80f30ef741e8570252f321ed7f7b8
|
7
|
+
data.tar.gz: 33f27f98eef7fee0f370f7f9003b73b26b27fb0c5c596b9a325bef6566669be6710b4fab5f4ab67e2be9728470b0b08369079b0924ca89544813b3b386e31f7d
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 0.0.4
|
4
|
+
|
5
|
+
- `PerfectShape::Arc#center_x` / `PerfectShape::Arc#center_y` / `PerfectShape::Arc#radius_x` / `PerfectShape::Arc#radius_y`
|
6
|
+
- `PerfectShape::Rectangle#center_x` / `PerfectShape::Arc#center_y`
|
7
|
+
- `PerfectShape::Square#center_x` / `PerfectShape::Square#center_y`
|
8
|
+
- `PerfectShape::Arc#initialize(center_x: , center_y: , radius_x: , radius_y: )`
|
9
|
+
- `PerfectShape::Math::normalize_degrees(degrees)` extracted from `PerfectShape::Arc`
|
10
|
+
|
3
11
|
## 0.0.3
|
4
12
|
|
5
13
|
- `PerfectShape::Square`
|
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
# Perfect Shape 0.0.
|
1
|
+
# Perfect Shape 0.0.4
|
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, ellipse, circle, polygon, polyline, polybezier, 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, polyline, polybezier, 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.
|
16
|
+
gem install perfect-shape -v 0.0.4
|
17
17
|
```
|
18
18
|
|
19
19
|
Or include in Bundler `Gemfile`:
|
20
20
|
|
21
21
|
```ruby
|
22
|
-
gem 'perfect-shape', '~> 0.0.
|
22
|
+
gem 'perfect-shape', '~> 0.0.4'
|
23
23
|
```
|
24
24
|
|
25
25
|
And, run:
|
@@ -32,9 +32,10 @@ bundle
|
|
32
32
|
|
33
33
|
### `PerfectShape::Math`
|
34
34
|
|
35
|
-
- `::degrees_to_radians(angle)
|
36
|
-
- `::radians_to_degrees(angle)
|
37
|
-
- `::
|
35
|
+
- `::degrees_to_radians(angle)`: converts degrees to radians
|
36
|
+
- `::radians_to_degrees(angle)`: converts radians to degrees
|
37
|
+
- `::normalize_degrees(angle)`: normalizes the specified angle into the range -180 to 180.
|
38
|
+
- `::ieee_remainder(x, y)` (alias: `ieee754_remainder`): [IEEE 754-1985 Remainder](https://en.wikipedia.org/wiki/IEEE_754-1985) (different from standard % modulo operator as it operates on floats and could return a negative result)
|
38
39
|
|
39
40
|
### `PerfectShape::Line`
|
40
41
|
|
@@ -42,32 +43,50 @@ bundle
|
|
42
43
|
|
43
44
|
### `PerfectShape::Rectangle`
|
44
45
|
|
46
|
+
![rectangle](images/rectangle.png)
|
47
|
+
|
45
48
|
- `::new(x: 0, y: 0, width: 1, height: 1)`: constructs a rectangle
|
46
49
|
- `#x`: top-left x
|
47
50
|
- `#y`: top-left y
|
48
51
|
- `#width`: width
|
49
52
|
- `#height`: height
|
53
|
+
- `#center_x`: center x
|
54
|
+
- `#center_y`: center y
|
50
55
|
- `#contain?(x_or_point, y=nil)`: checks if point is inside
|
51
56
|
|
52
57
|
### `PerfectShape::Square`
|
53
58
|
|
59
|
+
![square](images/square.png)
|
60
|
+
|
54
61
|
- `::new(x: 0, y: 0, length: 1)`: constructs a square
|
55
62
|
- `#x`: top-left x
|
56
63
|
- `#y`: top-left y
|
57
64
|
- `#length`: length
|
58
65
|
- `#width`: width (equal to length)
|
59
66
|
- `#height`: height (equal to length)
|
67
|
+
- `#center_x`: center x
|
68
|
+
- `#center_y`: center y
|
60
69
|
- `#contain?(x_or_point, y=nil)`: checks if point is inside
|
61
70
|
|
62
71
|
### `PerfectShape::Arc`
|
63
72
|
|
64
|
-
|
73
|
+
Arcs can be of type `:open`, `:chord`, or `:pie`
|
74
|
+
|
75
|
+
Open Arc | Chord Arc | Pie Arc
|
76
|
+
---------|-----------|--------
|
77
|
+
![arc-open](images/arc-open.png) | ![arc-chord](images/arc-chord.png) | ![arc-pie](images/arc-pie.png)
|
78
|
+
|
79
|
+
- `::new(type: :open, x: 0, y: 0, width: 1, height: 1, start: 0, extent: 360, center_x: nil, center_y: nil, radius_x: nil, radius_y: nil)`: constructs an arc of type `:open` (default), `:chord`, or `:pie`
|
65
80
|
- `#x`: top-left x of arc
|
66
81
|
- `#y`: top-left y of arc
|
67
82
|
- `#width`: width of arc
|
68
83
|
- `#height`: height of arc
|
69
84
|
- `#start`: start angle in degrees
|
70
85
|
- `#extent`: extent angle in degrees
|
86
|
+
- `#center_x`: center x
|
87
|
+
- `#center_y`: center y
|
88
|
+
- `#radius_x`: radius along the x-axis
|
89
|
+
- `#radius_y`: radius along the y-axis
|
71
90
|
- `#contain?(x_or_point, y=nil)`: checks if point is inside
|
72
91
|
|
73
92
|
## Process
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.4
|
data/lib/perfect_shape/arc.rb
CHANGED
@@ -32,8 +32,15 @@ module PerfectShape
|
|
32
32
|
attr_accessor :type
|
33
33
|
attr_reader :start, :extent
|
34
34
|
|
35
|
-
def initialize(type: :open, x: 0, y: 0, width: 1, height: 1, start: 0, extent: 360)
|
36
|
-
|
35
|
+
def initialize(type: :open, x: 0, y: 0, width: 1, height: 1, start: 0, extent: 360, center_x: nil, center_y: nil, radius_x: nil, radius_y: nil)
|
36
|
+
if center_x && center_y && radius_x && radius_y
|
37
|
+
self.center_x = center_x
|
38
|
+
self.center_y = center_y
|
39
|
+
self.radius_x = radius_x
|
40
|
+
self.radius_y = radius_y
|
41
|
+
else
|
42
|
+
super(x: x, y: y, width: width, height: height)
|
43
|
+
end
|
37
44
|
@type = type
|
38
45
|
self.start = start
|
39
46
|
self.extent = extent
|
@@ -47,6 +54,86 @@ module PerfectShape
|
|
47
54
|
@extent = BigDecimal(value.to_s)
|
48
55
|
end
|
49
56
|
|
57
|
+
def x
|
58
|
+
@center_x && @radius_x ? @center_x - @radius_x : super
|
59
|
+
end
|
60
|
+
|
61
|
+
def y
|
62
|
+
@center_y && @radius_y ? @center_y - @radius_y : super
|
63
|
+
end
|
64
|
+
|
65
|
+
def width
|
66
|
+
@radius_x ? @radius_x * BigDecimal('2.0') : super
|
67
|
+
end
|
68
|
+
|
69
|
+
def height
|
70
|
+
@radius_y ? @radius_y * BigDecimal('2.0') : super
|
71
|
+
end
|
72
|
+
|
73
|
+
# Sets x, normalizing to BigDecimal
|
74
|
+
def x=(value)
|
75
|
+
super
|
76
|
+
@center_x = nil
|
77
|
+
self.width = width if @radius_x
|
78
|
+
end
|
79
|
+
|
80
|
+
# Sets y, normalizing to BigDecimal
|
81
|
+
def y=(value)
|
82
|
+
super
|
83
|
+
@center_y = nil
|
84
|
+
self.height = height if @radius_y
|
85
|
+
end
|
86
|
+
|
87
|
+
# Sets width, normalizing to BigDecimal
|
88
|
+
def width=(value)
|
89
|
+
super
|
90
|
+
@radius_x = nil
|
91
|
+
end
|
92
|
+
|
93
|
+
# Sets height, normalizing to BigDecimal
|
94
|
+
def height=(value)
|
95
|
+
super
|
96
|
+
@radius_y = nil
|
97
|
+
end
|
98
|
+
|
99
|
+
def center_x
|
100
|
+
super || @center_x
|
101
|
+
end
|
102
|
+
|
103
|
+
def center_y
|
104
|
+
super || @center_y
|
105
|
+
end
|
106
|
+
|
107
|
+
def radius_x
|
108
|
+
@width ? @width/BigDecimal('2.0') : @radius_x
|
109
|
+
end
|
110
|
+
|
111
|
+
def radius_y
|
112
|
+
@height ? @height/BigDecimal('2.0') : @radius_y
|
113
|
+
end
|
114
|
+
|
115
|
+
def center_x=(value)
|
116
|
+
@center_x = BigDecimal(value.to_s)
|
117
|
+
@x = nil
|
118
|
+
self.radius_x = radius_x if @width
|
119
|
+
end
|
120
|
+
|
121
|
+
def center_y=(value)
|
122
|
+
@center_y = BigDecimal(value.to_s)
|
123
|
+
@y = nil
|
124
|
+
self.radius_y = radius_y if @height
|
125
|
+
end
|
126
|
+
|
127
|
+
def radius_x=(value)
|
128
|
+
@radius_x = BigDecimal(value.to_s)
|
129
|
+
@width = nil
|
130
|
+
end
|
131
|
+
|
132
|
+
def radius_y=(value)
|
133
|
+
@radius_y = BigDecimal(value.to_s)
|
134
|
+
@height = nil
|
135
|
+
end
|
136
|
+
|
50
137
|
# Checks if arc contains point denoted by point (two-number Array or x, y args)
|
51
138
|
#
|
52
139
|
# @param x The X coordinate of the point to test.
|
@@ -103,34 +190,11 @@ module PerfectShape
|
|
103
190
|
ang_ext = -ang_ext if backwards
|
104
191
|
return true if ang_ext >= 360.0
|
105
192
|
|
106
|
-
angle = normalize_degrees(angle) - normalize_degrees(start)
|
193
|
+
angle = Math.normalize_degrees(angle) - Math.normalize_degrees(start)
|
107
194
|
angle = -angle if backwards
|
108
195
|
angle += 360.0 if angle < 0.0
|
109
196
|
|
110
197
|
(angle >= 0.0) && (angle < ang_ext)
|
111
198
|
end
|
112
|
-
|
113
|
-
# Normalizes the specified angle into the range -180 to 180.
|
114
|
-
# TODO refactor/extract to Math class
|
115
|
-
def normalize_degrees(angle)
|
116
|
-
if angle > 180.0
|
117
|
-
if angle <= (180.0 + 360.0)
|
118
|
-
angle = angle - 360.0
|
119
|
-
else
|
120
|
-
angle = Math.ieee_remainder(angle, 360.0)
|
121
|
-
# IEEEremainder can return -180 here for some input values...
|
122
|
-
angle = 180.0 if angle == -180.0
|
123
|
-
end
|
124
|
-
elsif angle <= -180.0
|
125
|
-
if angle > (-180.0 - 360.0)
|
126
|
-
angle = angle + 360.0
|
127
|
-
else
|
128
|
-
angle = Math.ieee_remainder(angle, 360.0)
|
129
|
-
# IEEEremainder can return -180 here for some input values...
|
130
|
-
angle = 180.0 if angle == -180.0
|
131
|
-
end
|
132
|
-
end
|
133
|
-
angle
|
134
|
-
end
|
135
199
|
end
|
136
200
|
end
|
data/lib/perfect_shape/math.rb
CHANGED
@@ -15,6 +15,28 @@ module PerfectShape
|
|
15
15
|
def degrees_to_radians(degrees)
|
16
16
|
(Math::PI/180)*degrees
|
17
17
|
end
|
18
|
+
|
19
|
+
# Normalizes the specified angle into the range -180 to 180.
|
20
|
+
def normalize_degrees(angle)
|
21
|
+
if angle > 180.0
|
22
|
+
if angle <= (180.0 + 360.0)
|
23
|
+
angle = angle - 360.0
|
24
|
+
else
|
25
|
+
angle = Math.ieee_remainder(angle, 360.0)
|
26
|
+
# IEEEremainder can return -180 here for some input values...
|
27
|
+
angle = 180.0 if angle == -180.0
|
28
|
+
end
|
29
|
+
elsif angle <= -180.0
|
30
|
+
if angle > (-180.0 - 360.0)
|
31
|
+
angle = angle + 360.0
|
32
|
+
else
|
33
|
+
angle = Math.ieee_remainder(angle, 360.0)
|
34
|
+
# IEEEremainder can return -180 here for some input values...
|
35
|
+
angle = 180.0 if angle == -180.0
|
36
|
+
end
|
37
|
+
end
|
38
|
+
angle
|
39
|
+
end
|
18
40
|
|
19
41
|
# Computes the remainder operation on two arguments as prescribed by the IEEE 754 standard.
|
20
42
|
#
|
@@ -53,5 +53,13 @@ module PerfectShape
|
|
53
53
|
def height=(value)
|
54
54
|
@height = BigDecimal(value.to_s)
|
55
55
|
end
|
56
|
+
|
57
|
+
def center_x
|
58
|
+
@x + (@width/BigDecimal('2.0')) if @x && @width
|
59
|
+
end
|
60
|
+
|
61
|
+
def center_y
|
62
|
+
@y + (@height/BigDecimal('2.0')) if @y && @height
|
63
|
+
end
|
56
64
|
end
|
57
65
|
end
|
data/lib/perfect_shape/square.rb
CHANGED
@@ -37,22 +37,20 @@ module PerfectShape
|
|
37
37
|
# Sets length, normalizing to BigDecimal
|
38
38
|
def length=(value)
|
39
39
|
@length = BigDecimal(value.to_s)
|
40
|
+
self.width = value unless width == value
|
41
|
+
self.height = value unless height == value
|
40
42
|
end
|
41
43
|
|
42
44
|
def width=(value)
|
43
|
-
|
45
|
+
super
|
46
|
+
self.length = value unless length == value
|
47
|
+
self.height = value unless height == value
|
44
48
|
end
|
45
49
|
|
46
50
|
def height=(value)
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
def width
|
51
|
-
length
|
52
|
-
end
|
53
|
-
|
54
|
-
def height
|
55
|
-
length
|
51
|
+
super
|
52
|
+
self.length = value unless length == value
|
53
|
+
self.width = value unless width == value
|
56
54
|
end
|
57
55
|
end
|
58
56
|
end
|
data/perfect-shape.gemspec
CHANGED
@@ -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.
|
5
|
+
# stub: perfect-shape 0.0.4 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "perfect-shape".freeze
|
9
|
-
s.version = "0.0.
|
9
|
+
s.version = "0.0.4"
|
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-
|
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, ellipse, circle, polygon, polyline, polybezier, 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-15"
|
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, polybezier, 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",
|
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: 0.0.
|
4
|
+
version: 0.0.4
|
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-
|
11
|
+
date: 2021-12-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rdoc
|
@@ -82,10 +82,10 @@ dependencies:
|
|
82
82
|
version: '0'
|
83
83
|
description: Perfect Shape is a collection of pure Ruby geometric algorithms that
|
84
84
|
are mostly useful for GUI manipulation like checking containment of a mouse click
|
85
|
-
point in popular geometry shapes such as rectangle, square, arc,
|
86
|
-
polygon, polyline, polybezier, and paths containing lines,
|
87
|
-
curves. Additionally, it contains some purely mathematical
|
88
|
-
(also known as IEEE-754 remainder).
|
85
|
+
point in popular geometry shapes such as rectangle, square, arc (open, chord, and
|
86
|
+
pie), ellipse, circle, polygon, polyline, polybezier, and paths containing lines,
|
87
|
+
bezier curves, and quadratic curves. Additionally, it contains some purely mathematical
|
88
|
+
algorithms like IEEEremainder (also known as IEEE-754 remainder).
|
89
89
|
email: andy.am@gmail.com
|
90
90
|
executables: []
|
91
91
|
extensions: []
|