geometry 6 → 6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -76,7 +76,6 @@ describe Geometry::Rectangle do
76
76
  -> { Rectangle.new height:1 }.must_raise ArgumentError
77
77
  -> { Rectangle.new width:1 }.must_raise ArgumentError
78
78
  end
79
-
80
79
  end
81
80
 
82
81
  describe "comparison" do
@@ -86,6 +85,24 @@ describe Geometry::Rectangle do
86
85
  end
87
86
  end
88
87
 
88
+ describe "inset" do
89
+ subject { Rectangle.new [0,0], [10,10] }
90
+
91
+ it "must inset equally" do
92
+ subject.inset(1).must_equal Rectangle.new [1,1], [9,9]
93
+ end
94
+
95
+ it "must inset vertically and horizontally" do
96
+ subject.inset(1,2).must_equal Rectangle.new [1,2], [9,8]
97
+ subject.inset(x:1, y:2).must_equal Rectangle.new [1,2], [9,8]
98
+ end
99
+
100
+ it "must inset from individual sides" do
101
+ subject.inset(1,2,3,4).must_equal Rectangle.new [2,3], [6,9]
102
+ subject.inset(top:1, left:2, bottom:3, right:4).must_equal Rectangle.new [2,3], [6,9]
103
+ end
104
+ end
105
+
89
106
  describe "properties" do
90
107
  subject { Rectangle.new [1,2], [3,4] }
91
108
  let(:rectangle) { Rectangle [1,2], [3,4] }
@@ -6,6 +6,7 @@ describe Geometry::RegularPolygon do
6
6
 
7
7
  describe "when constructed with named center and radius arguments" do
8
8
  let(:polygon) { RegularPolygon.new sides:4, center:[1,2], radius:3 }
9
+ subject { RegularPolygon.new sides:4, center:[1,2], radius:3 }
9
10
 
10
11
  it "must create a RegularPolygon" do
11
12
  polygon.must_be_instance_of(RegularPolygon)
@@ -26,6 +27,12 @@ describe Geometry::RegularPolygon do
26
27
  it "must compare equal" do
27
28
  polygon.must_equal RegularPolygon.new(sides:4, center:[1,2], radius:3)
28
29
  end
30
+
31
+ describe "properties" do
32
+ it "must have vertices" do
33
+ subject.vertices.must_equal [Point[4.0, 2.0], Point[1.0000000000000002, 5.0], Point[-2.0, 2.0000000000000004], Point[0.9999999999999994, -1.0]]
34
+ end
35
+ end
29
36
  end
30
37
 
31
38
  describe "when constructed with a center and diameter" do
@@ -69,8 +76,8 @@ describe Geometry::RegularPolygon do
69
76
  polygon.edge_count.must_equal 4
70
77
  end
71
78
 
72
- it "must have a nil center" do
73
- polygon.center.must_be_nil
79
+ it "must be at the origin" do
80
+ polygon.center.must_equal Point.zero
74
81
  end
75
82
 
76
83
  it "must have a diameter" do
@@ -81,4 +88,33 @@ describe Geometry::RegularPolygon do
81
88
  polygon.radius.must_equal 2
82
89
  end
83
90
  end
91
+
92
+ describe "properties" do
93
+ subject { RegularPolygon.new sides:6, diameter:4 }
94
+
95
+ it "must have edges" do
96
+ expected_edges = [Edge(Point[2, 0], Point[1, 1.732]), Edge(Point[1, 1.732], Point[-1, 1.732]), Edge(Point[-1, 1.732], Point[-2, 0]), Edge(Point[-2, 0], Point[-1, -1.732]), Edge(Point[-1, -1.732], Point[1, -1.732]), Edge(Point[1, -1.732], Point[2, 0])]
97
+ subject.edges.zip(expected_edges) do |edge1, edge2|
98
+ edge1.to_a.zip(edge2.to_a) do |point1, point2|
99
+ point1.to_a.zip(point2.to_a) {|a, b| a.must_be_close_to b }
100
+ end
101
+ end
102
+ end
103
+
104
+ it "must have a bounds property that returns a Rectangle" do
105
+ subject.bounds.must_equal Rectangle.new([-2,-2], [2,2])
106
+ end
107
+
108
+ it "must have a minmax property that returns the corners of the bounding rectangle" do
109
+ subject.minmax.must_equal [Point[-2,-2], Point[2,2]]
110
+ end
111
+
112
+ it "must have a max property that returns the upper right corner of the bounding rectangle" do
113
+ subject.max.must_equal Point[2,2]
114
+ end
115
+
116
+ it "must have a min property that returns the lower left corner of the bounding rectangle" do
117
+ subject.min.must_equal Point[-2,-2]
118
+ end
119
+ end
84
120
  end
