geometry 5 → 6

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.
@@ -29,7 +29,7 @@ describe Geometry::Path do
29
29
  end
30
30
 
31
31
  it "with Points and Arcs" do
32
- path = Geometry::Path.new [0,0], [1.0,0.0], Geometry::Arc.new([1,1], 1, -90*Math::PI/180, 0), [2.0,1.0], [1,2]
32
+ path = Geometry::Path.new [0,0], [1.0,0.0], Arc.new(center:[1,1], radius:1, start:-90*Math::PI/180, end:0), [2.0,1.0], [1,2]
33
33
  path.elements.size.must_equal 3
34
34
  path.elements[0].must_be_kind_of Geometry::Edge
35
35
  path.elements[1].must_be_kind_of Geometry::Arc
@@ -37,7 +37,7 @@ describe Geometry::Path do
37
37
  end
38
38
 
39
39
  it "with Edges and Arcs" do
40
- path = Geometry::Path.new Edge.new([0,0], [1.0,0.0]), Geometry::Arc.new([1,1], 1, -90*Math::PI/180, 0), Edge.new([2.0,1.0], [1,2])
40
+ path = Geometry::Path.new Edge.new([0,0], [1.0,0.0]), Arc.new(center:[1,1], radius:1, start:-90*Math::PI/180, end:0), Edge.new([2.0,1.0], [1,2])
41
41
  path.elements.size.must_equal 3
42
42
  path.elements[0].must_be_kind_of Geometry::Edge
43
43
  path.elements[1].must_be_kind_of Geometry::Arc
@@ -45,7 +45,7 @@ describe Geometry::Path do
45
45
  end
46
46
 
47
47
  it "with disjoint Edges and Arcs" do
48
- path = Geometry::Path.new Edge.new([0,0], [1,0]), Geometry::Arc.new([2,1], 1, -90*Math::PI/180, 0), Edge.new([3,1], [1,2])
48
+ path = Geometry::Path.new Edge.new([0,0], [1,0]), Arc.new(center:[2,1], radius:1, start:-90*Math::PI/180, end:0), Edge.new([3,1], [1,2])
49
49
  path.elements.size.must_equal 4
50
50
  path.elements[0].must_be_kind_of Geometry::Edge
51
51
  path.elements[1].must_be_kind_of Geometry::Edge
@@ -54,7 +54,7 @@ describe Geometry::Path do
54
54
  end
55
55
 
56
56
  it "with disjoint Arcs" do
57
- path = Geometry::Path.new Geometry::Arc.new([2,1], 1, -90*Math::PI/180, 0), Geometry::Arc.new([3,1], 1, -90*Math::PI/180, 0)
57
+ path = Geometry::Path.new Arc.new(center:[2,1], radius:1, start:-90*Math::PI/180, end:0), Arc.new(center:[3,1], radius:1, start:-90*Math::PI/180, end:0)
58
58
  path.elements.size.must_equal 3
59
59
  path.elements[0].must_be_kind_of Geometry::Arc
60
60
  path.elements[1].must_be_kind_of Geometry::Edge
@@ -62,6 +62,5 @@ describe Geometry::Path do
62
62
 
63
63
  path.elements[0].last.must_equal path.elements[1].first
64
64
  end
65
-
66
65
  end
67
66
  end
@@ -11,6 +11,12 @@ describe Geometry::Point do
11
11
  point.x.must_equal 3
12
12
  point.y.must_equal 4
13
13
  end
14
+
15
+ it "must return the PointZero when constructed from a PointZero" do
16
+ original_point = Geometry::PointZero.new
17
+ point = Geometry::Point[original_point]
18
+ point.must_be_same_as original_point
19
+ end
14
20
  end
15
21
 
16
22
  it "create a Point object using list syntax" do
@@ -102,12 +108,9 @@ describe Geometry::Point do
102
108
  (left + [5,6]).must_equal Point[6,8]
