ffi-geos 1.2.0 → 2.2.0

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.
Files changed (54) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +4851 -0
  3. data/.travis.yml +24 -9
  4. data/FUNDING.yml +2 -0
  5. data/Gemfile +12 -16
  6. data/Guardfile +6 -8
  7. data/MIT-LICENSE +1 -1
  8. data/README.rdoc +2 -20
  9. data/Rakefile +4 -2
  10. data/ffi-geos.gemspec +13 -14
  11. data/lib/ffi-geos.rb +342 -244
  12. data/lib/ffi-geos/buffer_params.rb +9 -20
  13. data/lib/ffi-geos/coordinate_sequence.rb +351 -65
  14. data/lib/ffi-geos/geometry.rb +267 -191
  15. data/lib/ffi-geos/geometry_collection.rb +74 -12
  16. data/lib/ffi-geos/interrupt.rb +11 -16
  17. data/lib/ffi-geos/line_string.rb +157 -33
  18. data/lib/ffi-geos/linear_ring.rb +2 -3
  19. data/lib/ffi-geos/multi_line_string.rb +1 -2
  20. data/lib/ffi-geos/multi_point.rb +0 -1
  21. data/lib/ffi-geos/multi_polygon.rb +0 -1
  22. data/lib/ffi-geos/point.rb +70 -15
  23. data/lib/ffi-geos/polygon.rb +124 -21
  24. data/lib/ffi-geos/prepared_geometry.rb +11 -12
  25. data/lib/ffi-geos/strtree.rb +64 -77
  26. data/lib/ffi-geos/tools.rb +16 -19
  27. data/lib/ffi-geos/utils.rb +36 -60
  28. data/lib/ffi-geos/version.rb +1 -3
  29. data/lib/ffi-geos/wkb_reader.rb +4 -9
  30. data/lib/ffi-geos/wkb_writer.rb +15 -20
  31. data/lib/ffi-geos/wkt_reader.rb +2 -5
  32. data/lib/ffi-geos/wkt_writer.rb +20 -31
  33. data/sonar-project.properties +16 -0
  34. data/test/.rubocop.yml +36 -0
  35. data/test/coordinate_sequence_tests.rb +322 -52
  36. data/test/geometry_collection_tests.rb +388 -4
  37. data/test/geometry_tests.rb +466 -121
  38. data/test/interrupt_tests.rb +9 -12
  39. data/test/line_string_tests.rb +213 -25
  40. data/test/linear_ring_tests.rb +1 -3
  41. data/test/misc_tests.rb +28 -30
  42. data/test/multi_line_string_tests.rb +0 -2
  43. data/test/point_tests.rb +158 -2
  44. data/test/polygon_tests.rb +283 -2
  45. data/test/prepared_geometry_tests.rb +8 -11
  46. data/test/strtree_tests.rb +14 -15
  47. data/test/test_helper.rb +75 -51
  48. data/test/tools_tests.rb +1 -4
  49. data/test/utils_tests.rb +85 -76
  50. data/test/wkb_reader_tests.rb +18 -18
  51. data/test/wkb_writer_tests.rb +15 -22
  52. data/test/wkt_reader_tests.rb +1 -4
  53. data/test/wkt_writer_tests.rb +8 -17
  54. metadata +11 -7
