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,196 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../test_helper"
4
+
5
+ class Vec4Test < Test::Unit::TestCase
6
+ def test_new_with_default_values
7
+ v = Larb::Vec4.new
8
+ assert_equal 0.0, v.x
9
+ assert_equal 0.0, v.y
10
+ assert_equal 0.0, v.z
11
+ assert_equal 1.0, v.w
12
+ end
13
+
14
+ def test_new_with_given_values
15
+ v = Larb::Vec4.new(1, 2, 3, 4)
16
+ assert_equal 1.0, v.x
17
+ assert_equal 2.0, v.y
18
+ assert_equal 3.0, v.z
19
+ assert_equal 4.0, v.w
20
+ end
21
+
22
+ def test_bracket_syntax
23
+ v = Larb::Vec4[1, 2, 3, 4]
24
+ assert_equal 1.0, v.x
25
+ assert_equal 2.0, v.y
26
+ assert_equal 3.0, v.z
27
+ assert_equal 4.0, v.w
28
+ end
29
+
30
+ def test_bracket_syntax_default_w
31
+ v = Larb::Vec4[1, 2, 3]
32
+ assert_equal 1.0, v.w
33
+ end
34
+
35
+ def test_zero
36
+ assert_equal Larb::Vec4.new(0, 0, 0, 0), Larb::Vec4.zero
37
+ end
38
+
39
+ def test_one
40
+ assert_equal Larb::Vec4.new(1, 1, 1, 1), Larb::Vec4.one
41
+ end
42
+
43
+ def test_add
44
+ v1 = Larb::Vec4.new(1, 2, 3, 4)
45
+ v2 = Larb::Vec4.new(5, 6, 7, 8)
46
+ assert_equal Larb::Vec4.new(6, 8, 10, 12), v1 + v2
47
+ end
48
+
49
+ def test_subtract
50
+ v1 = Larb::Vec4.new(5, 6, 7, 8)
51
+ v2 = Larb::Vec4.new(1, 2, 3, 4)
52
+ assert_equal Larb::Vec4.new(4, 4, 4, 4), v1 - v2
53
+ end
54
+
55
+ def test_multiply_by_scalar
56
+ v = Larb::Vec4.new(1, 2, 3, 4)
57
+ assert_equal Larb::Vec4.new(2, 4, 6, 8), v * 2
58
+ end
59
+
60
+ def test_divide_by_scalar
61
+ v = Larb::Vec4.new(2, 4, 6, 8)
62
+ assert_equal Larb::Vec4.new(1, 2, 3, 4), v / 2
63
+ end
64
+
65
+ def test_perspective_divide
66
+ v = Larb::Vec4.new(2, 4, 6, 2)
67
+ result = v.perspective_divide
68
+ assert_instance_of Larb::Vec3, result
69
+ assert_equal 1.0, result.x
70
+ assert_equal 2.0, result.y
71
+ assert_equal 3.0, result.z
72
+ end
73
+
74
+ def test_perspective_divide_w_is_1
75
+ v = Larb::Vec4.new(1, 2, 3, 1)
76
+ assert_equal Larb::Vec3.new(1, 2, 3), v.perspective_divide
77
+ end
78
+
79
+ def test_perspective_divide_w_is_0
80
+ v = Larb::Vec4.new(1, 2, 3, 0)
81
+ assert_raise(ArgumentError) { v.perspective_divide }
82
+ assert_equal Larb::Vec3.new(1, 2, 3), v.xyz
83
+ end
84
+
85
+ def test_perspective_divide_rejects_nonfinite_w
86
+ [Float::NAN, Float::INFINITY].each do |w|
87
+ assert_raise(ArgumentError) { Larb::Vec4.new(1, 2, 3, w).perspective_divide }
88
+ end
89
+ end
90
+
91
+ def test_xyz
92
+ v = Larb::Vec4.new(1, 2, 3, 4)
93
+ result = v.xyz
94
+ assert_instance_of Larb::Vec3, result
95
+ assert_equal Larb::Vec3.new(1, 2, 3), result
96
+ end
97
+
98
+ def test_xy
99
+ v = Larb::Vec4.new(1, 2, 3, 4)
100
+ result = v.xy
101
+ assert_instance_of Larb::Vec2, result
102
+ assert_equal Larb::Vec2.new(1, 2), result
103
+ end
104
+
105
+ def test_rgb
106
+ v = Larb::Vec4.new(0.5, 0.6, 0.7, 1.0)
107
+ result = v.rgb
108
+ assert_instance_of Larb::Vec3, result
109
+ assert_equal Larb::Vec3.new(0.5, 0.6, 0.7), result
110
+ end
111
+
112
+ def test_to_a
113
+ v = Larb::Vec4.new(1, 2, 3, 4)
114
+ assert_equal [1.0, 2.0, 3.0, 4.0], v.to_a
115
+ end
116
+
117
+ def test_index_access
118
+ v = Larb::Vec4.new(1, 2, 3, 4)
119
+ assert_equal 1.0, v[0]
120
+ assert_equal 2.0, v[1]
121
+ assert_equal 3.0, v[2]
122
+ assert_equal 4.0, v[3]
123
+ end
124
+
125
+ def test_negate
126
+ v = Larb::Vec4.new(1, -2, 3, -4)
127
+ assert_equal Larb::Vec4.new(-1, 2, -3, 4), -v
128
+ end
129
+
130
+ def test_dot
131
+ v1 = Larb::Vec4.new(1, 2, 3, 4)
132
+ v2 = Larb::Vec4.new(5, 6, 7, 8)
133
+ assert_equal 70.0, v1.dot(v2)
134
+ end
135
+
136
+ def test_length
137
+ v = Larb::Vec4.new(1, 2, 2, 0)
138
+ assert_equal 3.0, v.length
139
+ end
140
+
141
+ def test_length_squared
142
+ v = Larb::Vec4.new(1, 2, 2, 0)
143
+ assert_equal 9.0, v.length_squared
144
+ end
145
+
146
+ def test_normalize
147
+ v = Larb::Vec4.new(1, 2, 2, 0)
148
+ result = v.normalize
149
+ assert_in_delta 1.0, result.length, 1e-10
150
+ end
151
+
152
+ def test_normalize!
153
+ v = Larb::Vec4.new(1, 2, 2, 0)
154
+ v.normalize!
155
+ assert_in_delta 1.0, v.length, 1e-10
156
+ end
157
+
158
+ def test_equality
159
+ v1 = Larb::Vec4.new(1, 2, 3, 4)
160
+ v2 = Larb::Vec4.new(1, 2, 3, 4)
161
+ assert_equal v1, v2
162
+ end
163
+
164
+ def test_inequality
165
+ v1 = Larb::Vec4.new(1, 2, 3, 4)
166
+ v2 = Larb::Vec4.new(1, 2, 3, 5)
167
+ assert_not_equal v1, v2
168
+ end
169
+
170
+ def test_not_equal_to_array
171
+ v = Larb::Vec4.new(1, 2, 3, 4)
172
+ assert_not_equal v, [1, 2, 3, 4]
173
+ end
174
+
175
+ def test_near
176
+ v1 = Larb::Vec4.new(1.0, 2.0, 3.0, 4.0)
177
+ v2 = Larb::Vec4.new(1.0000001, 2.0000001, 3.0000001, 4.0000001)
178
+ assert v1.near?(v2)
179
+ end
180
+
181
+ def test_lerp
182
+ v1 = Larb::Vec4.new(0, 0, 0, 0)
183
+ v2 = Larb::Vec4.new(10, 20, 30, 40)
184
+ assert_equal Larb::Vec4.new(5, 10, 15, 20), v1.lerp(v2, 0.5)
185
+ end
186
+
187
+ def test_inspect
188
+ v = Larb::Vec4.new(1, 2, 3, 4)
189
+ assert_equal "Vec4[1.0, 2.0, 3.0, 4.0]", v.inspect
190
+ end
191
+
192
+ def test_to_s
193
+ v = Larb::Vec4.new(1, 2, 3, 4)
194
+ assert_equal v.inspect, v.to_s
195
+ end
196
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test-unit"
4
+ require_relative "../lib/larb"
metadata CHANGED
@@ -1,43 +1,85 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: larb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yudai Takada
8
8
  bindir: bin
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
- dependencies: []
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: rake-compiler
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '1.2'
19
+ type: :development
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '1.2'
12
26
  description: Larb provides vectors, matrices, quaternions, and Color classes for 2D/3D