103
109
  end
104
110
 
105
- it "must raise TypeError when adding a scalar to a Point of dimension greater than 1" do
106
- lambda { left + 1 }.must_raise Geometry::DimensionMismatch
107
- end
108
-
109
- it "must support adding a Numeric to a Point with a size of 1" do
110
- (Point[1] + 2).must_equal Point[3]
111
+ it "must add a Numeric to all elements" do
112
+ (left + 2).must_equal Point[3,4]
113
+ (2 + left).must_equal Point[3,4]
111
114
  end
112
115
 
113
116
  it "must raise an exception when adding mismatched sizes" do
@@ -130,12 +133,9 @@ describe Geometry::Point do
130
133
  (left - [5,6]).must_equal Point[-4, -4]
131
134
  end
132
135
 
133
- it "must raise an exception when subtracting a scalar from a Vector" do
134
- lambda { left - 1 }.must_raise Geometry::DimensionMismatch
135
- end
136
-
137
- it "must subtract a Numeric from a Point of size 1" do
138
- (Point[3] - 2).must_equal Point[1]
136
+ it "must subtract a Numeric from all elements" do
137
+ (left - 2).must_equal Point[-1, 0]
138
+ (2 - left).must_equal Point[1,0]
139
139
  end
140
140
 
141
141
  it "must raise an exception when subtracting mismatched sizes" do
@@ -17,7 +17,19 @@ describe Geometry::PointZero do
17
17
  (-zero).must_be :eql?, 0
18
18
  (-zero).must_be_instance_of(Geometry::PointZero)
19
19
  end
20
-
20
+
21
+ describe "Accessors" do
22
+ it "must return 0 for array access" do
23
+ zero[3].must_equal 0
24
+ end
25
+
26
+ it "must return 0 for named element access" do
27
+ zero.x.must_equal 0
28
+ zero.y.must_equal 0
29
+ zero.z.must_equal 0
30
+ end
31
+ end
32
+
21
33
  describe "when adding" do
22
34
  it "must return a number" do
23
35
  (zero + 3).must_equal 3
@@ -29,10 +41,15 @@ describe Geometry::PointZero do
29
41
  (left + zero).must_be_kind_of Point
30
42
  end
31
43
 
32
- it "must return a Point when adding an array" do
44
+ it "must return an Array when adding an array" do
33
45
  (zero + [5,6]).must_equal [5,6]
34
46
  # ([5,6] + zero).must_equal [5,6]
35
47
  end
48
+
49
+ it "must return a Point when adding a Size" do
50
+ (zero + Size[5,6]).must_be_instance_of(Point)
51
+ (zero + Size[5,6]).must_equal Point[5,6]
52
+ end
36
53
  end
37
54
 
38
55
  describe "when subtracting" do
@@ -50,6 +67,11 @@ describe Geometry::PointZero do
50
67
  (zero - [5,6]).must_equal [-5, -6]
51
68
  # ([5,6] - zero).must_equal [5,6]
52
69
  end
70
+
71
+ it "must return a Point when subtracting a Size" do
72
+ (zero - Size[5,6]).must_be_instance_of(Point)
73
+ (zero - Size[5,6]).must_equal Point[-5,-6]
74
+ end
53
75
  end
54
76
 
55
77
  describe "multiplication" do
@@ -104,7 +126,7 @@ describe Geometry::PointZero do
104
126
  end
105
127
 
106
128
  describe "comparison" do
107
- let(:zero) { Geometry::PointZero.new }
129
+ subject { Geometry::PointZero.new }
108
130
 
109
131
  it "must be equal to 0 and 0.0" do
110
132
  zero.must_be :eql?, 0
@@ -119,7 +141,9 @@ describe Geometry::PointZero do
119
141
  it "must be equal to an Array of zeros" do
120
142
  zero.must_be :==, [0,0]