@@ -0,0 +1,16 @@
1
+ sonar.projectKey=dark-panda_ffi-geos
2
+ sonar.organization=dark-panda
3
+
4
+ # This is the name and version displayed in the SonarCloud UI.
5
+ #sonar.projectName=ffi-geos
6
+ #sonar.projectVersion=1.0
7
+
8
+ # Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.
9
+ sonar.sources=lib, test
10
+
11
+ # Encoding of the source code. Default is default system encoding
12
+ #sonar.sourceEncoding=UTF-8
13
+
14
+ # Additional reports
15
+ sonar.ruby.rubocop.reportPaths=rubocop-report.json
16
+ sonar.ruby.coverage.reportPaths=coverage/.resultset.json
data/test/.rubocop.yml ADDED
@@ -0,0 +1,36 @@
1
+
2
+ inherit_from:
3
+ - ../.rubocop.yml
4
+
5
+ Metrics/BlockLength:
6
+ Description: 'Avoid long blocks with many lines.'
7
+ Enabled: false
8
+
9
+ Metrics/ModuleLength:
10
+ Description: 'Avoid modules longer than 300 lines of code.'
11
+ Enabled: false
12
+ Max: 300
13
+
14
+ Metrics/MethodLength:
15
+ Description: 'Avoid methods longer than 10 lines of code.'
16
+ StyleGuide: '#short-methods'
17
+ Enabled: false
18
+ Max: 50
19
+
20
+ Metrics/AbcSize:
21
+ Description: >-
22
+ A calculated magnitude based on number of assignments,
23
+ branches, and conditions.
24
+ Reference: 'http://c2.com/cgi/wiki?AbcMetric'
25
+ Enabled: true
26
+ Max: 50
27
+
28
+ Metrics/ClassLength:
29
+ Description: 'Avoid classes longer than 300 lines of code.'
30
+ Enabled: false
31
+ Max: 300
32
+
33
+ Metrics/ParameterLists:
34
+ Description: 'Avoid parameter lists longer than three or four parameters.'
35
+ StyleGuide: '#too-many-params'
36
+ Enabled: false
@@ -1,7 +1,5 @@
1
- # encoding: UTF-8
2
1
  # frozen_string_literal: true
3
2
 
4
- $: << File.dirname(__FILE__)
5
3
  require 'test_helper'
6
4
 
7
5
  class CoordinateSequenceTests < Minitest::Test
@@ -45,6 +43,28 @@ class CoordinateSequenceTests < Minitest::Test
45
43
  assert_equal(2, @cs.dimensions)
46
44
  end
47
45
 
46
+ def test_counter_clockwise
47
+ skip unless ENV['FORCE_TESTS'] || Geos::CoordinateSequence.method_defined?(:counter_clockwise?)
48
+
49
+ cs = Geos::CoordinateSequence.new([
50
+ [0, 0],
51
+ [1, 0],
52
+ [1, 1],
53
+ [0, 0]
54
+ ])
55
+
56
+ assert(cs.counter_clockwise?)
57
+
58
+ cs = Geos::CoordinateSequence.new([
59
+ [0, 0],
60
+ [1, 1],
61
+ [1, 0],
62
+ [0, 0]
63
+ ])
64
+
65
+ refute(cs.counter_clockwise?)
66
+ end
67
+
48
68
  def test_check_bounds
49
69
  assert_raises(Geos::IndexBoundsError) { @cs.set_x(10, 0.1) }
50
70
  assert_raises(Geos::IndexBoundsError) { @cs.set_x(-1, 0.1) }
@@ -107,11 +127,11 @@ class CoordinateSequenceTests < Minitest::Test
107
127
 
108
128
  def test_read_from_array
109
129
  cs = Geos::CoordinateSequence.new([
110
- [ 0, 0 ],
111
- [ 1, 1 ],
112
- [ 2, 2 ],
113
- [ 3, 3 ],
114
- [ 4, 4 ]
130
+ [0, 0],
131
+ [1, 1],
132
+ [2, 2],
133
+ [3, 3],
134
+ [4, 4]
115
135
  ])
116
136
 
117
137
  assert_equal(2, cs.dimensions)
@@ -119,90 +139,92 @@ class CoordinateSequenceTests < Minitest::Test
119
139
 
120
140
  assert_raises(Geos::CoordinateSequence::ParseError) do
121
141
  cs = Geos::CoordinateSequence.new([
122
- [ 1, 2 ],
123
- [ 1, 2, 3 ]
142
+ [1, 2],
143
+ [1, 2, 3]
124
144
  ])
125
145
  end
126
146
 
127
147
  assert_raises(Geos::CoordinateSequence::ParseError) do
128
148
  cs = Geos::CoordinateSequence.new([
129
- [ 1, 2, 3, 4 ]
149
+ [1, 2, 3, 4]
130
150
  ])
131
151
  end
132
152
  end
133
153
 
134
154
  def test_to_point
135
- cs = Geos::CoordinateSequence.new([5,7])
136
- assert_equal('POINT (5 7)', write(cs.to_point, :trim => true))
155
+ cs = Geos::CoordinateSequence.new([5, 7])
156
+ assert_equal('POINT (5 7)', write(cs.to_point, trim: true))
137
157
  end
138
158
 
139
159
  def test_to_to_linear_ring
