perfect-shape 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +6 -4
- data/VERSION +1 -1
- data/lib/perfect_shape/line.rb +25 -0
- data/lib/perfect_shape/rectangle.rb +39 -0
- data/perfect-shape.gemspec +4 -4
- metadata +10 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ea11a066d120228aeb5889877909e17d93022e44e9c46899088bf97e52a328a6
|
4
|
+
data.tar.gz: 2d9f3031bd0edfa073d20c6c8f8d56541aa473ef92335f6606b88fbe0a9b39f4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8025f51a536223a337d10b8a3b0bb9cd66aefe37543d24108aa002d719c4eb123a5b19d89b00157a85054bd614f92bdaf944562efbbecf14a93ab6d9c0a6481c
|
7
|
+
data.tar.gz: 06701161fbe42ec6afe1f19d9ece0db38d44db679702ea0db420fc260fa19526a2d2b4475c5aaa0d6f0500260ad48ad7267b4da1ec626153749d70175c50e523
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
# Perfect Shape 0.
|
1
|
+
# Perfect Shape 0.5.0
|
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
|
-
[`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 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 [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 [Winding Number Algorithm](https://en.wikipedia.org/wiki/Point_in_polygon#Winding_number_algorithm), aka [Nonzero Rule](https://en.wikipedia.org/wiki/Nonzero-rule)).
|
6
|
+
[`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 [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 [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
7
|
|
8
8
|
Additionally, [`PerfectShape::Math`](#perfectshapemath) contains some purely mathematical algorithms, like [IEEE 754-1985 Remainder](https://en.wikipedia.org/wiki/IEEE_754-1985).
|
9
9
|
|
@@ -14,13 +14,13 @@ To ensure high accuracy, this library does all its mathematical operations with
|
|
14
14
|
Run:
|
15
15
|
|
16
16
|
```
|
17
|
-
gem install perfect-shape -v 0.
|
17
|
+
gem install perfect-shape -v 0.5.0
|
18
18
|
```
|
19
19
|
|
20
20
|
Or include in Bundler `Gemfile`:
|
21
21
|
|
22
22
|
```ruby
|
23
|
-
gem 'perfect-shape', '~> 0.
|
23
|
+
gem 'perfect-shape', '~> 0.5.0'
|
24
24
|
```
|
25
25
|
|
26
26
|
And, run:
|
@@ -220,6 +220,7 @@ Includes `PerfectShape::MultiPoint`
|
|
220
220
|
- `#bounding_box`: bounding box is a rectangle with x = min x, y = min y, and width/height of shape
|
221
221
|
- `#==(other)`: Returns `true` if equal to `other` or `false` otherwise
|
222
222
|
- `#contain?(x_or_point, y=nil, outline: true, distance_tolerance: 0)`: checks if point lies on line, with a distance tolerance (0 by default). Distance tolerance provides a fuzz factor that for example enables GUI users to mouse-click-select a line shape more successfully. `outline` option makes no difference on line
|
223
|
+
- `#intersect?(rectangle)`: Returns `true` if intersecting with interior of rectangle or `false` otherwise. This is useful for GUI optimization checks of whether a shape appears in a GUI viewport rectangle and needs redrawing
|
223
224
|
- `#relative_counterclockwise(x_or_point, y=nil)`: Returns an indicator of where the specified point (px,py) lies with respect to the line segment from (x1,y1) to (x2,y2). The return value can be either 1, -1, or 0 and indicates in which direction the specified line must pivot around its first end point, (x1,y1), in order to point at the specified point (px,py). A return value of 1 indicates that the line segment must turn in the direction that takes the positive X axis towards the negative Y axis. In the default coordinate system, this direction is counterclockwise. A return value of -1 indicates that the line segment must turn in the direction that takes the positive X axis towards the positive Y axis. In the default coordinate system, this direction is clockwise. A return value of 0 indicates that the point lies exactly on the line segment. Note that an indicator value of 0 is rare and not useful for determining collinearity because of floating point rounding issues. If the point is colinear with the line segment, but not between the end points, then the value will be -1 if the point lies “beyond (x1,y1)” or 1 if the point lies “beyond (x2,y2)”.
|
224
225
|
- `#point_distance(x_or_point, y=nil)`: Returns the distance from a point to a line segment.
|
225
226
|
|
@@ -362,6 +363,7 @@ Includes `PerfectShape::RectangularShape`
|
|
362
363
|
- `#==(other)`: Returns `true` if equal to `other` or `false` otherwise
|
363
364
|
- `#contain?(x_or_point, y=nil, outline: false, distance_tolerance: 0)`: checks if point is inside when `outline` is `false` or if point is on the outline when `outline` is `true`. `distance_tolerance` can be used as a fuzz factor when `outline` is `true`, for example, to help GUI users mouse-click-select a rectangle shape from its outline more successfully
|
364
365
|
- `#edges`: edges of rectangle as `PerfectShape::Line` objects
|
366
|
+
- `#out_state(x_or_point, y = nil)`: Returns "out state" of specified point (x,y) (whether it lies to the left, right, top, bottom of rectangle). If point is outside rectangle, it returns a bit mask combination of `Rectangle::OUT_LEFT`, `Rectangle::OUT_RIGHT`, `Rectangle::OUT_TOP`, or `Rectangle::OUT_BOTTOM`. Otherwise, it returns `0` if point is inside the rectangle.
|
365
367
|
|
366
368
|
Example:
|
367
369
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.5.0
|
data/lib/perfect_shape/line.rb
CHANGED
@@ -22,6 +22,7 @@
|
|
22
22
|
require 'perfect_shape/shape'
|
23
23
|
require 'perfect_shape/point'
|
24
24
|
require 'perfect_shape/multi_point'
|
25
|
+
require 'perfect_shape/rectangle'
|
25
26
|
|
26
27
|
module PerfectShape
|
27
28
|
class Line < Shape
|
@@ -241,5 +242,29 @@ module PerfectShape
|
|
241
242
|
return unless x && y
|
242
243
|
Line.point_crossings(points[0][0], points[0][1], points[1][0], points[1][1], x, y)
|
243
244
|
end
|
245
|
+
|
246
|
+
def intersect?(rectangle)
|
247
|
+
x1 = points[0][0]
|
248
|
+
y1 = points[0][1]
|
249
|
+
x2 = points[1][0]
|
250
|
+
y2 = points[1][1]
|
251
|
+
out1 = out2 = nil
|
252
|
+
return true if (out2 = rectangle.out_state(x2, y2)) == 0
|
253
|
+
while (out1 = rectangle.out_state(x1, y1)) != 0
|
254
|
+
return false if (out1 & out2) != 0
|
255
|
+
if (out1 & (Rectangle::OUT_LEFT | Rectangle::OUT_RIGHT)) != 0
|
256
|
+
x = rectangle.x
|
257
|
+
x += rectangle.width if (out1 & Rectangle::OUT_RIGHT) != 0
|
258
|
+
y1 = y1 + (x - x1) * (y2 - y1) / (x2 - x1)
|
259
|
+
x1 = x
|
260
|
+
else
|
261
|
+
y = rectangle.y
|
262
|
+
y += rectangle.height if (out1 & Rectangle::OUT_BOTTOM) != 0
|
263
|
+
x1 = x1 + (y - y1) * (x2 - x1) / (y2 - y1)
|
264
|
+
y1 = y
|
265
|
+
end
|
266
|
+
end
|
267
|
+
true
|
268
|
+
end
|
244
269
|
end
|
245
270
|
end
|
@@ -28,6 +28,18 @@ module PerfectShape
|
|
28
28
|
class Rectangle < Shape
|
29
29
|
include RectangularShape
|
30
30
|
include Equalizer.new(:x, :y, :width, :height)
|
31
|
+
|
32
|
+
# bitmask indicating a point lies to the left
|
33
|
+
OUT_LEFT = 1
|
34
|
+
|
35
|
+
# bitmask indicating a point lies above
|
36
|
+
OUT_TOP = 2
|
37
|
+
|
38
|
+
# bitmask indicating a point lies to the right
|
39
|
+
OUT_RIGHT = 4
|
40
|
+
|
41
|
+
# bitmask indicating a point lies below
|
42
|
+
OUT_BOTTOM = 8
|
31
43
|
|
32
44
|
# Checks if rectangle contains point (two-number Array or x, y args)
|
33
45
|
#
|
@@ -56,5 +68,32 @@ module PerfectShape
|
|
56
68
|
Line.new(points: [[self.x, self.y + height], [self.x, self.y]])
|
57
69
|
]
|
58
70
|
end
|
71
|
+
|
72
|
+
# Returns out state for specified point (x,y): (left, right, top, bottom)
|
73
|
+
#
|
74
|
+
# It can be 0 meaning not outside the rectangle,
|
75
|
+
# or if outside the rectangle, then a bit mask
|
76
|
+
# combination of OUT_LEFT, OUT_RIGHT, OUT_TOP, or OUT_BOTTOM
|
77
|
+
def out_state(x_or_point, y = nil)
|
78
|
+
x, y = Point.normalize_point(x_or_point, y)
|
79
|
+
return unless x && y
|
80
|
+
|
81
|
+
out = 0
|
82
|
+
if self.width <= 0
|
83
|
+
out |= OUT_LEFT | OUT_RIGHT
|
84
|
+
elsif x < self.x
|
85
|
+
out |= OUT_LEFT
|
86
|
+
elsif x > self.x + self.width
|
87
|
+
out |= OUT_RIGHT
|
88
|
+
end
|
89
|
+
if self.height <= 0
|
90
|
+
out |= OUT_TOP | OUT_BOTTOM
|
91
|
+
elsif y < self.y
|
92
|
+
out |= OUT_TOP
|
93
|
+
elsif y > self.y + self.height
|
94
|
+
out |= OUT_BOTTOM
|
95
|
+
end
|
96
|
+
out
|
97
|
+
end
|
59
98
|
end
|
60
99
|
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.
|
5
|
+
# stub: perfect-shape 0.5.0 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "perfect-shape".freeze
|
9
|
-
s.version = "0.
|
9
|
+
s.version = "0.5.0"
|
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-01-
|
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, 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 Ray Casting Algorithm, aka Even-odd Rule, and Winding Number Algorithm, aka Nonzero Rule). Additionally, it contains some purely mathematical algorithms like IEEEremainder (also known as IEEE-754 remainder).".freeze
|
14
|
+
s.date = "2022-01-18"
|
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 Ray Casting Algorithm, aka Even-odd Rule, and 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 = [
|
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.
|
4
|
+
version: 0.5.0
|
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-01-
|
11
|
+
date: 2022-01-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: equalizer
|
@@ -95,14 +95,14 @@ dependencies:
|
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
description: Perfect Shape is a collection of pure Ruby geometric algorithms that
|
98
|
-
are mostly useful for GUI manipulation like checking
|
99
|
-
point in popular geometry shapes such as rectangle,
|
100
|
-
pie), ellipse, circle, polygon, and paths containing
|
101
|
-
and cubic bezier curves, potentially with affine
|
102
|
-
scale, rotation, shear/skew, and inversion
|
103
|
-
aka Even-odd Rule, and Winding Number Algorithm,
|
104
|
-
it contains some purely mathematical algorithms
|
105
|
-
IEEE-754 remainder).
|
98
|
+
are mostly useful for GUI manipulation like checking viewport rectangle intersection
|
99
|
+
or containment of a mouse click point in popular geometry shapes such as rectangle,
|
100
|
+
square, arc (open, chord, and pie), ellipse, circle, polygon, and paths containing
|
101
|
+
lines, quadratic bézier curves, and cubic bezier curves, potentially with affine
|
102
|
+
transforms applied like translation, scale, rotation, shear/skew, and inversion
|
103
|
+
(including both Ray Casting Algorithm, aka Even-odd Rule, and Winding Number Algorithm,
|
104
|
+
aka Nonzero Rule). Additionally, it contains some purely mathematical algorithms
|
105
|
+
like IEEEremainder (also known as IEEE-754 remainder).
|
106
106
|
email: andy.am@gmail.com
|
107
107
|
executables: []
|
108
108
|
extensions: []
|