121
143
  zero.must_be :eql?, [0,0]
144
+ zero.must_be :===, [0,0]
122
145
  [0,0].must_equal zero
146
+ subject.must_equal [0,0]
123
147
  end
124
148
 
125
149
  it "must not be equal to a non-zero Array" do
@@ -130,7 +154,9 @@ describe Geometry::PointZero do
130
154
  it "must be equal to a Point at the origin" do
131
155
  zero.must_be :==, Point[0,0]
132
156
  zero.must_be :eql?, Point[0,0]
157
+ zero.must_be :===, Point[0,0]
133
158
  Point[0,0].must_equal zero
159
+ subject.must_equal Point[0,0]
134
160
  end
135
161
 
136
162
  it "must not be equal to a Point not at the origin" do
@@ -2,7 +2,6 @@ require 'minitest/autorun'
2
2
  require 'geometry/polygon'
3
3
 
4
4
  describe Geometry::Polygon do
5
- Point = Geometry::Point
6
5
  Polygon = Geometry::Polygon
7
6
 
8
7
  let(:cw_unit_square) { Polygon.new [0,0], [0,1], [1,1], [1,0] }
@@ -59,6 +58,18 @@ describe Geometry::Polygon do
59
58
  assert_equal(polygon.edges.first.first, polygon.edges.last.last)
60
59
  end
61
60
 
61
+ describe "orientation" do
62
+ it "must return true for clockwise" do
63
+ Polygon.new([0,0], [0,1], [1,1], [1,0]).clockwise?.must_equal true
64
+ Polygon.new([1,1], [1,3], [3,3], [3,1]).clockwise?.must_equal true
65
+ end
66
+
67
+ it "must return fale for counterclockwise" do
68
+ Polygon.new([0,0], [1,0], [1,1], [0,1]).clockwise?.must_equal false
69
+ Polygon.new([1,1], [3,1], [3,3], [1,3]).clockwise?.must_equal false
70
+ end
71
+ end
72
+
62
73
  it "must gift wrap a square polygon" do
63
74
  polygon = Polygon.new [0,0], [1,0], [1,1], [0,1]
64
75
  convex_hull = polygon.wrap
@@ -91,6 +102,18 @@ describe Geometry::Polygon do
91
102
  convex_hull.vertices.must_equal [[0,0], [0,1], [2,1], [2,0], [1,-1]].map {|a| Point[*a]}
92
103
  end
93
104
 
105
+ describe "spaceship" do
106
+ it "with a Point" do
107
+ (unit_square <=> Point[2,0]).must_equal -1
108
+ (unit_square <=> Point[1,0]).must_equal 0
109
+ (unit_square <=> Point[0.5,0.5]).must_equal 1
110
+ end
111
+
112
+ it "with a Point that lies on a horizontal edge" do
113
+ (unit_square <=> Point[0.5,0]).must_equal 0
114
+ end
115
+ end
116
+
94
117
  describe "when outsetting" do
95
118
  it "must outset a unit square" do
96
119
  outset_polygon = unit_square.outset(1)
@@ -129,4 +152,41 @@ describe Geometry::Polygon do
129
152
  polygon.outset(1).must_equal Polygon.new [3, 0], [3, 3], [-2, 3], [-2, -2], [3, -2]
130
153
  end
131
154
  end