140
160
  cs = Geos::CoordinateSequence.new([
141
- [ 0, 0 ],
142
- [ 0, 5 ],
143
- [ 5, 5 ],
144
- [ 5, 0 ],
145
- [ 0, 0 ]
161
+ [0, 0],
162
+ [0, 5],
163
+ [5, 5],
164
+ [5, 0],
165
+ [0, 0]
146
166
  ])
147
167
 
148
- assert_equal('LINEARRING (0 0, 0 5, 5 5, 5 0, 0 0)', write(cs.to_linear_ring, :trim => true))
168
+ assert_equal('LINEARRING (0 0, 0 5, 5 5, 5 0, 0 0)', write(cs.to_linear_ring, trim: true))
149
169
  end
150
170
 
151
171
  def test_empty
152
172
  cs = Geos::CoordinateSequence.new
153
173
  assert_geom_empty(cs)
154
174
 
155
- cs = Geos::CoordinateSequence.new([4,1])
175
+ cs = Geos::CoordinateSequence.new([4, 1])
156
176
  refute_geom_empty(cs)
157
177
  end
158
178
 
159
179
  def test_to_empty_linear_ring
160
180
  cs = Geos::CoordinateSequence.new
161
181
 
162
- assert_equal('LINEARRING EMPTY', write(cs.to_linear_ring, :trim => true))
182
+ assert_equal('LINEARRING EMPTY', write(cs.to_linear_ring, trim: true))
163
183
  end
164
184
 
165
185
  def test_to_line_string
166
186
  cs = Geos::CoordinateSequence.new([
167
- [ 0, 0 ],
168
- [ 0, 5 ],
169
- [ 5, 5 ],
170
- [ 5, 0 ]
187
+ [0, 0],
188
+ [0, 5],
189
+ [5, 5],
190
+ [5, 0]
171
191
  ])
172
192
 
173
- assert_equal('LINESTRING (0 0, 0 5, 5 5, 5 0)', write(cs.to_line_string, :trim => true))
193
+ assert_equal('LINESTRING (0 0, 0 5, 5 5, 5 0)', write(cs.to_line_string, trim: true))
174
194
  end
175
195
 
176
196
  def test_to_empty_line_string
177
197
  cs = Geos::CoordinateSequence.new
178
198
 
179
- assert_equal('LINESTRING EMPTY', write(cs.to_line_string, :trim => true))
199
+ assert_equal('LINESTRING EMPTY', write(cs.to_line_string, trim: true))
180
200
  end
181
201
 
182
202
  def test_to_polygon
183
203
  cs = Geos::CoordinateSequence.new([
184
- [ 0, 0 ],
185
- [ 0, 5 ],
186
- [ 5, 5 ],
187
- [ 5, 0 ],
188
- [ 0, 0 ]
204
+ [0, 0],
205
+ [0, 5],
206
+ [5, 5],
207
+ [5, 0],
208
+ [0, 0]
189
209
  ])
190
210
 
191
- assert_equal('POLYGON ((0 0, 0 5, 5 5, 5 0, 0 0))', write(cs.to_polygon, :trim => true))
211
+ assert_equal('POLYGON ((0 0, 0 5, 5 5, 5 0, 0 0))', write(cs.to_polygon, trim: true))
192
212
  end
193
213
 
194
214
  def test_to_empty_polygon
195
215
  cs = Geos::CoordinateSequence.new
196
216
 
197
- assert_equal('POLYGON EMPTY', write(cs.to_polygon, :trim => true))
217
+ assert_equal('POLYGON EMPTY', write(cs.to_polygon, trim: true))
198
218
  end
199
219
 
200
- def test_to_s
220
+ def test_to_s_2d
201
221
  cs = Geos::CoordinateSequence.new([[1, 2], [10, 11]])
202
- assert_equal("1.0 2.0, 10.0 11.0", cs.to_s)
222
+ assert_equal('1.0 2.0, 10.0 11.0', cs.to_s)
223
+ end
203
224
 
225
+ def test_to_s_3d
204
226
  cs = Geos::CoordinateSequence.new([[1, 2, 3], [10, 11, 12]])
205
- assert_equal("1.0 2.0 3.0, 10.0 11.0 12.0", cs.to_s)
227
+ assert_equal('1.0 2.0 3.0, 10.0 11.0 12.0', cs.to_s)
206
228
  end
