larb 0.1.0 → 1.0.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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +13 -1
  3. data/README.md +63 -1
  4. data/ext/larb/color.c +449 -0
  5. data/ext/larb/color.h +35 -0
  6. data/ext/larb/extconf.rb +11 -0
  7. data/ext/larb/larb.c +27 -0
  8. data/ext/larb/larb.h +31 -0
  9. data/ext/larb/mat2.c +303 -0
  10. data/ext/larb/mat2.h +30 -0
  11. data/ext/larb/mat2d.c +397 -0
  12. data/ext/larb/mat2d.h +35 -0
  13. data/ext/larb/mat3.c +455 -0
  14. data/ext/larb/mat3.h +33 -0
  15. data/ext/larb/mat4.c +651 -0
  16. data/ext/larb/mat4.h +31 -0
  17. data/ext/larb/matrix_utils.h +97 -0
  18. data/ext/larb/quat.c +567 -0
  19. data/ext/larb/quat.h +39 -0
  20. data/ext/larb/quat2.c +511 -0
  21. data/ext/larb/quat2.h +39 -0
  22. data/ext/larb/vec2.c +365 -0
  23. data/ext/larb/vec2.h +43 -0
  24. data/ext/larb/vec3.c +538 -0
  25. data/ext/larb/vec3.h +52 -0
  26. data/ext/larb/vec4.c +361 -0
  27. data/ext/larb/vec4.h +38 -0
  28. data/lib/larb/version.rb +5 -0
  29. data/lib/larb.rb +2 -14
  30. data/test/larb/color_test.rb +299 -0
  31. data/test/larb/mat2_test.rb +144 -0
  32. data/test/larb/mat2d_test.rb +197 -0
  33. data/test/larb/mat3_test.rb +147 -0
  34. data/test/larb/mat4_test.rb +347 -0
  35. data/test/larb/matrix_test.rb +135 -0
  36. data/test/larb/native_value_test.rb +157 -0
  37. data/test/larb/quat2_test.rb +254 -0
  38. data/test/larb/quat_test.rb +284 -0
  39. data/test/larb/vec2_test.rb +274 -0
  40. data/test/larb/vec3_test.rb +373 -0
  41. data/test/larb/vec4_test.rb +196 -0
  42. data/test/test_helper.rb +4 -0
  43. metadata +60 -18
  44. data/Rakefile +0 -11
  45. data/lib/larb/color.rb +0 -148
  46. data/lib/larb/mat2.rb +0 -119
  47. data/lib/larb/mat2d.rb +0 -180
  48. data/lib/larb/mat3.rb +0 -238
  49. data/lib/larb/mat4.rb +0 -329
  50. data/lib/larb/quat.rb +0 -238
  51. data/lib/larb/quat2.rb +0 -193
  52. data/lib/larb/vec2.rb +0 -150
  53. data/lib/larb/vec3.rb +0 -218
  54. data/lib/larb/vec4.rb +0 -125