155
+
156
+ describe "set operations" do
157
+ describe "union" do
158
+ it "must union two adjacent squares" do
159
+ polygonA = Polygon.new [0,0], [1,0], [1,1], [0,1]
160
+ polygonB = Polygon.new [1,0], [2,0], [2,1], [1,1]
161
+ (polygonA.union polygonB).must_equal Polygon.new [0,0], [2,0], [2,1], [0,1]
162
+ (polygonA + polygonB).must_equal Polygon.new [0,0], [2,0], [2,1], [0,1]
163
+ end
164
+
165
+ it "must union two overlapping squares" do
166
+ polygonA = Polygon.new [0,0], [2,0], [2,2], [0,2]
167
+ polygonB = Polygon.new [1,1], [3,1], [3,3], [1,3]
168
+ expected_polygon = Polygon.new [0,0], [2,0], [2,1], [3,1], [3,3], [1,3], [1,2], [0,2]
169
+ union = polygonA.union polygonB
170
+ union.must_be_kind_of Polygon
171
+ union.must_equal expected_polygon
172
+ end
173
+
174
+ it "must union two overlapping clockwise squares" do
175
+ polygonA = Polygon.new [0,0], [0,2], [2,2], [2,0]
176
+ polygonB = Polygon.new [1,1], [1,3], [3,3], [3,1]
177
+ expected_polygon = Polygon.new [0, 0], [0, 2], [1, 2], [1, 3], [3, 3], [3, 1], [2, 1], [2, 0]
178
+ union = polygonA.union polygonB
179
+ union.must_be_kind_of Polygon
180
+ union.must_equal expected_polygon
181
+ end
182
+
183
+ it "must union two overlapping squares with collinear edges" do
184
+ polygonA = Polygon.new [0,0], [2,0], [2,2], [0,2]
185
+ polygonB = Polygon.new [1,0], [3,0], [3,2], [1,2]
186
+ union = polygonA + polygonB
187
+ union.must_be_kind_of Polygon
188
+ union.must_equal Polygon.new [0,0], [3,0], [3,2], [0,2]
189
+ end
190
+ end
191
+ end
132
192
  end
@@ -2,7 +2,6 @@ require 'minitest/autorun'
2
2
  require 'geometry/polyline'
3
3
 
4
4
  describe Geometry::Polyline do
5
- Point = Geometry::Point
6
5
  Polyline = Geometry::Polyline
7
6
 
8
7
  let(:unit_square) { Polyline.new [0,0], [1,0], [1,1], [0,1] }
@@ -5,54 +5,93 @@ def Rectangle(*args)
5
5
  Geometry::Rectangle.new(*args)
6
6
  end
7
7
 
8
- Point = Geometry::Point
9
- Size = Geometry::Size
10
-
11
8
  describe Geometry::Rectangle do
12
- describe "when constructed" do
13
- it "create a Rectangle object from two Points" do
14
- rectangle = Rectangle [1,2], [3,4]
15
- assert_kind_of(Geometry::Rectangle, rectangle)
9
+ Rectangle = Geometry::Rectangle
10
+
11
+ describe "when initializing" do
12
+ it "must accept two corners as Arrays" do
13
+ rectangle = Rectangle.new [1,2], [2,3]
14
+ rectangle.must_be_kind_of Geometry::Rectangle
15
+ rectangle.height.must_equal 1
16
+ rectangle.width.must_equal 1
17
+ rectangle.origin.must_equal Point[1,2]
16
18
  end
17
19
 
18
- it "create a Rectangle from a width and height" do
19
- rectangle = Rectangle 2, 3
20
- assert_kind_of(Geometry::Rectangle, rectangle)
21
- assert_equal(2, rectangle.width)
22
- assert_equal(3, rectangle.height)
23
- assert_equal(Point[0,0], rectangle.center)
20
+ it "must accept two named corners as Arrays" do
21
+ rectangle = Rectangle.new from:[1,2], to:[2,3]
22
+ rectangle.must_be_kind_of Geometry::Rectangle
23
+ rectangle.height.must_equal 1
24
+ rectangle.width.must_equal 1
25
+ rectangle.origin.must_equal Point[1,2]
24
26
  end
25
27
 