207
229
 
208
230
  def test_get_by_proxy
@@ -262,11 +284,11 @@ class CoordinateSequenceTests < Minitest::Test
262
284
 
263
285
  assert_kind_of(Enumerable, cs.x.each)
264
286
  assert_kind_of(Enumerable, cs.x.to_enum)
265
- assert_equal(cs.x, cs.x.each {})
287
+ assert_equal(cs.x, cs.x.each(&EMPTY_BLOCK))
266
288
  end
267
289
 
268
290
  def test_options_hash
269
- cs = Geos::CoordinateSequence.new(:size => 10, :dimensions => 2)
291
+ cs = Geos::CoordinateSequence.new(size: 10, dimensions: 2)
270
292
 
271
293
  assert_equal(10, cs.size)
272
294
  assert_equal(2, cs.dimensions)
@@ -277,13 +299,13 @@ class CoordinateSequenceTests < Minitest::Test
277
299
 
278
300
  assert_kind_of(Enumerable, cs.each)
279
301
  assert_kind_of(Enumerable, cs.to_enum)
280
- assert_equal(cs, cs.each {})
302
+ assert_equal(cs, cs.each(&EMPTY_BLOCK))
281
303
  end
282
304
 
283
305
  def test_array_like_access
284
306
  cs = Geos::CoordinateSequence.new([
285
- [ 0, 1 ],
286
- [ 2, 3 ]
307
+ [0, 1],
308
+ [2, 3]
287
309
  ])
288
310
 
289
311
  assert_equal(0, cs[0][0])
@@ -292,7 +314,7 @@ class CoordinateSequenceTests < Minitest::Test
292
314
  assert_equal(3, cs[1][1])
293
315
 
294
316
  cs = Geos::CoordinateSequence.new([
295
- [ 4, 5, 6 ]
317
+ [4, 5, 6]
296
318
  ])
297
319
 
298
320
  assert_equal(4, cs[0][0])
@@ -302,9 +324,9 @@ class CoordinateSequenceTests < Minitest::Test
302
324
 
303
325
  def test_slice
304
326
  cs = Geos::CoordinateSequence.new([
305
- [ 0, 1 ],
306
- [ 2, 3 ],
307
- [ 4, 5 ]
327
+ [0, 1],
328
+ [2, 3],
329
+ [4, 5]
308
330
  ])
309
331
 
310
332
  assert_equal([[0, 1], [2, 3]], cs.slice(0..1))
@@ -313,24 +335,272 @@ class CoordinateSequenceTests < Minitest::Test
313
335
  end
314
336
 
315
337
  def test_proxy_clone
316
- cs = Geos::CoordinateSequence.new([ 10, 20 ])
317
- cs2 = cs.clone
338
+ cs = Geos::CoordinateSequence.new([10, 20])
339
+ cs_2 = cs.clone
318
340
 
319
341
  cs.x[0] = 100
320
342
 
321
343
  assert_equal(100, cs.x[0])
322
- assert_equal(10, cs2.x[0])
344
+ assert_equal(10, cs_2.x[0])
323
345
 
324
- refute_equal(cs.x, cs2.x)
325
- refute_equal(cs.y, cs2.y)
346
+ refute_equal(cs.x, cs_2.x)
347
+ refute_equal(cs.y, cs_2.y)
326
348
  end
327
349
 
328
350
  def test_has_z
329
- assert_geom_has_z(Geos::CoordinateSequence.new([ 0, 1, 2 ]))
330
- refute_geom_has_z(Geos::CoordinateSequence.new([ 0, 1 ]))
351
+ assert_geom_has_z(Geos::CoordinateSequence.new([0, 1, 2]))
352
+ refute_geom_has_z(Geos::CoordinateSequence.new([0, 1]))
331
353
  refute_geom_has_z(Geos::CoordinateSequence.new(1, 2))
332
354
  assert_geom_has_z(Geos::CoordinateSequence.new(1, 3))
333
355
  assert_geom_has_z(read('POINT (0 0 0)').coord_seq)
334
356
  refute_geom_has_z(read('POINT (0 0)').coord_seq)
335
357
  end