@@ -2,7 +2,29 @@ require 'minitest/autorun'
2
2
  require 'geometry/rotation'
3
3
 
4
4
  describe Geometry::Rotation do
5
+ Point = Geometry::Point
5
6
  Rotation = Geometry::Rotation
7
+ RotationAngle = Geometry::RotationAngle
8
+
9
+ describe "when constructed" do
10
+ it "must accept a rotation angle" do
11
+ rotation = Rotation.new angle:Math::PI/2
12
+ rotation.must_be_instance_of(RotationAngle)
13
+ rotation.angle.must_equal Math::PI/2
14
+ rotation.x.x.must_be_close_to 0
15
+ rotation.x.y.must_be_close_to 1
16
+ rotation.y.x.must_be_close_to -1
17
+ rotation.y.y.must_be_close_to 0
18
+ end
19
+
20
+ it "must accept an X axis" do
21
+ rotation = Rotation.new x:[1,0]
22
+ rotation.must_be_instance_of(RotationAngle)
23
+ rotation.angle.must_equal 0
24
+ rotation.x.must_equal Point[1,0]
25
+ rotation.y.must_equal Point[0,1]
26
+ end
27
+ end
6
28
 
7
29
  it "must accept x and y axes" do
8
30
  rotation = Geometry::Rotation.new :x => [1,2,3], :y => [4,5,6]
@@ -45,4 +67,42 @@ describe Geometry::Rotation do
45
67
  Rotation.new(x:[1,2,3], y:[4,5,6]).must_equal Rotation.new(x:[1,2,3], y:[4,5,6])
46
68
  end
47
69
  end
70
+
71
+ describe "comparison" do
72
+ it "must equate equal angles" do
73
+ Rotation.new(angle:45).must_equal Rotation.new(angle:45)
74
+ end
75
+
76
+ it "must not equate unequal angles" do
77
+ Rotation.new(angle:10).wont_equal Rotation.new(angle:45)
78
+ end
79
+ end
80
+
81
+ describe "composition" do
82
+ it "must add angles" do
83
+ (Rotation.new(angle:45) + Rotation.new(angle:45)).must_equal Rotation.new(angle:90)
84
+ end
85
+
86
+ it "must subtract angles" do
87
+ (Rotation.new(angle:45) - Rotation.new(angle:45)).must_equal Rotation.new(angle:0)
88
+ end
89
+
90
+ it "must negate angles" do
91
+ (-Rotation.new(angle:45)).must_equal Rotation.new(angle:-45)
92
+ end
93
+ end
94
+
95
+ describe "when transforming a Point" do
96
+ describe "when no rotation is set" do
97
+ it "must return the Point" do
98
+ Rotation.new.transform(Point[1,0]).must_equal Point[1,0]
99
+ end
100
+ end
101
+
102
+ it "must rotate" do
103
+ rotated_point = Rotation.new(angle:Math::PI/2).transform(Point[1,0])
104
+ rotated_point.x.must_be_close_to 0
105
+ rotated_point.y.must_be_close_to 1
106
+ end
107
+ end
48
108
  end
@@ -58,46 +58,112 @@ describe Geometry::Transformation do
58
58
  end
59
59
 
60
60
  describe "rotation" do
61
- it "must accept an x axis option" do
62
- t = Transformation.new :x => [0,1]
63
- t.rotation.x.must_equal [0,1]
64
- t.identity?.wont_equal true
65
- end
66
-
67
61
  it "must accept a y axis option" do
68
62
  t = Transformation.new :y => [1,0]
69
63
  t.rotation.y.must_equal [1,0]
70
64
  t.identity?.wont_equal true
71
65
  end