26
- it "create a Rectangle from a Size" do
27
- rectangle = Rectangle Size[2, 3]
28
- assert_kind_of(Geometry::Rectangle, rectangle)
29
- assert_equal(2, rectangle.width)
30
- assert_equal(3, rectangle.height)
31
- assert_equal(Point[0,0], rectangle.center)
28
+ it "must accept named center point and size arguments" do
29
+ rectangle = Rectangle.new center:[1,2], size:[3,4]
30
+ rectangle.must_be_kind_of Geometry::Rectangle
31
+ rectangle.height.must_equal 4
32
+ rectangle.width.must_equal 3
33
+ rectangle.center.must_equal Point[1,2]
32
34
  end
33
35
 
34
- it "create a Rectangle from an origin Point and Size" do
35
- rectangle = Rectangle Point[1,2], Size[2, 3]
36
- assert_kind_of(Geometry::Rectangle, rectangle)
37
- assert_equal(2, rectangle.width)
38
- assert_equal(3, rectangle.height)
39
- assert_equal(Point[1,2], rectangle.origin)
36
+ it "must reject a named center argument with no size argument" do
37
+ -> { Rectangle.new center:[1,2] }.must_raise ArgumentError
40
38
  end
41
39
 
42
- it "create a Rectangle from sides" do
43
- rectangle = Rectangle 1,2,3,4
44
- assert_kind_of(Geometry::Rectangle, rectangle)
45
- assert_equal(2, rectangle.width)
46
- assert_equal(2, rectangle.height)
47
- assert_equal(Point[1,2], rectangle.origin)
40
+ it "must accept named origin point and size arguments" do
41
+ rectangle = Rectangle.new origin:[1,2], size:[3,4]
42
+ rectangle.must_be_kind_of Geometry::Rectangle
43
+ rectangle.height.must_equal 4
44
+ rectangle.width.must_equal 3
45
+ rectangle.origin.must_equal Point[1,2]
46
+ end
47
+
48
+ it "must reject a named origin argument with no size argument" do
49
+ -> { Rectangle.new origin:[1,2] }.must_raise ArgumentError
50
+ end
51
+
52
+ it "must accept a sole named size argument that is an Array" do
53
+ rectangle = Rectangle.new size:[1,2]
54
+ rectangle.must_be_kind_of Geometry::Rectangle
55
+ rectangle.origin.must_equal Point[0,0]
56
+ rectangle.height.must_equal 2
57
+ rectangle.width.must_equal 1
58
+ end
59
+
60
+ it "must accept a sole named size argument that is a Size" do
61
+ rectangle = Rectangle.new size:Size[1,2]
62
+ rectangle.must_be_kind_of Geometry::Rectangle
63
+ rectangle.origin.must_equal Point[0,0]
64
+ rectangle.height.must_equal 2
65
+ rectangle.width.must_equal 1
66
+ end
67
+
68
+ it "must accept named width and height arguments" do
69
+ rectangle = Rectangle.new width:1, height:3
70
+ rectangle.must_be_kind_of Geometry::Rectangle
71
+ rectangle.height.must_equal 3
72
+ rectangle.width.must_equal 1
73
+ end
74
+
75
+ it "must reject width or height by themselves" do
76
+ -> { Rectangle.new height:1 }.must_raise ArgumentError
77
+ -> { Rectangle.new width:1 }.must_raise ArgumentError
78
+ end
79
+
80
+ end
81
+
82
+ describe "comparison" do
83
+ it "must compare equal" do
84
+ rectangle = Rectangle [1,2], [3,4]
85
+ rectangle.must_equal Rectangle([1,2], [3, 4])
48
86
  end
49
87
  end
50
88
 
51
89
  describe "properties" do
90
+ subject { Rectangle.new [1,2], [3,4] }
52
91
  let(:rectangle) { Rectangle [1,2], [3,4] }
53
92
 
54
93
  it "have a center point property" do
55
- assert_equal(rectangle.center, [2,3])
94
+ rectangle.center.must_equal Point[2,3]
56
95
  end
57
96
 
58
97
  it "have a width property" do
@@ -78,5 +117,21 @@ describe Geometry::Rectangle do
78
117
  assert_equal(4, points.size)