358
+
359
+ def test_x_max
360
+ cs = Geos::CoordinateSequence.new([-10, -15], [0, 5], [10, 20])
361
+ assert_equal(10, cs.x_max)
362
+ end
363
+
364
+ def test_x_min
365
+ cs = Geos::CoordinateSequence.new([-10, -15], [0, 5], [10, 20])
366
+ assert_equal(-10, cs.x_min)
367
+ end
368
+
369
+ def test_y_max
370
+ cs = Geos::CoordinateSequence.new([-10, -15], [0, 5], [10, 20])
371
+ assert_equal(20, cs.y_max)
372
+ end
373
+
374
+ def test_y_min
375
+ cs = Geos::CoordinateSequence.new([-10, -15], [0, 5], [10, 20])
376
+ assert_equal(-15, cs.y_min)
377
+ end
378
+
379
+ def test_z_max
380
+ cs = Geos::CoordinateSequence.new([-10, -15], [0, 5], [10, 20])
381
+ assert(cs.z_max.nan?, ' Expected NaN')
382
+
383
+ cs = Geos::CoordinateSequence.new([-10, -15, -20], [0, 5, 10], [10, 20, 30])
384
+ assert_equal(30, cs.z_max)
385
+ end
386
+
387
+ def test_z_min
388
+ cs = Geos::CoordinateSequence.new([-10, -15], [0, 5], [10, 20])
389
+ assert(cs.z_min.nan?, ' Expected NaN')
390
+
391
+ cs = Geos::CoordinateSequence.new([-10, -15, -20], [0, 5, 10], [10, 20, 30])
392
+ assert_equal(-20, cs.z_min)
393
+ end
394
+
395
+ def test_snap_to_grid_with_size
396
+ expected = [
397
+ [[-10.0, -15.0], [0.0, 5.0], [10.0, 20.0]],
398
+ [[-10.1, -15.1], [0.1, 5.1], [10.1, 20.1]],
399
+ [[-10.12, -15.12], [0.12, 5.12], [10.12, 20.12]],
400
+ [[-10.123, -15.123], [0.123, 5.123], [10.123, 20.123]],
401
+ [[-10.1235, -15.1235], [0.1235, 5.1235], [10.1235, 20.1235]],
402
+ [[-10.12346, -15.12346], [0.12346, 5.12346], [10.12346, 20.12346]],
403
+ [[-10.123457, -15.123457], [0.123457, 5.123457], [10.123457, 20.123457]],
404
+ [[-10.1234568, -15.1234568], [0.1234568, 5.1234568], [10.1234568, 20.1234568]],
405
+ [[-10.12345679, -15.12345679], [0.12345679, 5.12345679], [10.12345679, 20.12345679]]
406
+ ]
407
+
408
+ coordinates = [
409
+ [-10.123456789, -15.123456789],
410
+ [0.123456789, 5.123456789],
411
+ [10.123456789, 20.123456789]
412
+ ]
413
+
414
+ 9.times do |i|
415
+ cs = Geos::CoordinateSequence.new(*coordinates)
416
+ cs.snap_to_grid!(10 ** -i)
417
+
418
+ # XXX - Ruby 1.8.7 sometimes sees the the float values as differing
419
+ # slightly, but not enough that it would matter for these tests.
420
+ # Test equality on the inspect Strings instead of the float values.
421
+ assert_equal(expected[i].inspect, cs.to_a.inspect)
422
+
423
+ cs = Geos::CoordinateSequence.new(*coordinates)
424
+ snapped = cs.snap_to_grid(10 ** -i)
425
+ assert_equal(coordinates, cs.to_a)
426
+ assert_equal(expected[i].inspect, snapped.to_a.inspect)
427
+ end
428
+ end
429
+
430
+ def test_snap_to_grid_with_hash
431
+ cs = Geos::CoordinateSequence.new(
432
+ [10, 10],
433
+ [20, 20],
434
+ [30, 30]
435
+ )
436
+ cs.snap_to_grid!(size_x: 1, size_y: 1, offset_x: 12.5, offset_y: 12.5)
437
+
438
+ assert_equal([
439
+ [9.5, 9.5],
440
+ [20.5, 20.5],
441
+ [30.5, 30.5]
442
+ ], cs.to_a)
443
+ end
444
+
445
+ def test_snap_to_grid_with_geometry_origin
446
+ cs = Geos::CoordinateSequence.new(
447
+ [10, 10],
448
+ [20, 20],
449
+ [30, 30]
450
+ )
451
+ cs.snap_to_grid!(size: 1, offset: read('LINESTRING (0 0, 25 25)'))
452
+
453
+ assert_equal([
454
+ [9.5, 9.5],
455
+ [20.5, 20.5],
456
+ [30.5, 30.5]
457
+ ], cs.to_a)
458
+ end
459
+
460
+ def test_snap_to_grid_with_z
461
+ cs = Geos::CoordinateSequence.new(
462
+ [10, 10, 10],
463
+ [20, 20, 20],
464
+ [30, 30, 30]
465
+ )
466
+ cs.snap_to_grid!(
467
+ size_x: 1,
468
+ size_y: 1,
469
+ size_z: 1,
470
+
471
+ offset_x: 12.5,
472
+ offset_y: 12.5,
473
+ offset_z: 12.5
474
+ )
475
+
476
+ assert_equal([
477
+ [9.5, 9.5, 9.5],
478
+ [20.5, 20.5, 20.5],
479
+ [30.5, 30.5, 30.5]
480
+ ], cs.to_a)
481
+ end
482
+
483
+ def test_snap_to_grid_remove_duplicate_points
484
+ coords = [
485
+ [-10.0, 0.0],
486
+ [-10.0, 5.0], [-10.0, 5.0],
487
+ [-10.0, 6.0], [-10.0, 6.0], [-10.0, 6.0],
488
+ [-10.0, 7.0], [-10.0, 7.0], [-10.0, 7.0],
489
+ [-10.0, 8.0], [-10.0, 8.0],
490
+ [-9.0, 8.0], [-9.0, 9.0],
491
+ [-10.0, 0.0]
492
+ ]
493
+
494
+ expected = [
495
+ [-10.0, 0.0],
496
+ [-10.0, 5.0],
497
+ [-10.0, 6.0],
498
+ [-10.0, 7.0],
499
+ [-10.0, 8.0],
500
+ [-9.0, 8.0],
501
+ [-9.0, 9.0],
502
+ [-10.0, 0.0]
503
+ ]
504
+
505
+ cs = Geos::CoordinateSequence.new(coords)
506
+ cs.snap_to_grid!
507
+
508
+ assert_equal(expected, cs.to_a)
509
+
510
+ cs = Geos::CoordinateSequence.new(coords)
511
+ cs_2 = cs.snap_to_grid
512
+
513
+ assert_equal(coords, cs.to_a)
514
+ assert_equal(expected, cs_2.to_a)
515
+ end
516
+
517
+ undef :affine_tester
518
+ def affine_tester(method, expected, coords, *args)
519
+ cs = Geos::CoordinateSequence.new(coords)
520
+ cs.send("#{method}!", *args)
521
+
522
+ expected.length.times do |i|
523
+ assert_in_delta(expected[i], cs.get_ordinate(0, i), TOLERANCE)
524
+ end
525
+
526
+ cs = Geos::CoordinateSequence.new(coords)
527
+ cs_2 = cs.send(method, *args)
528
+
529
+ expected.length.times do |i|
530
+ assert_in_delta(coords[i], cs.get_ordinate(0, i), TOLERANCE)
531
+ assert_in_delta(expected[i], cs_2.get_ordinate(0, i), TOLERANCE)
532
+ end
533
+ end
534
+
535
+ def test_rotate
536
+ affine_tester(:rotate, [29.0, 11.0], [1, 1], Math::PI / 2, [10.0, 20.0])
537
+ affine_tester(:rotate, [-2.0, 0.0], [1, 1], -Math::PI / 2, [-1.0, 2.0])
538
+ affine_tester(:rotate, [19.0, 1.0], [1, 1], Math::PI / 2, read('POINT(10 10)'))
539
+ affine_tester(:rotate, [-0.5, 0.5], [1, 1], Math::PI / 2, read('LINESTRING(0 0, 1 0)'))
540
+ end
541
+
542
+ def test_rotate_x
543
+ affine_tester(:rotate_x, [1, -1, -1], [1, 1, 1], Math::PI)
544
+ affine_tester(:rotate_x, [1, -1, 1], [1, 1, 1], Math::PI / 2)
545
+ affine_tester(:rotate_x, [1, 1, -1], [1, 1, 1], Math::PI + Math::PI / 2)
546
+ affine_tester(:rotate_x, [1, 1, 1], [1, 1, 1], Math::PI * 2)
547
+ end
548
+
549
+ def test_rotate_y
550
+ affine_tester(:rotate_y, [-1, 1, -1], [1, 1, 1], Math::PI)
551
+ affine_tester(:rotate_y, [1, 1, -1], [1, 1, 1], Math::PI / 2)
552
+ affine_tester(:rotate_y, [-1, 1, 1], [1, 1, 1], Math::PI + Math::PI / 2)
553
+ affine_tester(:rotate_y, [1, 1, 1], [1, 1, 1], Math::PI * 2)
554
+ end
555
+
556
+ def test_rotate_z
557
+ affine_tester(:rotate_z, [-1, -1], [1, 1], Math::PI)
558
+ affine_tester(:rotate_z, [-1, 1], [1, 1], Math::PI / 2)
559
+ affine_tester(:rotate_z, [1, -1], [1, 1], Math::PI + Math::PI / 2)
560
+ affine_tester(:rotate_z, [1, 1], [1, 1], Math::PI * 2)
561
+ end
562
+
563
+ def test_scale
564
+ affine_tester(:scale, [5, 5], [1, 1], 5, 5)
565
+ affine_tester(:scale, [3, 2], [1, 1], 3, 2)
566
+ affine_tester(:scale, [40, 40, 40], [10, 20, -5], 4, 2, -8)
567
+ end
568
+
569
+ def test_scale_hash
570
+ affine_tester(:scale, [5, 5], [1, 1], x: 5, y: 5)
571
+ affine_tester(:scale, [3, 2], [1, 1], x: 3, y: 2)
572
+ affine_tester(:scale, [40, 40, 40], [10, 20, -5], x: 4, y: 2, z: -8)
573
+ end
574
+
575
+ def test_trans_scale
576
+ affine_tester(:trans_scale, [2, 2], [1, 1], 1, 1, 1, 1)
577
+ affine_tester(:trans_scale, [3, 3], [2, 2], 1, 1, 1, 1)
578
+ affine_tester(:trans_scale, [0, 0], [1, 1], -1, -1, -1, -1)
579
+ affine_tester(:trans_scale, [1, 2], [1, 1], 0, 1, 1, 1)
580
+ affine_tester(:trans_scale, [2, 1], [1, 1], 1, 0, 1, 1)
581
+ affine_tester(:trans_scale, [0, 2], [1, 1], 1, 1, 0, 1)
582
+ affine_tester(:trans_scale, [2, 0], [1, 1], 1, 1, 1, 0)
583
+ affine_tester(:trans_scale, [3, 2], [1, 1], 2, 1, 1, 1)
584
+ affine_tester(:trans_scale, [2, 3], [1, 1], 1, 2, 1, 1)
585
+ affine_tester(:trans_scale, [4, 2], [1, 1], 1, 1, 2, 1)
586
+ affine_tester(:trans_scale, [2, 4], [1, 1], 1, 1, 1, 2)
587
+ affine_tester(:trans_scale, [15, 28], [1, 1], 2, 3, 5, 7)
588
+ affine_tester(:trans_scale, [15, 28, 1], [1, 1, 1], 2, 3, 5, 7)
589
+ end
590
+
591
+ def test_trans_scale_hash
592
+ affine_tester(:trans_scale, [2, 2], [1, 1], delta_x: 1, delta_y: 1, x_factor: 1, y_factor: 1)
593
+ affine_tester(:trans_scale, [15, 28, 1], [1, 1, 1], delta_x: 2, delta_y: 3, x_factor: 5, y_factor: 7)
594
+ affine_tester(:trans_scale, [3, 1, 1], [1, 1, 1], delta_x: 2, z_factor: 2)
595
+ end
596
+
597
+ def test_translate
598
+ affine_tester(:translate, [5, 12], [0, 0], 5, 12)
599
+ affine_tester(:translate, [-3, -7, 3], [0, 0, 0], -3, -7, 3)
600
+ end
601
+
602
+ def test_translate_hash
603
+ affine_tester(:translate, [5, 12], [0, 0], x: 5, y: 12)
604
+ affine_tester(:translate, [-3, -7, 3], [0, 0, 0], x: -3, y: -7, z: 3)
605
+ end
336
606
  end