66
+
67
+ it "must accept a rotation angle" do
68
+ transformation = Transformation.new angle:90
69
+ transformation.identity?.wont_equal true
70
+ transformation.rotation.wont_be_nil
71
+ transformation.rotation.angle.must_equal 90
72
+ end
73
+
74
+ it "must accept a rotation angle specified by an X-axis" do
75
+ transformation = Transformation.new x:[0,1]
76
+ rotation = transformation.rotation
77
+ rotation.must_be_instance_of(RotationAngle)
78
+ rotation.angle.must_equal Math::PI/2
79
+ rotation.x.x.must_be_close_to 0
80
+ rotation.x.y.must_be_close_to 1
81
+ rotation.y.x.must_be_close_to -1
82
+ rotation.y.y.must_be_close_to 0
83
+ end
72
84
  end
73
85
  end
74
86
 
75
87
  describe "comparison" do
88
+ subject { Transformation.new(origin:[1,2]) }
89
+
76
90
  it "must equate equal transformations" do
77
- Transformation.new(origin:[1,2]).must_equal Transformation.new(origin:[1,2])
91
+ subject.must_equal Transformation.new(origin:[1,2])
92
+ end
93
+
94
+ it "must not equal nil" do
95
+ subject.eql?(nil).wont_equal true
96
+ end
97
+
98
+ it "must not equate a translation with a rotation" do
99
+ subject.wont_equal Transformation.new(x:[0,1,0], y:[1,0,0])
100
+ end
101
+
102
+ it "must equate empty transformations" do
103
+ Transformation.new.must_equal Transformation.new
104
+ end
105
+ end
106
+
107
+ describe "attributes" do
108
+ describe "has_rotation?" do
109
+ it "must properly be true" do
110
+ Transformation.new(angle:90).has_rotation?.must_equal true
111
+ end
112
+
113
+ it "must properly be false" do
114
+ Transformation.new.has_rotation?.must_equal false
115
+ end
78
116
  end
79
117
  end
80
118
 
81
119
  describe "composition" do
120
+ let(:translate_left) { Geometry::Transformation.new origin:[-2,-2] }
121
+ let(:translate_right) { Geometry::Transformation.new origin:[1,1] }
82
122
  let(:transformation) { Geometry::Transformation.new }
83
123
 
124
+ it "must add pure translation" do
125
+ (translate_left + translate_right).must_equal Geometry::Transformation.new origin:[-1,-1]
126
+ end
127
+
128
+ it "must add translation and no translation" do
129
+ (transformation + translate_left).must_equal translate_left
130
+ (translate_left + transformation).must_equal translate_left
131
+ end
132
+
84
133
  it "array addition" do
85
134
  (transformation + [1,2]).translation.must_equal Point[1,2]
86
135
  ((transformation + [1,2]) + [2,3]).translation.must_equal Point[3,5]
87
- (transformation + [1,2]).rotation.identity?.must_equal true
136
+ (transformation + [1,2]).rotation.must_be_nil
88
137
  end
89
138
 
90
139
  it "must update the translation when an array is subtracted" do
91
140
  (transformation - [1,2]).translation.must_equal Point[-1,-2]
92
141
  ((transformation - [1,2]) - [2,3]).translation.must_equal Point[-3,-5]
93
- (transformation - [1,2,3]).rotation.identity?.must_equal true
142
+ (transformation - [1,2,3]).rotation.must_be_nil
143
+ end
144
+
145
+ it "must subtract translation and no translation" do
146
+ (transformation - translate_left).must_equal translate_left
147
+ (translate_left - transformation).must_equal translate_left
94
148
  end
95
149
  end
96
150
 
97
151
  describe "when transforming a Point" do
152
+ describe "when no transformation is set" do
153
+ it "must return the Point" do
154
+ Transformation.new.transform(Point[1,2]).must_equal Point[1,2];
155
+ end
156
+ end
157
+
98
158
  it "must translate" do
99
159
  Geometry::Transformation.new(origin:[0,1]).transform([1,0]).must_equal Point[1,1]
100
160
  end
101
- end
102
161
 
162
+ it "must rotate" do
163
+ rotated_point = Transformation.new(angle:Math::PI/2).transform([1,0])
164
+ rotated_point.x.must_be_close_to 0
165
+ rotated_point.y.must_be_close_to 1
166
+ end
167
+
168
+ end
103
169
  end