79
118
  points.each {|point| assert_kind_of(Geometry::Point, point)}
80
119
  end
120
+
121
+ it "must have a bounds property that returns a Rectangle" do
122
+ subject.bounds.must_equal Rectangle.new([1,2], [3,4])
123
+ end
124
+
125
+ it "must have a minmax property that returns the corners of the bounding rectangle" do
126
+ subject.minmax.must_equal [Point[1,2], Point[3,4]]
127
+ end
128
+
129
+ it "must have a max property that returns the upper right corner of the bounding rectangle" do
130
+ subject.max.must_equal Point[3,4]
131
+ end
132
+
133
+ it "must have a min property that returns the lower left corner of the bounding rectangle" do
134
+ subject.min.must_equal Point[1,2]
135
+ end
81
136
  end
82
137
  end
@@ -0,0 +1,84 @@
1
+ require 'minitest/autorun'
2
+ require 'geometry/regular_polygon'
3
+
4
+ describe Geometry::RegularPolygon do
5
+ RegularPolygon = Geometry::RegularPolygon
6
+
7
+ describe "when constructed with named center and radius arguments" do
8
+ let(:polygon) { RegularPolygon.new sides:4, center:[1,2], radius:3 }
9
+
10
+ it "must create a RegularPolygon" do
11
+ polygon.must_be_instance_of(RegularPolygon)
12
+ end
13
+
14
+ it "must have the correct number of sides" do
15
+ polygon.edge_count.must_equal 4
16
+ end
17
+
18
+ it "must have a center point accessor" do
19
+ polygon.center.must_equal Point[1,2]
20
+ end
21
+
22
+ it "must have a radius accessor" do
23
+ polygon.radius.must_equal 3
24
+ end
25
+
26
+ it "must compare equal" do
27
+ polygon.must_equal RegularPolygon.new(sides:4, center:[1,2], radius:3)
28
+ end
29
+ end
30
+
31
+ describe "when constructed with a center and diameter" do
32
+ let(:polygon) { RegularPolygon.new sides:4, center:[1,2], diameter:4 }
33
+
34
+ it "must be a DiameterRegularPolygon" do
35
+ polygon.must_be_instance_of(Geometry::DiameterRegularPolygon)
36
+ polygon.must_be_kind_of(RegularPolygon)
37
+ end
38
+
39
+ it "must have the correct number of sides" do
40
+ polygon.edge_count.must_equal 4
41
+ end
42
+
43
+ it "must have a center" do
44
+ polygon.center.must_equal Point[1,2]
45
+ end
46
+
47
+ it "must have a diameter" do
48
+ polygon.diameter.must_equal 4
49
+ end
50
+
51
+ it "must calculate the correct radius" do
52
+ polygon.radius.must_equal 2
53
+ end
54
+
55
+ it "must compare equal" do
56
+ polygon.must_equal RegularPolygon.new(sides:4, center:[1,2], diameter:4)
57
+ end
58
+ end
59
+
60
+ describe "when constructed with a diameter and no center" do
61
+ let(:polygon) { RegularPolygon.new sides:4, diameter:4 }
62
+
63
+ it "must be a DiameterRegularPolygon" do
64
+ polygon.must_be_instance_of(Geometry::DiameterRegularPolygon)
65
+ polygon.must_be_kind_of(RegularPolygon)
66
+ end
67
+
68
+ it "must have the correct number of sides" do
69
+ polygon.edge_count.must_equal 4
70
+ end
71
+
72
+ it "must have a nil center" do
73
+ polygon.center.must_be_nil
74
+ end
75
+
76
+ it "must have a diameter" do
77
+ polygon.diameter.must_equal 4
78
+ end
79
+
80
+ it "must calculate the correct radius" do
81
+ polygon.radius.must_equal 2
82
+ end
83
+ end
84
+ end