13
27
  graphics and mathematical computations
14
28
  email:
15
29
  - t.yudai92@gmail.com
16
30
  executables: []
17
- extensions: []
31
+ extensions:
32
+ - ext/larb/extconf.rb
18
33
  extra_rdoc_files: []
19
34
  files:
20
35
  - CHANGELOG.md
21
36
  - LICENSE
22
37
  - README.md
23
- - Rakefile
38
+ - ext/larb/color.c
39
+ - ext/larb/color.h
40
+ - ext/larb/extconf.rb
41
+ - ext/larb/larb.c
42
+ - ext/larb/larb.h
43
+ - ext/larb/mat2.c
44
+ - ext/larb/mat2.h
45
+ - ext/larb/mat2d.c
46
+ - ext/larb/mat2d.h
47
+ - ext/larb/mat3.c
48
+ - ext/larb/mat3.h
49
+ - ext/larb/mat4.c
50
+ - ext/larb/mat4.h
51
+ - ext/larb/matrix_utils.h
52
+ - ext/larb/quat.c
53
+ - ext/larb/quat.h
54
+ - ext/larb/quat2.c
55
+ - ext/larb/quat2.h
56
+ - ext/larb/vec2.c
57
+ - ext/larb/vec2.h
58
+ - ext/larb/vec3.c
59
+ - ext/larb/vec3.h
60
+ - ext/larb/vec4.c
61
+ - ext/larb/vec4.h
24
62
  - lib/larb.rb
