geometry 0 → 1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/LICENSE +21 -0
- data/{README → README.markdown} +0 -0
- data/geometry.gemspec +1 -1
- data/lib/geometry.rb +19 -3
- data/lib/geometry/line.rb +114 -0
- data/lib/geometry/point.rb +45 -0
- data/test/test_geometry.rb +15 -0
- data/test/test_line.rb +1 -1
- data/test/test_point.rb +4 -10
- metadata +8 -5
- data/lib/line.rb +0 -85
- data/lib/point.rb +0 -39
data/.gitignore
CHANGED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Copyright (c) 2012, Brandon Fosdick <bfoz@bfoz.net>
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
5
|
+
that the following conditions are met:
|
6
|
+
|
7
|
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the
|
8
|
+
following disclaimer.
|
9
|
+
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
|
10
|
+
the following disclaimer in the documentation and/or other materials provided with the distribution.
|
11
|
+
|
12
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
13
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
14
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
15
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
16
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
17
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
18
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
19
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
20
|
+
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
21
|
+
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/{README → README.markdown}
RENAMED
File without changes
|
data/geometry.gemspec
CHANGED
data/lib/geometry.rb
CHANGED
@@ -1,6 +1,22 @@
|
|
1
|
-
require_relative 'point'
|
2
|
-
require_relative 'line'
|
1
|
+
require_relative 'geometry/point'
|
2
|
+
require_relative 'geometry/line'
|
3
3
|
|
4
4
|
module Geometry
|
5
|
-
|
5
|
+
# :call-seq:
|
6
|
+
# Line[Array, Array] -> TwoPointLine
|
7
|
+
# Line[Point, Point] -> TwoPointLine
|
8
|
+
# Line[Vector, Vector] -> TwoPointLine
|
9
|
+
# Line[y-intercept, slope] -> SlopeInterceptLine
|
10
|
+
# Line[point, slope] -> PointSlopeLine
|
11
|
+
def self.Line(*args)
|
12
|
+
Geometry::Line[*args]
|
13
|
+
end
|
14
|
+
|
15
|
+
# :call-seq:
|
16
|
+
# Point[x,y,z,...]
|
17
|
+
# Point[Point]
|
18
|
+
# Point[Vector]
|
19
|
+
def self.Point(*args)
|
20
|
+
Geometry::Point[*args]
|
21
|
+
end
|
6
22
|
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require_relative 'point'
|
2
|
+
|
3
|
+
module Geometry
|
4
|
+
|
5
|
+
=begin rdoc
|
6
|
+
A cluster of objects representing a Line of infinite length
|
7
|
+
|
8
|
+
Supports two-point, slope-intercept, and point-slope initializer forms
|
9
|
+
|
10
|
+
== Usage
|
11
|
+
|
12
|
+
=== Two-point constructors
|
13
|
+
line = Geometry::Line[[0,0], [10,10]]
|
14
|
+
line = Geometry::Line[Geometry::Point[0,0], Geometry::Point[10,10]]
|
15
|
+
line = Geometry::Line[Vector[0,0], Vector[10,10]]
|
16
|
+
|
17
|
+
=== Slope-intercept constructors
|
18
|
+
Geometry::Line[Rational(3,4), 5] # Slope = 3/4, Intercept = 5
|
19
|
+
Geometry::Line[0.75, 5]
|
20
|
+
|
21
|
+
=== Point-slope constructors
|
22
|
+
Geometry::Line(Geometry::Point[0,0], 0.75)
|
23
|
+
Geometry::Line(Vector[0,0], Rational(3,4))
|
24
|
+
|
25
|
+
=== Special constructors (2D only)
|
26
|
+
Geometry::Line.horizontal(y=0)
|
27
|
+
Geometry::Line.vertical(x=0)
|
28
|
+
=end
|
29
|
+
class Line
|
30
|
+
|
31
|
+
# :call-seq:
|
32
|
+
# Line[Array, Array] -> TwoPointLine
|
33
|
+
# Line[Point, Point] -> TwoPointLine
|
34
|
+
# Line[Vector, Vector] -> TwoPointLine
|
35
|
+
# Line[y-intercept, slope] -> SlopeInterceptLine
|
36
|
+
# Line[point, slope] -> PointSlopeLine
|
37
|
+
def self.[](*args)
|
38
|
+
if( 2 == args.size )
|
39
|
+
args.map! {|x| x.is_a?(Array) ? Point[*x] : x}
|
40
|
+
|
41
|
+
# If both args are Points, create a TwoPointLine
|
42
|
+
return TwoPointLine.new(*args) if args.all? {|x| x.is_a?(Vector)}
|
43
|
+
|
44
|
+
# If only the first arg is a Point, create a PointSlopeLine
|
45
|
+
return PointSlopeLine.new(*args) if args.first.is_a?(Vector)
|
46
|
+
|
47
|
+
# Otherise, create a SlopeInterceptLine
|
48
|
+
return SlopeInterceptLine.new(*args)
|
49
|
+
else
|
50
|
+
nil
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.horizontal(y_intercept=0)
|
55
|
+
SlopeInterceptLine.new(0, y_intercept)
|
56
|
+
end
|
57
|
+
def self.vertical(x_intercept=0)
|
58
|
+
SlopeInterceptLine.new(1/0.0, x_intercept)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class PointSlopeLine < Line # :nodoc:
|
63
|
+
def initialize(point, slope)
|
64
|
+
@point = point.is_a?(Geometry::Point) ? point : Geometry.Point(point)
|
65
|
+
@slope = slope
|
66
|
+
end
|
67
|
+
def to_s
|
68
|
+
'Line(' + @slope.to_s + ',' + @point.to_s + ')'
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
class SlopeInterceptLine < Line # :nodoc:
|
73
|
+
def initialize(slope, intercept)
|
74
|
+
@slope = slope
|
75
|
+
@intercept = intercept
|
76
|
+
end
|
77
|
+
|
78
|
+
def horizontal?
|
79
|
+
0 == @slope
|
80
|
+
end
|
81
|
+
def vertical?
|
82
|
+
(1/0.0) == @slope
|
83
|
+
end
|
84
|
+
|
85
|
+
def intercept(axis=:y)
|
86
|
+
case axis
|
87
|
+
when :x
|
88
|
+
vertical? ? @intercept : (horizontal? ? nil : (-@intercept/@slope))
|
89
|
+
when :y
|
90
|
+
vertical? ? nil : @intercept
|
91
|
+
end
|
92
|
+
end
|
93
|
+
def slope
|
94
|
+
@slope
|
95
|
+
end
|
96
|
+
|
97
|
+
def to_s
|
98
|
+
'Line(' + @slope.to_s + ',' + @intercept.to_s + ')'
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
class TwoPointLine < Line # :nodoc:
|
103
|
+
attr_reader :first, :last
|
104
|
+
|
105
|
+
def initialize(point0, point1)
|
106
|
+
@first, @last = [point0, point1].map {|p| p.is_a?(Point) ? p : Point[p] }
|
107
|
+
end
|
108
|
+
def inspect
|
109
|
+
'Line(' + @first.to_s + ', ' + @last.to_s + ')'
|
110
|
+
end
|
111
|
+
alias :to_s :inspect
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'matrix'
|
2
|
+
|
3
|
+
module Geometry
|
4
|
+
class Point < Vector
|
5
|
+
# An object repesenting a Point in N-dimensional space
|
6
|
+
#
|
7
|
+
# Supports all of the familiar Vector methods and adds convenience
|
8
|
+
# accessors for those variables you learned to hate in your high school
|
9
|
+
# geometry class (x, y, z).
|
10
|
+
#
|
11
|
+
# *Usage*
|
12
|
+
#
|
13
|
+
# point = Geometry::Point[x,y]
|
14
|
+
|
15
|
+
# :call-seq:
|
16
|
+
# Point[x,y,z,...]
|
17
|
+
# Point[Point]
|
18
|
+
# Point[Vector]
|
19
|
+
#
|
20
|
+
# Allow vector-style initialization, but override to support copy-init
|
21
|
+
# from Vector or another Point
|
22
|
+
def self.[](*array)
|
23
|
+
array = array[0] if array[0].is_a?(Array)
|
24
|
+
array = array[0].to_a if array[0].is_a?(Vector)
|
25
|
+
super *array
|
26
|
+
end
|
27
|
+
|
28
|
+
def inspect # :nodoc:
|
29
|
+
'Point' + @elements.inspect
|
30
|
+
end
|
31
|
+
def to_s # :nodoc:
|
32
|
+
'Point' + @elements.to_s
|
33
|
+
end
|
34
|
+
|
35
|
+
def x
|
36
|
+
@elements[0]
|
37
|
+
end
|
38
|
+
def y
|
39
|
+
@elements[1]
|
40
|
+
end
|
41
|
+
def z
|
42
|
+
@elements[2]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require_relative 'test_unit_extensions'
|
3
|
+
require_relative '../lib/geometry'
|
4
|
+
|
5
|
+
class GeometryTest < Test::Unit::TestCase
|
6
|
+
must "create a Point object" do
|
7
|
+
point = Geometry.Point(2,1)
|
8
|
+
assert_kind_of(Geometry::Point, point)
|
9
|
+
end
|
10
|
+
must "create a Line object" do
|
11
|
+
line = Geometry.Line([0,0], [10,10])
|
12
|
+
assert_kind_of(Geometry::Line, line)
|
13
|
+
assert_kind_of(Geometry::TwoPointLine, line)
|
14
|
+
end
|
15
|
+
end
|
data/test/test_line.rb
CHANGED
data/test/test_point.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'test/unit'
|
2
2
|
require_relative 'test_unit_extensions'
|
3
|
-
require_relative '../lib/point'
|
3
|
+
require_relative '../lib/geometry/point'
|
4
4
|
|
5
5
|
class PointTest < Test::Unit::TestCase
|
6
6
|
must "create a Point object using list syntax" do
|
@@ -10,31 +10,25 @@ class PointTest < Test::Unit::TestCase
|
|
10
10
|
assert_equal(1, point.y)
|
11
11
|
end
|
12
12
|
must "create a Point object from an array" do
|
13
|
-
point = Geometry::Point([3,4])
|
14
|
-
assert_equal(2, point.size)
|
15
|
-
assert_equal(3, point.x)
|
16
|
-
assert_equal(4, point.y)
|
17
|
-
end
|
18
|
-
must "create a Point object from an array using list syntax" do
|
19
13
|
point = Geometry::Point[[3,4]]
|
20
14
|
assert_equal(2, point.size)
|
21
15
|
assert_equal(3, point.x)
|
22
16
|
assert_equal(4, point.y)
|
23
17
|
end
|
24
18
|
must "create a Point object from individual parameters" do
|
25
|
-
point = Geometry
|
19
|
+
point = Geometry::Point[3,4]
|
26
20
|
assert_equal(2, point.size)
|
27
21
|
assert_equal(3, point.x)
|
28
22
|
assert_equal(4, point.y)
|
29
23
|
end
|
30
24
|
must "create a Point object from a Vector" do
|
31
|
-
point = Geometry
|
25
|
+
point = Geometry::Point[Vector[3,4]]
|
32
26
|
assert_equal(2, point.size)
|
33
27
|
assert_equal(3, point.x)
|
34
28
|
assert_equal(4, point.y)
|
35
29
|
end
|
36
30
|
must "create a Point object from a Point" do
|
37
|
-
point = Geometry
|
31
|
+
point = Geometry::Point[Geometry::Point[3,4]]
|
38
32
|
assert_equal(2, point.size)
|
39
33
|
assert_equal(3, point.x)
|
40
34
|
assert_equal(4, point.y)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: geometry
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '
|
4
|
+
version: '1'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-03-
|
12
|
+
date: 2012-03-09 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Geometric primitives and algorithms for Ruby
|
15
15
|
email:
|
@@ -20,12 +20,14 @@ extra_rdoc_files: []
|
|
20
20
|
files:
|
21
21
|
- .gitignore
|
22
22
|
- Gemfile
|
23
|
-
-
|
23
|
+
- LICENSE
|
24
|
+
- README.markdown
|
24
25
|
- Rakefile
|
25
26
|
- geometry.gemspec
|
26
27
|
- lib/geometry.rb
|
27
|
-
- lib/line.rb
|
28
|
-
- lib/point.rb
|
28
|
+
- lib/geometry/line.rb
|
29
|
+
- lib/geometry/point.rb
|
30
|
+
- test/test_geometry.rb
|
29
31
|
- test/test_line.rb
|
30
32
|
- test/test_point.rb
|
31
33
|
- test/test_unit_extensions.rb
|
@@ -54,6 +56,7 @@ signing_key:
|
|
54
56
|
specification_version: 3
|
55
57
|
summary: Geometric primitives and algoritms
|
56
58
|
test_files:
|
59
|
+
- test/test_geometry.rb
|
57
60
|
- test/test_line.rb
|
58
61
|
- test/test_point.rb
|
59
62
|
- test/test_unit_extensions.rb
|
data/lib/line.rb
DELETED
@@ -1,85 +0,0 @@
|
|
1
|
-
require_relative 'point'
|
2
|
-
|
3
|
-
module Geometry
|
4
|
-
class Line
|
5
|
-
def self.[](*args)
|
6
|
-
Geometry.Line(*args)
|
7
|
-
end
|
8
|
-
def self.horizontal(y_intercept=0)
|
9
|
-
SlopeInterceptLine.new(0, y_intercept)
|
10
|
-
end
|
11
|
-
def self.vertical(x_intercept=0)
|
12
|
-
SlopeInterceptLine.new(1/0.0, x_intercept)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
class PointSlopeLine < Line
|
17
|
-
def initialize(point, slope)
|
18
|
-
@point = point.is_a?(Geometry::Point) ? point : Geometry.Point(point)
|
19
|
-
@slope = slope
|
20
|
-
end
|
21
|
-
def to_s
|
22
|
-
'Line(' + @slope.to_s + ',' + @point.to_s + ')'
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
class SlopeInterceptLine < Line
|
27
|
-
def initialize(slope, intercept)
|
28
|
-
@slope = slope
|
29
|
-
@intercept = intercept
|
30
|
-
end
|
31
|
-
|
32
|
-
def horizontal?
|
33
|
-
0 == @slope
|
34
|
-
end
|
35
|
-
def vertical?
|
36
|
-
(1/0.0) == @slope
|
37
|
-
end
|
38
|
-
|
39
|
-
def intercept(axis=:y)
|
40
|
-
case axis
|
41
|
-
when :x
|
42
|
-
vertical? ? @intercept : (horizontal? ? nil : (-@intercept/@slope))
|
43
|
-
when :y
|
44
|
-
vertical? ? nil : @intercept
|
45
|
-
end
|
46
|
-
end
|
47
|
-
def slope
|
48
|
-
@slope
|
49
|
-
end
|
50
|
-
|
51
|
-
def to_s
|
52
|
-
'Line(' + @slope.to_s + ',' + @intercept.to_s + ')'
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
class TwoPointLine < Line
|
57
|
-
attr_reader :first, :last
|
58
|
-
|
59
|
-
def initialize(point0, point1)
|
60
|
-
@first, @last = [point0, point1].map {|p| p.is_a?(Point) ? p : Geometry.Point(p) }
|
61
|
-
end
|
62
|
-
def inspect
|
63
|
-
'Line(' + @first.to_s + ', ' + @last.to_s + ')'
|
64
|
-
end
|
65
|
-
alias :to_s :inspect
|
66
|
-
end
|
67
|
-
|
68
|
-
def self.Line(*args)
|
69
|
-
if( 2 == args.size )
|
70
|
-
args.map! {|x| x.is_a?(Array) ? Point[*x] : x}
|
71
|
-
|
72
|
-
# If both args are Points, create a TwoPointLine
|
73
|
-
return TwoPointLine.new(*args) if args.all? {|x| x.is_a?(Vector)}
|
74
|
-
|
75
|
-
# If only the first arg is a Point, create a PointSlopeLine
|
76
|
-
return PointSlopeLine.new(*args) if args.first.is_a?(Vector)
|
77
|
-
|
78
|
-
# Otherise, create a SlopeInterceptLine
|
79
|
-
return SlopeInterceptLine.new(*args)
|
80
|
-
else
|
81
|
-
nil
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
data/lib/point.rb
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
require 'matrix'
|
2
|
-
|
3
|
-
module Geometry
|
4
|
-
class Point < Vector
|
5
|
-
|
6
|
-
# Custom accessors to enable a more natural notation
|
7
|
-
def x
|
8
|
-
@elements[0]
|
9
|
-
end
|
10
|
-
def y
|
11
|
-
@elements[1]
|
12
|
-
end
|
13
|
-
def z
|
14
|
-
@elements[2]
|
15
|
-
end
|
16
|
-
|
17
|
-
# Allow vector-style initialization, but override to
|
18
|
-
# support copy-init from another Vector or Point
|
19
|
-
def self.[](*array)
|
20
|
-
array = array[0] if array[0].is_a?(Array)
|
21
|
-
return Point[*(array[0].to_a)] if array[0].is_a?(Vector)
|
22
|
-
super *array
|
23
|
-
end
|
24
|
-
|
25
|
-
def inspect
|
26
|
-
'Point' + @elements.inspect
|
27
|
-
end
|
28
|
-
def to_s
|
29
|
-
'Point' + @elements.to_s
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
end
|
34
|
-
|
35
|
-
def Geometry.Point(*args)
|
36
|
-
args[0] = args[0].to_a if args[0].is_a?(Vector)
|
37
|
-
args = args[0] if args[0].is_a?(Array)
|
38
|
-
Geometry::Point[*args]
|
39
|
-
end
|