@@ -0,0 +1,49 @@
1
+ require 'minitest/autorun'
2
+ require 'geometry/transformation/composition'
3
+
4
+ describe Geometry::Transformation::Composition do
5
+ Composition = Geometry::Transformation::Composition
6
+ Transformation = Geometry::Transformation
7
+
8
+ subject { Composition.new }
9
+
10
+ describe "when constructed" do
11
+ it "must accept multiple transformations" do
12
+ composition = Composition.new(Transformation.new, Transformation.new)
13
+ composition.size.must_equal 2
14
+ end
15
+
16
+ it "must reject anything that isn't a Transformation" do
17
+ -> { Composition.new :foo }.must_raise TypeError
18
+ end
19
+ end
20
+
21
+ describe "attributes" do
22
+ describe "has_rotation?" do
23
+ it "must properly be true" do
24
+ Composition.new(Transformation.new angle:90).has_rotation?.must_equal true
25
+ end
26
+
27
+ it "must properly be false" do
28
+ subject.has_rotation?.must_equal false
29
+ end
30
+ end
31
+ end
32
+
33
+ describe "when composing" do
34
+ it "must append a Transformation" do
35
+ (Composition.new(Transformation.new) + Transformation.new).size.must_equal 2
36
+ end
37
+
38
+ it "must merge with a Composition" do
39
+ (Composition.new(Transformation.new) + Composition.new(Transformation.new)).size.must_equal 2
40
+ end
41
+ end
42
+
43
+ describe "when transforming a Point" do
44
+ it "must handle composed translations" do
45
+ composition = Composition.new(Transformation.new origin:[1,2]) + Composition.new(Transformation.new [3,4])
46
+ composition.transform(Point[5,6]).must_equal Point[9, 12]
47
+ end
48
+ end
49
+ end
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: geometry
3
3
  version: !ruby/object:Gem::Version
4
- version: '6'
5
- prerelease:
4
+ version: '6.1'
6
5
  platform: ruby
7
6
  authors:
8
7
  - Brandon Fosdick
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-05-18 00:00:00.000000000 Z
11
+ date: 2014-01-13 00:00:00.000000000 Z
13
12
  dependencies: []
14
13
  description: Geometric primitives and algorithms for Ruby
15
14
  email:
@@ -43,6 +42,7 @@ files:
43
42
  - lib/geometry/size_zero.rb
44
43
  - lib/geometry/square.rb
45
44
  - lib/geometry/transformation.rb
45
+ - lib/geometry/transformation/composition.rb
46
46
  - lib/geometry/triangle.rb
47
47
  - lib/geometry/vector.rb
48
48
  - test/geometry.rb
@@ -63,37 +63,31 @@ files:
63
63
  - test/geometry/size_zero.rb
64
64
  - test/geometry/square.rb
65
65
  - test/geometry/transformation.rb
66
+ - test/geometry/transformation/composition.rb
66
67
  - test/geometry/triangle.rb
67
68
  - test/geometry/vector.rb
68
69
  homepage: http://github.com/bfoz/geometry
69
70
  licenses: []
71
+ metadata: {}
70
72
  post_install_message:
71
73
  rdoc_options: []
72
74
  require_paths:
73
75
  - lib
74
76
  required_ruby_version: !ruby/object:Gem::Requirement
75
- none: false
76
77
  requirements:
77
- - - ! '>='
78
+ - - '>='
78
79
  - !ruby/object:Gem::Version
79
80
  version: '0'
80
- segments:
81
- - 0
82
- hash: -1868771796100540308
83
81
  required_rubygems_version: !ruby/object:Gem::Requirement
84
- none: false
85
82
  requirements:
86
- - - ! '>='
83
+ - - '>='
87
84
  - !ruby/object:Gem::Version
88
85
  version: '0'
89
- segments:
90
- - 0
91
- hash: -1868771796100540308
92
86
  requirements: []
93
87
  rubyforge_project: geometry
94
- rubygems_version: 1.8.25
88
+ rubygems_version: 2.1.11
95
89
  signing_key:
96
- specification_version: 3
90
+ specification_version: 4
97
91
  summary: Geometric primitives and algoritms
98
92
  test_files:
99
93
  - test/geometry.rb
@@ -114,5 +108,6 @@ test_files:
114
108
  - test/geometry/size_zero.rb
115
109
  - test/geometry/square.rb
116
110
  - test/geometry/transformation.rb
111
+ - test/geometry/transformation/composition.rb
117
112
  - test/geometry/triangle.rb
118
113
  - test/geometry/vector.rb