25
- - lib/larb/color.rb
26
- - lib/larb/mat2.rb
27
- - lib/larb/mat2d.rb
28
- - lib/larb/mat3.rb
29
- - lib/larb/mat4.rb
30
- - lib/larb/quat.rb
31
- - lib/larb/quat2.rb
32
- - lib/larb/vec2.rb
33
- - lib/larb/vec3.rb
34
- - lib/larb/vec4.rb
35
- homepage: https://github.com/ydah/larb
63
+ - lib/larb/version.rb
64
+ - test/larb/color_test.rb
65
+ - test/larb/mat2_test.rb
66
+ - test/larb/mat2d_test.rb
67
+ - test/larb/mat3_test.rb
68
+ - test/larb/mat4_test.rb
69
+ - test/larb/matrix_test.rb
70
+ - test/larb/native_value_test.rb
71
+ - test/larb/quat2_test.rb
72
+ - test/larb/quat_test.rb
73
+ - test/larb/vec2_test.rb
74
+ - test/larb/vec3_test.rb
75
+ - test/larb/vec4_test.rb
76
+ - test/test_helper.rb
77
+ homepage: https://github.com/rbgfx/larb
36
78
  licenses:
37
79
  - MIT
38
80
  metadata:
39
- source_code_uri: https://github.com/ydah/larb
40
- changelog_uri: https://github.com/ydah/larb/blob/main/CHANGELOG.md
81
+ source_code_uri: https://github.com/rbgfx/larb
82
+ changelog_uri: https://github.com/rbgfx/larb/blob/main/CHANGELOG.md
41
83
  rdoc_options: []
42
84
  require_paths:
43
85
  - lib
@@ -52,7 +94,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
52
94
  - !ruby/object:Gem::Version
53
95
  version: '0'
54
96
  requirements: []
55
- rubygems_version: 4.0.3
97
+ rubygems_version: 4.0.19
56
98
  specification_version: 4
57
99
  summary: Linear algebra library for 2D/3D graphics in Ruby
58
100
  test_files: []