@@ -0,0 +1,274 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../test_helper"
4
+
5
+ class Vec2Test < Test::Unit::TestCase
6
+ def test_index_assignment_bounds_and_negative_indices
7
+ v = Larb::Vec2.new(1, 2)
8
+ v[-2] = 3
9
+ v[-1] = 4
10
+ assert_equal [3.0, 4.0], v.to_a
11
+ [-3, 2, 100].each { |index| assert_raise(IndexError) { v[index] = 99 } }
12
+ assert_equal [3.0, 4.0], v.to_a
13
+ end
14
+
15
+ def test_clamp_length_validates_limits_and_handles_extreme_magnitudes
16
+ [Larb::Vec2, Larb::Vec3].each do |klass|
17
+ v = klass.new(1e200, 0)
18
+ [-1, Float::NAN, Float::INFINITY].each do |limit|
19
+ assert_raise(ArgumentError) { v.clamp_length(limit) }
20
+ end
21
+ assert_equal klass.new(2, 0), v.clamp_length(2)
22
+ assert_equal klass.zero, v.clamp_length(0)
23
+ assert_equal klass.zero, klass.zero.clamp_length(0)
24
+ tiny = klass.new(1e-200, 0)
25
+ assert_equal klass.new(1e-201, 0), tiny.clamp_length(1e-201)
26
+ end
27
+ end
28
+
29
+ def test_new_with_default_values
30
+ v = Larb::Vec2.new
31
+ assert_equal 0.0, v.x
32
+ assert_equal 0.0, v.y
33
+ end
34
+
35
+ def test_new_with_given_values
36
+ v = Larb::Vec2.new(3, 4)
37
+ assert_equal 3.0, v.x
38
+ assert_equal 4.0, v.y
39
+ end
40
+
41
+ def test_bracket_syntax
42
+ v = Larb::Vec2[1, 2]
43
+ assert_equal 1.0, v.x
44
+ assert_equal 2.0, v.y
45
+ end
46
+
47
+ def test_zero
48
+ v = Larb::Vec2.zero
49
+ assert_equal 0.0, v.x
50
+ assert_equal 0.0, v.y
51
+ end
52
+
53
+ def test_one
54
+ v = Larb::Vec2.one
55
+ assert_equal 1.0, v.x
56
+ assert_equal 1.0, v.y
57
+ end
58
+
59
+ def test_add
60
+ v1 = Larb::Vec2.new(1, 2)
61
+ v2 = Larb::Vec2.new(3, 4)
62
+ result = v1 + v2
63
+ assert_equal 4.0, result.x
64
+ assert_equal 6.0, result.y
65
+ end
66
+
67
+ def test_subtract
68
+ v1 = Larb::Vec2.new(5, 7)
69
+ v2 = Larb::Vec2.new(2, 3)
70
+ result = v1 - v2
71
+ assert_equal 3.0, result.x
72
+ assert_equal 4.0, result.y
73
+ end
74
+
75
+ def test_multiply_by_scalar
76
+ v = Larb::Vec2.new(2, 3)
77
+ result = v * 2
78
+ assert_equal 4.0, result.x
79
+ assert_equal 6.0, result.y
80
+ end
81
+
82
+ def test_divide_by_scalar
83
+ v = Larb::Vec2.new(6, 8)
84
+ result = v / 2
85
+ assert_equal 3.0, result.x
86
+ assert_equal 4.0, result.y
87
+ end
88
+
89
+ def test_negate
90
+ v = Larb::Vec2.new(1, -2)
91
+ result = -v
92
+ assert_equal(-1.0, result.x)
93
+ assert_equal 2.0, result.y
94
+ end
95
+
96
+ def test_dot
97
+ v1 = Larb::Vec2.new(1, 2)
98
+ v2 = Larb::Vec2.new(3, 4)
99
+ assert_equal 11.0, v1.dot(v2)
100
+ end
101
+
102
+ def test_length
103
+ v = Larb::Vec2.new(3, 4)
104
+ assert_equal 5.0, v.length
105
+ end
106
+
107
+ def test_length_squared
108
+ v = Larb::Vec2.new(3, 4)
109
+ assert_equal 25.0, v.length_squared
110
+ end
111
+
112
+ def test_normalize
113
+ v = Larb::Vec2.new(3, 4)
114
+ result = v.normalize
115
+ assert_in_delta 0.6, result.x, 1e-10
116
+ assert_in_delta 0.8, result.y, 1e-10
117
+ end
118
+
119
+ def test_normalize!
120
+ v = Larb::Vec2.new(3, 4)
121
+ v.normalize!
122
+ assert_in_delta 0.6, v.x, 1e-10
123
+ assert_in_delta 0.8, v.y, 1e-10
124
+ end
125
+
126
+ def test_lerp
127
+ v1 = Larb::Vec2.new(0, 0)
128
+ v2 = Larb::Vec2.new(10, 20)
129
+ result = v1.lerp(v2, 0.5)
130
+ assert_equal 5.0, result.x
131
+ assert_equal 10.0, result.y
132
+ end
133
+
134
+ def test_to_a
135
+ v = Larb::Vec2.new(1, 2)
136
+ assert_equal [1.0, 2.0], v.to_a
137
+ end
138
+
139
+ def test_index_access
140
+ v = Larb::Vec2.new(1, 2)
141
+ assert_equal 1.0, v[0]
142
+ assert_equal 2.0, v[1]
143
+ end
144
+
145
+ def test_index_assignment
146
+ v = Larb::Vec2.new(0, 0)
147
+ v[0] = 5
148
+ v[1] = 6
149
+ assert_equal 5, v.x
150
+ assert_equal 6, v.y
151
+ end
152
+
153
+ def test_equality
154
+ v1 = Larb::Vec2.new(1, 2)
155
+ v2 = Larb::Vec2.new(1, 2)
156
+ assert_equal v1, v2
157
+ end
158
+
159
+ def test_inequality
160
+ v1 = Larb::Vec2.new(1, 2)
161
+ v2 = Larb::Vec2.new(1, 3)
162
+ assert_not_equal v1, v2
163
+ end
164
+
165
+ def test_not_equal_to_array
166
+ v = Larb::Vec2.new(1, 2)
167
+ assert_not_equal v, [1, 2]
168
+ end
169
+
170
+ def test_near_true
171
+ v1 = Larb::Vec2.new(1.0, 2.0)
172
+ v2 = Larb::Vec2.new(1.0000001, 2.0000001)
173
+ assert v1.near?(v2)
174
+ end
175
+
176
+ def test_near_false
177
+ v1 = Larb::Vec2.new(1.0, 2.0)
178
+ v2 = Larb::Vec2.new(1.1, 2.1)
179
+ assert_false v1.near?(v2)
180
+ end
181
+
182
+ def test_angle
183
+ v = Larb::Vec2.new(1, 0)
184
+ assert_equal 0.0, v.angle
185
+ end
186
+
187
+ def test_angle_up
188
+ v = Larb::Vec2.new(0, 1)
189
+ assert_in_delta Math::PI / 2, v.angle, 1e-10
190
+ end
191
+
192
+ def test_angle_to
193
+ v1 = Larb::Vec2.new(0, 0)
194
+ v2 = Larb::Vec2.new(1, 0)
195
+ assert_equal 0.0, v1.angle_to(v2)
196
+ end
197
+
198
+ def test_rotate
199
+ v = Larb::Vec2.new(1, 0)
200
+ result = v.rotate(Math::PI / 2)
201
+ assert_in_delta 0.0, result.x, 1e-10
202
+ assert_in_delta 1.0, result.y, 1e-10
203
+ end
204
+
205
+ def test_distance
206
+ v1 = Larb::Vec2.new(0, 0)
207
+ v2 = Larb::Vec2.new(3, 4)
208
+ assert_equal 5.0, v1.distance(v2)
209
+ end
210
+
211
+ def test_distance_squared
212
+ v1 = Larb::Vec2.new(0, 0)
213
+ v2 = Larb::Vec2.new(3, 4)
214
+ assert_equal 25.0, v1.distance_squared(v2)
215
+ end
216
+
217
+ def test_cross
218
+ v1 = Larb::Vec2.new(1, 0)
219
+ v2 = Larb::Vec2.new(0, 1)
220
+ assert_equal 1.0, v1.cross(v2)
221
+ end
222
+
223
+ def test_perpendicular
224
+ v = Larb::Vec2.new(1, 0)
225
+ result = v.perpendicular
226
+ assert_equal 0.0, result.x
227
+ assert_equal 1.0, result.y
228
+ end
229
+
230
+ def test_reflect
231
+ v = Larb::Vec2.new(1, -1).normalize
232
+ normal = Larb::Vec2.new(0, 1)
233
+ result = v.reflect(normal)
234
+ assert_in_delta v.x, result.x, 1e-10
235
+ assert_in_delta(-v.y, result.y, 1e-10)
236
+ end
237
+
238
+ def test_clamp_length
239
+ v = Larb::Vec2.new(3, 4)
240
+ result = v.clamp_length(2.5)
241
+ assert_in_delta 2.5, result.length, 1e-10
242
+ end
243
+
244
+ def test_clamp_length_under_limit
245
+ v = Larb::Vec2.new(1, 1)
246
+ result = v.clamp_length(10)
247
+ assert_equal v, result
248
+ end
249
+
250
+ def test_to_vec3
251
+ v = Larb::Vec2.new(1, 2)
252
+ result = v.to_vec3
253
+ assert_instance_of Larb::Vec3, result
254
+ assert_equal 1.0, result.x
255
+ assert_equal 2.0, result.y
256
+ assert_equal 0.0, result.z
257
+ end
258
+
259
+ def test_to_vec3_with_custom_z
260
+ v = Larb::Vec2.new(1, 2)
261
+ result = v.to_vec3(5)
262
+ assert_equal 5.0, result.z
263
+ end
264
+
265
+ def test_inspect
266
+ v = Larb::Vec2.new(1, 2)
267
+ assert_equal "Vec2[1.0, 2.0]", v.inspect
268
+ end
269
+
270
+ def test_to_s
271
+ v = Larb::Vec2.new(1, 2)
272
+ assert_equal v.inspect, v.to_s
273
+ end
274
+ end
@@ -0,0 +1,373 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../test_helper"
4
+
5
+ class Vec3Test < Test::Unit::TestCase
6
+ def assert_finite_vector(expected, actual)
7
+ actual.to_a.zip(expected).each do |value, target|
8
+ assert_predicate value, :finite?
9
+ assert_in_delta target, value, 1e-10
10
+ end
11
+ end
12
+
13
+ def test_slerp_equal_opposite_and_nonunit_endpoints
14
+ a = Larb::Vec3.new(2, 0, 0)
15
+ [0, 0.5, 1].each { |t| assert_finite_vector a.to_a, a.slerp(a, t) }
16
+ b = Larb::Vec3.new(0, 4, 0)
17
+ assert_equal a, a.slerp(b, 0)
18
+ assert_equal b, a.slerp(b, 1)
19
+ assert_finite_vector [3 / Math.sqrt(2), 3 / Math.sqrt(2), 0], a.slerp(b, 0.5)
20
+ same_direction = Larb::Vec3.new(4, 0, 0)
21
+ assert_finite_vector [3, 0, 0], a.slerp(same_direction, 0.5)
22
+
23
+ [Larb::Vec3.right, Larb::Vec3.up, Larb::Vec3.new(1, 2, 3).normalize].each do |v|
24
+ middle = v.slerp(-v, 0.5)
25
+ assert middle.to_a.all?(&:finite?)
26
+ assert_in_delta 1, middle.length, 1e-10
27
+ assert_in_delta 0, middle.dot(v), 1e-10
28
+ assert_equal(-v, v.slerp(-v, 1))
29
+ assert_equal middle, v.slerp(-v, 0.5)
30
+ end
31
+ close = Larb::Vec3.new(1, 1e-8, 0).normalize
32
+ assert_finite_vector [1, 5e-9, 0], Larb::Vec3.right.slerp(close, 0.5)
33
+ end
34
+
35
+ def test_direction_operations_reject_zero_vectors
36
+ v = Larb::Vec3.right
37
+ assert_raise(ArgumentError) { v.project(Larb::Vec3.zero) }
38
+ assert_raise(ArgumentError) { v.reject(Larb::Vec3.zero) }
39
+ assert_raise(ArgumentError) { v.angle_between(Larb::Vec3.zero) }
40
+ assert_raise(ArgumentError) { Larb::Vec3.zero.angle_between(v) }
41
+ assert_raise(ArgumentError) { v.slerp(Larb::Vec3.zero, 0.5) }
42
+ assert_raise(ArgumentError) { Larb::Vec3.zero.slerp(v, 0.5) }
43
+ assert_raise(ArgumentError) { v.slerp(v, Float::NAN) }
44
+ end
45
+
46
+ def test_slerp_near_antipodes_preserves_interpolated_length
47
+ a = Larb::Vec3.new(1, 2, 3).normalize
48
+ tangent = a.cross(Larb::Vec3.right).normalize
49
+ [1e-8, 1e-10, 1e-11, 1e-13].each do |offset|
50
+ b = (-a + tangent * offset).normalize
51
+ [0.25, 0.5, 0.75].each do |t|
52
+ result = (a * 2).slerp(b * 4, t)
53
+ assert result.to_a.all?(&:finite?)
54
+ assert_in_delta 2 + 2 * t, result.length, 1e-12
55
+ end
56
+ end
57
+ end
58
+
59
+ def test_projection_and_angle_handle_extreme_direction_magnitudes
60
+ [1e200, 1e-200].each do |magnitude|
61
+ v = Larb::Vec3.new(3, 4, 5)
62
+ direction = Larb::Vec3.new(magnitude, 0, 0)
63
+ assert_finite_vector [3, 0, 0], v.project(direction)
64
+ assert_finite_vector [0, 4, 5], v.reject(direction)
65
+ assert_in_delta Math::PI / 2, direction.angle_between(Larb::Vec3.up * magnitude), 1e-10
66
+ end
67
+ end
68
+
69
+ def test_new_with_default_values
70
+ v = Larb::Vec3.new
71
+ assert_equal 0.0, v.x
72
+ assert_equal 0.0, v.y
73
+ assert_equal 0.0, v.z
74
+ end
75
+
76
+ def test_new_with_given_values
77
+ v = Larb::Vec3.new(1, 2, 3)
78
+ assert_equal 1.0, v.x
79
+ assert_equal 2.0, v.y
80
+ assert_equal 3.0, v.z
81
+ end
82
+
83
+ def test_bracket_syntax
84
+ v = Larb::Vec3[1, 2, 3]
85
+ assert_equal 1.0, v.x
86
+ assert_equal 2.0, v.y
87
+ assert_equal 3.0, v.z
88
+ end
89
+
90
+ def test_zero
91
+ assert_equal Larb::Vec3.new(0, 0, 0), Larb::Vec3.zero
92
+ end
93
+
94
+ def test_one
95
+ assert_equal Larb::Vec3.new(1, 1, 1), Larb::Vec3.one
96
+ end
97
+
98
+ def test_up
99
+ assert_equal Larb::Vec3.new(0, 1, 0), Larb::Vec3.up
100
+ end
101
+
102
+ def test_down
103
+ assert_equal Larb::Vec3.new(0, -1, 0), Larb::Vec3.down
104
+ end
105
+
106
+ def test_forward
107
+ assert_equal Larb::Vec3.new(0, 0, -1), Larb::Vec3.forward
108
+ end
109
+
110
+ def test_back
111
+ assert_equal Larb::Vec3.new(0, 0, 1), Larb::Vec3.back
112
+ end
113
+
114
+ def test_right
115
+ assert_equal Larb::Vec3.new(1, 0, 0), Larb::Vec3.right
116
+ end
117
+
118
+ def test_left
119
+ assert_equal Larb::Vec3.new(-1, 0, 0), Larb::Vec3.left
120
+ end
121
+
122
+ def test_add
123
+ v1 = Larb::Vec3.new(1, 2, 3)
124
+ v2 = Larb::Vec3.new(4, 5, 6)
125
+ assert_equal Larb::Vec3.new(5, 7, 9), v1 + v2
126
+ end
127
+
128
+ def test_subtract
129
+ v1 = Larb::Vec3.new(4, 5, 6)
130
+ v2 = Larb::Vec3.new(1, 2, 3)
131
+ assert_equal Larb::Vec3.new(3, 3, 3), v1 - v2
132
+ end
133
+
134
+ def test_multiply_by_scalar
135
+ v = Larb::Vec3.new(1, 2, 3)
136
+ assert_equal Larb::Vec3.new(2, 4, 6), v * 2
137
+ end
138
+
139
+ def test_multiply_by_vec3
140
+ v1 = Larb::Vec3.new(1, 2, 3)
141
+ v2 = Larb::Vec3.new(2, 3, 4)
142
+ assert_equal Larb::Vec3.new(2, 6, 12), v1 * v2
143
+ end
144
+
145
+ def test_divide_by_scalar
146
+ v = Larb::Vec3.new(2, 4, 6)
147
+ assert_equal Larb::Vec3.new(1, 2, 3), v / 2
148
+ end
149
+
150
+ def test_negate
151
+ v = Larb::Vec3.new(1, -2, 3)
152
+ assert_equal Larb::Vec3.new(-1, 2, -3), -v
153
+ end
154
+
155
+ def test_dot
156
+ v1 = Larb::Vec3.new(1, 2, 3)
157
+ v2 = Larb::Vec3.new(4, 5, 6)
158
+ assert_equal 32.0, v1.dot(v2)
159
+ end
160
+
161
+ def test_cross
162
+ v1 = Larb::Vec3.new(1, 0, 0)
163
+ v2 = Larb::Vec3.new(0, 1, 0)
164
+ assert_equal Larb::Vec3.new(0, 0, 1), v1.cross(v2)
165
+ end
166
+
167
+ def test_cross_arbitrary
168
+ v1 = Larb::Vec3.new(1, 2, 3)
169
+ v2 = Larb::Vec3.new(4, 5, 6)
170
+ assert_equal Larb::Vec3.new(-3, 6, -3), v1.cross(v2)
171
+ end
172
+
173
+ def test_length
174
+ v = Larb::Vec3.new(2, 3, 6)
175
+ assert_equal 7.0, v.length
176
+ end
177
+
178
+ def test_length_squared
179
+ v = Larb::Vec3.new(2, 3, 6)
180
+ assert_equal 49.0, v.length_squared
181
+ end
182
+
183
+ def test_normalize
184
+ v = Larb::Vec3.new(0, 3, 4)
185
+ result = v.normalize
186
+ assert_in_delta 0.0, result.x, 1e-10
187
+ assert_in_delta 0.6, result.y, 1e-10
188
+ assert_in_delta 0.8, result.z, 1e-10
189
+ end
190
+
191
+ def test_reflect
192
+ v = Larb::Vec3.new(1, -1, 0).normalize
193
+ normal = Larb::Vec3.new(0, 1, 0)
194
+ result = v.reflect(normal)
195
+ assert_in_delta v.x, result.x, 1e-10
196
+ assert_in_delta(-v.y, result.y, 1e-10)
197
+ end
198
+
199
+ def test_xy
200
+ v = Larb::Vec3.new(1, 2, 3)
201
+ result = v.xy
202
+ assert_instance_of Larb::Vec2, result
203
+ assert_equal 1.0, result.x
204
+ assert_equal 2.0, result.y
205
+ end
206
+
207
+ def test_xz
208
+ v = Larb::Vec3.new(1, 2, 3)
209
+ result = v.xz
210
+ assert_instance_of Larb::Vec2, result
211
+ assert_equal 1.0, result.x
212
+ assert_equal 3.0, result.y
213
+ end
214
+
215
+ def test_yz
216
+ v = Larb::Vec3.new(1, 2, 3)
217
+ result = v.yz
218
+ assert_instance_of Larb::Vec2, result
219
+ assert_equal 2.0, result.x
220
+ assert_equal 3.0, result.y
221
+ end
222
+
223
+ def test_lerp
224
+ v1 = Larb::Vec3.new(0, 0, 0)
225
+ v2 = Larb::Vec3.new(10, 20, 30)
226
+ assert_equal Larb::Vec3.new(5, 10, 15), v1.lerp(v2, 0.5)
227
+ end
228
+
229
+ def test_to_a
230
+ v = Larb::Vec3.new(1, 2, 3)
231
+ assert_equal [1.0, 2.0, 3.0], v.to_a
232
+ end
233
+
234
+ def test_to_vec4
235
+ v = Larb::Vec3.new(1, 2, 3)
236
+ result = v.to_vec4
237
+ assert_instance_of Larb::Vec4, result
238
+ assert_equal 1.0, result.x
239
+ assert_equal 2.0, result.y
240
+ assert_equal 3.0, result.z
241
+ assert_equal 1.0, result.w
242
+ end
243
+
244
+ def test_to_vec4_with_custom_w
245
+ v = Larb::Vec3.new(1, 2, 3)
246
+ result = v.to_vec4(0.5)
247
+ assert_equal 0.5, result.w
248
+ end
249
+
250
+ def test_index_access
251
+ v = Larb::Vec3.new(1, 2, 3)
252
+ assert_equal 1.0, v[0]
253
+ assert_equal 2.0, v[1]
254
+ assert_equal 3.0, v[2]
255
+ end
256
+
257
+ def test_equality
258
+ v1 = Larb::Vec3.new(1, 2, 3)
259
+ v2 = Larb::Vec3.new(1, 2, 3)
260
+ assert_equal v1, v2
261
+ end
262
+
263
+ def test_inequality
264
+ v1 = Larb::Vec3.new(1, 2, 3)
265
+ v2 = Larb::Vec3.new(1, 2, 4)
266
+ assert_not_equal v1, v2
267
+ end
268
+
269
+ def test_not_equal_to_array
270
+ v = Larb::Vec3.new(1, 2, 3)
271
+ assert_not_equal v, [1, 2, 3]
272
+ end
273
+
274
+ def test_near
275
+ v1 = Larb::Vec3.new(1.0, 2.0, 3.0)
276
+ v2 = Larb::Vec3.new(1.0000001, 2.0000001, 3.0000001)
277
+ assert v1.near?(v2)
278
+ end
279
+
280
+ def test_distance
281
+ v1 = Larb::Vec3.new(0, 0, 0)
282
+ v2 = Larb::Vec3.new(2, 3, 6)
283
+ assert_equal 7.0, v1.distance(v2)
284
+ end
285
+
286
+ def test_distance_squared
287
+ v1 = Larb::Vec3.new(0, 0, 0)
288
+ v2 = Larb::Vec3.new(2, 3, 6)
289
+ assert_equal 49.0, v1.distance_squared(v2)
290
+ end
291
+
292
+ def test_angle_between
293
+ v1 = Larb::Vec3.new(1, 0, 0)
294
+ v2 = Larb::Vec3.new(0, 1, 0)
295
+ assert_in_delta Math::PI / 2, v1.angle_between(v2), 1e-10
296
+ end
297
+
298
+ def test_project
299
+ v = Larb::Vec3.new(3, 4, 0)
300
+ onto = Larb::Vec3.new(1, 0, 0)
301
+ result = v.project(onto)
302
+ assert_equal 3.0, result.x
303
+ assert_equal 0.0, result.y
304
+ end
305
+
306
+ def test_reject
307
+ v = Larb::Vec3.new(3, 4, 0)
308
+ from = Larb::Vec3.new(1, 0, 0)
309
+ result = v.reject(from)
310
+ assert_equal 0.0, result.x
311
+ assert_equal 4.0, result.y
312
+ end
313
+
314
+ def test_clamp_length
315
+ v = Larb::Vec3.new(2, 3, 6)
316
+ result = v.clamp_length(3.5)
317
+ assert_in_delta 3.5, result.length, 1e-10
318
+ end
319
+
320
+ def test_clamp_length_under_limit
321
+ v = Larb::Vec3.new(1, 1, 1)
322
+ result = v.clamp_length(10)
323
+ assert_equal v, result
324
+ end
325
+
326
+ def test_normalize!
327
+ v = Larb::Vec3.new(0, 3, 4)
328
+ v.normalize!
329
+ assert_in_delta 1.0, v.length, 1e-10
330
+ end
331
+
332
+ def test_min
333
+ v1 = Larb::Vec3.new(1, 5, 3)
334
+ v2 = Larb::Vec3.new(2, 3, 4)
335
+ assert_equal Larb::Vec3.new(1, 3, 3), v1.min(v2)
336
+ end
337
+
338
+ def test_max
339
+ v1 = Larb::Vec3.new(1, 5, 3)
340
+ v2 = Larb::Vec3.new(2, 3, 4)
341
+ assert_equal Larb::Vec3.new(2, 5, 4), v1.max(v2)
342
+ end
343
+
344
+ def test_abs
345
+ v = Larb::Vec3.new(-1, -2, 3)
346
+ assert_equal Larb::Vec3.new(1, 2, 3), v.abs
347
+ end
348
+
349
+ def test_floor
350
+ v = Larb::Vec3.new(1.7, 2.3, 3.9)
351
+ assert_equal Larb::Vec3.new(1, 2, 3), v.floor
352
+ end
353
+
354
+ def test_ceil
355
+ v = Larb::Vec3.new(1.1, 2.5, 3.9)
356
+ assert_equal Larb::Vec3.new(2, 3, 4), v.ceil
357
+ end
358
+
359
+ def test_round
360
+ v = Larb::Vec3.new(1.4, 2.5, 3.6)
361
+ assert_equal Larb::Vec3.new(1, 3, 4), v.round
362
+ end
363
+
364
+ def test_inspect
365
+ v = Larb::Vec3.new(1, 2, 3)
366
+ assert_equal "Vec3[1.0, 2.0, 3.0]", v.inspect
367
+ end
368
+
369
+ def test_to_s
370
+ v = Larb::Vec3.new(1, 2, 3)
371
+ assert_equal v.inspect, v.to_s
372
+ end
373
+ end