data/Rakefile DELETED
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "bundler/gem_tasks"
4
- require "rake/testtask"
5
-
6
- Rake::TestTask.new(:test) do |t|
7
- t.libs << "test"
8
- t.test_files = FileList["test/**/*_test.rb"]
9
- end
10
-
11
- task default: :test
data/lib/larb/color.rb DELETED
@@ -1,148 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Larb
4
- class Color
5
- attr_accessor :r, :g, :b, :a
6
-
7
- def initialize(r = 0.0, g = 0.0, b = 0.0, a = 1.0)
8
- @r = r.to_f
9
- @g = g.to_f
10
- @b = b.to_f
11
- @a = a.to_f
12
- end
13
-
14
- def self.[](r, g, b, a = 1.0)
15
- new(r, g, b, a)
16
- end
17
-
18
- def self.rgb(r, g, b)
19
- new(r, g, b, 1.0)
20
- end
21
-
22
- def self.rgba(r, g, b, a)
23
- new(r, g, b, a)
24
- end
25
-
26
- def self.from_bytes(r, g, b, a = 255)
27
- new(r / 255.0, g / 255.0, b / 255.0, a / 255.0)
28
- end
29
-
30
- def self.from_hex(hex)
31
- hex = hex.delete("#")
32
- r = hex[0..1].to_i(16) / 255.0
33
- g = hex[2..3].to_i(16) / 255.0
34
- b = hex[4..5].to_i(16) / 255.0
35
- a = hex.length > 6 ? hex[6..7].to_i(16) / 255.0 : 1.0
36
- new(r, g, b, a)
37
- end
38
-
39
- def self.black
40
- new(0, 0, 0, 1)
41
- end
42
-
43
- def self.white
44
- new(1, 1, 1, 1)
45
- end
46
-
47
- def self.red
48
- new(1, 0, 0, 1)
49
- end
50
-
51
- def self.green
52
- new(0, 1, 0, 1)
53
- end
54
-
55
- def self.blue
56
- new(0, 0, 1, 1)
57
- end
58
-
59
- def self.yellow
60
- new(1, 1, 0, 1)
61
- end
62
-
63
- def self.cyan
64
- new(0, 1, 1, 1)
65
- end
66
-
67
- def self.magenta
68
- new(1, 0, 1, 1)
69
- end
70
-
71
- def self.transparent
72
- new(0, 0, 0, 0)
73
- end
74
-
75
- def +(other)
76
- Color.new(@r + other.r, @g + other.g, @b + other.b, @a + other.a)
77
- end
78
-
79
- def -(other)
80
- Color.new(@r - other.r, @g - other.g, @b - other.b, @a - other.a)
81
- end
82
-
83
- def *(scalar)
84
- case scalar
85
- when Numeric
86
- Color.new(@r * scalar, @g * scalar, @b * scalar, @a * scalar)
87
- when Color
88
- Color.new(@r * scalar.r, @g * scalar.g, @b * scalar.b, @a * scalar.a)
89
- end
90
- end
91
-
92
- def lerp(other, t)
93
- Color.new(
94
- @r + (other.r - @r) * t,
95
- @g + (other.g - @g) * t,
96
- @b + (other.b - @b) * t,
97
- @a + (other.a - @a) * t
98
- )
99
- end
100
-
101
- def clamp
102
- Color.new(
103
- @r.clamp(0.0, 1.0),
104
- @g.clamp(0.0, 1.0),
105
- @b.clamp(0.0, 1.0),
106
- @a.clamp(0.0, 1.0)
107
- )
108
- end
109
-
110
- def to_bytes
111
- [(@r * 255).round.clamp(0, 255),
112
- (@g * 255).round.clamp(0, 255),
113
- (@b * 255).round.clamp(0, 255),
114
- (@a * 255).round.clamp(0, 255)]
115
- end
116
-
117
- def to_hex
118
- r, g, b, a = to_bytes
119
- format("#%02x%02x%02x%02x", r, g, b, a)
120
- end
121
-
122
- def to_vec3
123
- Vec3.new(@r, @g, @b)
124
- end
125
-
126
- def to_vec4
127
- Vec4.new(@r, @g, @b, @a)
128
- end
129
-
130
- def to_a
131
- [@r, @g, @b, @a]
132
- end
133
-
134
- def self.from_vec4(v)
135
- new(v.x, v.y, v.z, v.w)
136
- end
137
-
138
- def self.from_vec3(v, a = 1.0)
139
- new(v.x, v.y, v.z, a)
140
- end
141
-
142
- def inspect
143
- "Color[#{@r}, #{@g}, #{@b}, #{@a}]"
144
- end
145
-
146
- alias to_s inspect
147
- end
148
- end
data/lib/larb/mat2.rb DELETED
@@ -1,119 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Larb
4
- class Mat2
5
- attr_reader :data
6
-
7
- def initialize(data = nil)
8
- @data = data || [1.0, 0.0, 0.0, 1.0]
9
- end
10
-
11
- def self.identity
12
- new
13
- end
14
-
15
- def self.zero
16
- new([0.0, 0.0, 0.0, 0.0])
17
- end
18
-
19
- def self.rotation(radians)
20
- c = Math.cos(radians)
21
- s = Math.sin(radians)
22
- new([c, s, -s, c])
23
- end
24
-
25
- def self.scaling(x, y)
26
- new([x.to_f, 0.0, 0.0, y.to_f])
27
- end
28
-
29
- def self.from_vec2(v1, v2)
30
- new([v1.x, v1.y, v2.x, v2.y])
31
- end
32
-
33
- def [](i)
34
- @data[i]
35
- end
36
-
37
- def []=(i, v)
38
- @data[i] = v.to_f
39
- end
40
-
41
- def *(other)
42
- case other
43
- when Mat2
44
- a = @data
45
- b = other.data
46
- Mat2.new([
47
- a[0] * b[0] + a[2] * b[1],
48
- a[1] * b[0] + a[3] * b[1],
49
- a[0] * b[2] + a[2] * b[3],
50
- a[1] * b[2] + a[3] * b[3]
51
- ])
52
- when Vec2
53
- Vec2.new(
54
- @data[0] * other.x + @data[2] * other.y,
55
- @data[1] * other.x + @data[3] * other.y
56
- )
57
- when Numeric
58
- Mat2.new(@data.map { |v| v * other })
59
- end
60
- end
61
-
62
- def +(other)
63
- Mat2.new(@data.zip(other.data).map { |a, b| a + b })
64
- end
65
-
66
- def -(other)
67
- Mat2.new(@data.zip(other.data).map { |a, b| a - b })
68
- end
69
-
70
- def determinant
71
- @data[0] * @data[3] - @data[2] * @data[1]
72
- end
73
-
74
- def inverse
75
- det = determinant
76
- raise "Matrix is not invertible" if det.abs < 1e-10
77
-
78
- inv_det = 1.0 / det
79
- Mat2.new([
80
- @data[3] * inv_det,
81
- -@data[1] * inv_det,
82
- -@data[2] * inv_det,
83
- @data[0] * inv_det
84
- ])
85
- end
86
-
87
- def transpose
88
- Mat2.new([@data[0], @data[2], @data[1], @data[3]])
89
- end
90
-
91
- def adjoint
92
- Mat2.new([@data[3], -@data[1], -@data[2], @data[0]])
93
- end
94
-
95
- def frobenius_norm
96
- Math.sqrt(@data.sum { |v| v * v })
97
- end
98
-
99
- def to_a
100
- @data.dup
101
- end
102
-
103
- def ==(other)
104
- return false unless other.is_a?(Mat2)
105
-
106
- @data == other.data
107
- end
108
-
109
- def near?(other, epsilon = 1e-6)
110
- @data.zip(other.data).all? { |a, b| (a - b).abs < epsilon }
111
- end
112
-
113
- def inspect
114
- "Mat2[#{@data[0]}, #{@data[1]}, #{@data[2]}, #{@data[3]}]"
115
- end
116
-
117
- alias to_s inspect
118
- end
119
- end