numerix 1.0.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 (60) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.travis.yml +5 -0
  4. data/.yardopts +5 -0
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +6 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +66 -0
  9. data/Rakefile +18 -0
  10. data/TODO.txt +25 -0
  11. data/bin/console +14 -0
  12. data/bin/setup +8 -0
  13. data/ext/numerix/common.h +107 -0
  14. data/ext/numerix/extconf.rb +3 -0
  15. data/ext/numerix/matrix3x2.c +638 -0
  16. data/ext/numerix/matrix3x2.h +52 -0
  17. data/ext/numerix/matrix4x4.c +1807 -0
  18. data/ext/numerix/matrix4x4.h +90 -0
  19. data/ext/numerix/matrix_base.c +307 -0
  20. data/ext/numerix/matrix_base.h +70 -0
  21. data/ext/numerix/numerix.c +33 -0
  22. data/ext/numerix/numerix.h +19 -0
  23. data/ext/numerix/plane.c +311 -0
  24. data/ext/numerix/plane.h +34 -0
  25. data/ext/numerix/quaternion.c +712 -0
  26. data/ext/numerix/quaternion.h +53 -0
  27. data/ext/numerix/structure.c +154 -0
  28. data/ext/numerix/structure.h +24 -0
  29. data/ext/numerix/vector.c +326 -0
  30. data/ext/numerix/vector.h +57 -0
  31. data/ext/numerix/vector2.c +641 -0
  32. data/ext/numerix/vector2.h +64 -0
  33. data/ext/numerix/vector3.c +805 -0
  34. data/ext/numerix/vector3.h +68 -0
  35. data/ext/numerix/vector4.c +727 -0
  36. data/ext/numerix/vector4.h +63 -0
  37. data/ext/numerix/vector_base.c +94 -0
  38. data/ext/numerix/vector_base.h +30 -0
  39. data/extra/numerix128.png +0 -0
  40. data/extra/numerix24.png +0 -0
  41. data/extra/numerix32.png +0 -0
  42. data/extra/numerix320.png +0 -0
  43. data/extra/numerix48.png +0 -0
  44. data/extra/numerix96.png +0 -0
  45. data/lib/numerix/error.rb +36 -0
  46. data/lib/numerix/matrix3x2.rb +420 -0
  47. data/lib/numerix/matrix4x4.rb +676 -0
  48. data/lib/numerix/matrix_base.rb +14 -0
  49. data/lib/numerix/plane.rb +154 -0
  50. data/lib/numerix/quaternion.rb +355 -0
  51. data/lib/numerix/structure.rb +124 -0
  52. data/lib/numerix/vector.rb +13 -0
  53. data/lib/numerix/vector2.rb +534 -0
  54. data/lib/numerix/vector3.rb +572 -0
  55. data/lib/numerix/vector4.rb +551 -0
  56. data/lib/numerix/vector_base.rb +14 -0
  57. data/lib/numerix/version.rb +6 -0
  58. data/lib/numerix.rb +10 -0
  59. data/numerix.gemspec +30 -0
  60. metadata +167 -0
@@ -0,0 +1,311 @@
1
+
2
+ #include "plane.h"
3
+
4
+ VALUE rb_cPlane;
5
+
6
+ void Init_plane(VALUE outer) {
7
+ rb_cPlane = rb_define_class_under(outer, "Plane", rb_cNumerixStruct);
8
+ rb_define_alloc_func(rb_cPlane, rb_plane_alloc);
9
+ rb_define_method(rb_cPlane, "initialize", rb_plane_initialize, -1);
10
+
11
+ // Instance
12
+ rb_define_method(rb_cPlane, "normal", rb_plane_normal, 0);
13
+ rb_define_method(rb_cPlane, "distance", rb_plane_distance, 0);
14
+ rb_define_method(rb_cPlane, "normal=", rb_plane_normal_set, 1);
15
+ rb_define_method(rb_cPlane, "distance=", rb_plane_distance_set, 1);
16
+ rb_define_method(rb_cPlane, "==", rb_plane_equal, 1);
17
+ rb_define_method(rb_cPlane, "transform", rb_plane_transform, 1);
18
+ rb_define_method(rb_cPlane, "transform!", rb_plane_transform_bang, 1);
19
+ rb_define_method(rb_cPlane, "dot", rb_plane_dot, 1);
20
+ rb_define_method(rb_cPlane, "dot_coord", rb_plane_dot_coord, 1);
21
+ rb_define_method(rb_cPlane, "dot_normal", rb_plane_dot_normal, 1);
22
+ rb_define_method(rb_cPlane, "normalize", rb_plane_normalize, 0);
23
+ rb_define_method(rb_cPlane, "normalize!", rb_plane_normalize_bang, 0);
24
+
25
+ // Conversion
26
+ rb_define_method(rb_cPlane, "to_s", rb_plane_to_s, 0);
27
+
28
+ // Class
29
+ rb_define_singleton_method(rb_cPlane, "from_vertices", rb_plane_from_vertices_s, 3);
30
+ }
31
+
32
+ static VALUE rb_plane_alloc(VALUE klass) {
33
+ Plane *p = ALLOC(Plane);
34
+ memset(p, 0, sizeof(Plane));
35
+ return NUMERIX_WRAP(klass, p);
36
+ }
37
+
38
+ VALUE rb_plane_initialize(int argc, VALUE *argv, VALUE self) {
39
+ PLANE();
40
+ switch (argc) {
41
+ case 0:
42
+ break;
43
+ case 1: {
44
+ Vector4 *vec4;
45
+ Data_Get_Struct(argv[0], Vector4, vec4);
46
+ memcpy(p, vec4, sizeof(Vector4));
47
+ break;
48
+ }
49
+ case 2: {
50
+ Vector3 *vec3;
51
+ Data_Get_Struct(argv[0], Vector3, vec3);
52
+ memcpy(p, vec3, sizeof(Vector3));
53
+ p->distance = NUM2FLT(argv[1]);
54
+ break;
55
+ }
56
+ case 4: {
57
+ p->normal.x = NUM2FLT(argv[0]);
58
+ p->normal.y = NUM2FLT(argv[1]);
59
+ p->normal.z = NUM2FLT(argv[2]);
60
+ p->distance = NUM2FLT(argv[3]);
61
+ break;
62
+ }
63
+ default:
64
+ rb_raise(rb_eArgError, "wrong number of arguments (given %d, expected 0, 1, 2, 4)", argc);
65
+ break;
66
+ }
67
+ return Qnil;
68
+ }
69
+
70
+ VALUE rb_plane_normal(VALUE self) {
71
+ PLANE();
72
+ return NUMERIX_WRAP(rb_cVector3, &(p->normal));
73
+ }
74
+
75
+ VALUE rb_plane_distance(VALUE self) {
76
+ PLANE();
77
+ return DBL2NUM(p->distance);
78
+ }
79
+
80
+ VALUE rb_plane_normal_set(VALUE self, VALUE value) {
81
+ PLANE();
82
+ Vector3 *v3;
83
+ Data_Get_Struct(value, Vector3, v3);
84
+ memcpy(p, v3, sizeof(Vector3));
85
+ return value;
86
+ }
87
+
88
+ VALUE rb_plane_distance_set(VALUE self, VALUE value) {
89
+ PLANE();
90
+ p->distance = NUM2FLT(value);
91
+ return value;
92
+ }
93
+
94
+ VALUE rb_plane_equal(VALUE self, VALUE other) {
95
+ if (CLASS_OF(other) != CLASS_OF(self))
96
+ return Qfalse;
97
+ Plane *p1, *p2;
98
+ Data_Get_Struct(self, Plane, p1);
99
+ Data_Get_Struct(other, Plane, p2);
100
+ return FLT_EQUAL(p1->normal.x, p2->normal.x) && FLT_EQUAL(p1->normal.y, p2->normal.y) &&
101
+ FLT_EQUAL(p1->normal.z, p2->normal.z) && FLT_EQUAL(p1->distance, p2->distance)
102
+ ? Qtrue
103
+ : Qfalse;
104
+ }
105
+
106
+ VALUE rb_plane_to_s(VALUE self) {
107
+ PLANE();
108
+ return rb_sprintf("{<%f, %f, %f>, %f}", p->normal.x, p->normal.y, p->normal.z, p->distance);
109
+ }
110
+
111
+ VALUE rb_plane_transform(VALUE self, VALUE matrix) {
112
+ PLANE();
113
+ Plane *result = ALLOC(Plane);
114
+
115
+ if (NUMERIX_TYPE_P(matrix, rb_cMatrix4x4)) {
116
+ VALUE inverted = rb_matrix4x4_invert(matrix);
117
+ Matrix4x4 *m;
118
+ Data_Get_Struct(inverted, Matrix4x4, m);
119
+
120
+ float x = p->normal.x, y = p->normal.y, z = p->normal.z, w = p->distance;
121
+
122
+ result->normal.x = x * m->m11 + y * m->m12 + z * m->m13 + w * m->m14;
123
+ result->normal.y = x * m->m21 + y * m->m22 + z * m->m23 + w * m->m24;
124
+ result->normal.z = x * m->m31 + y * m->m32 + z * m->m33 + w * m->m34;
125
+ result->distance = x * m->m41 + y * m->m42 + z * m->m43 + w * m->m44;
126
+ } else {
127
+ Quaternion *q;
128
+ Data_Get_Struct(matrix, Quaternion, q);
129
+
130
+ // Compute rotation matrix.
131
+ float x2 = q->x + q->x;
132
+ float y2 = q->y + q->y;
133
+ float z2 = q->z + q->z;
134
+
135
+ float wx2 = q->w * x2;
136
+ float wy2 = q->w * y2;
137
+ float wz2 = q->w * z2;
138
+ float xx2 = q->x * x2;
139
+ float xy2 = q->x * y2;
140
+ float xz2 = q->x * z2;
141
+ float yy2 = q->y * y2;
142
+ float yz2 = q->y * z2;
143
+ float zz2 = q->z * z2;
144
+
145
+ float m11 = 1.0f - yy2 - zz2;
146
+ float m21 = xy2 - wz2;
147
+ float m31 = xz2 + wy2;
148
+
149
+ float m12 = xy2 + wz2;
150
+ float m22 = 1.0f - xx2 - zz2;
151
+ float m32 = yz2 - wx2;
152
+
153
+ float m13 = xz2 - wy2;
154
+ float m23 = yz2 + wx2;
155
+ float m33 = 1.0f - xx2 - yy2;
156
+
157
+ float x = p->normal.x, y = p->normal.y, z = p->normal.z;
158
+
159
+ result->normal.x = x * m11 + y * m21 + z * m31;
160
+ result->normal.y = x * m12 + y * m22 + z * m32;
161
+ result->normal.y = x * m13 + y * m23 + z * m33;
162
+ result->distance = p->distance;
163
+ }
164
+
165
+ return NUMERIX_WRAP(CLASS_OF(self), result);
166
+ }
167
+
168
+ VALUE rb_plane_transform_bang(VALUE self, VALUE matrix) {
169
+ PLANE();
170
+
171
+ if (NUMERIX_TYPE_P(matrix, rb_cMatrix4x4)) {
172
+ VALUE inverted = rb_matrix4x4_invert(matrix);
173
+ Matrix4x4 *m;
174
+ Data_Get_Struct(inverted, Matrix4x4, m);
175
+
176
+ float x = p->normal.x, y = p->normal.y, z = p->normal.z, w = p->distance;
177
+
178
+ p->normal.x = x * m->m11 + y * m->m12 + z * m->m13 + w * m->m14;
179
+ p->normal.y = x * m->m21 + y * m->m22 + z * m->m23 + w * m->m24;
180
+ p->normal.z = x * m->m31 + y * m->m32 + z * m->m33 + w * m->m34;
181
+ p->distance = x * m->m41 + y * m->m42 + z * m->m43 + w * m->m44;
182
+ } else {
183
+ Quaternion *q;
184
+ Data_Get_Struct(matrix, Quaternion, q);
185
+
186
+ // Compute rotation matrix.
187
+ float x2 = q->x + q->x;
188
+ float y2 = q->y + q->y;
189
+ float z2 = q->z + q->z;
190
+
191
+ float wx2 = q->w * x2;
192
+ float wy2 = q->w * y2;
193
+ float wz2 = q->w * z2;
194
+ float xx2 = q->x * x2;
195
+ float xy2 = q->x * y2;
196
+ float xz2 = q->x * z2;
197
+ float yy2 = q->y * y2;
198
+ float yz2 = q->y * z2;
199
+ float zz2 = q->z * z2;
200
+
201
+ float m11 = 1.0f - yy2 - zz2;
202
+ float m21 = xy2 - wz2;
203
+ float m31 = xz2 + wy2;
204
+
205
+ float m12 = xy2 + wz2;
206
+ float m22 = 1.0f - xx2 - zz2;
207
+ float m32 = yz2 - wx2;
208
+
209
+ float m13 = xz2 - wy2;
210
+ float m23 = yz2 + wx2;
211
+ float m33 = 1.0f - xx2 - yy2;
212
+
213
+ float x = p->normal.x, y = p->normal.y, z = p->normal.z;
214
+
215
+ p->normal.x = x * m11 + y * m21 + z * m31;
216
+ p->normal.y = x * m12 + y * m22 + z * m32;
217
+ p->normal.y = x * m13 + y * m23 + z * m33;
218
+ p->distance = p->distance;
219
+ }
220
+
221
+ return self;
222
+ }
223
+
224
+ VALUE rb_plane_dot(VALUE self, VALUE vec4) {
225
+ PLANE();
226
+ Vector4 *v;
227
+ Data_Get_Struct(vec4, Vector4, v);
228
+
229
+ return DBL2NUM(p->normal.x * v->x + p->normal.y * v->y + p->normal.z * v->z + p->distance * v->w);
230
+ }
231
+
232
+ VALUE rb_plane_dot_coord(VALUE self, VALUE vec3) {
233
+ PLANE();
234
+ Vector3 *v;
235
+ Data_Get_Struct(vec3, Vector3, v);
236
+ return DBL2NUM(p->normal.x * v->x + p->normal.y * v->y + p->normal.z * v->z + p->distance);
237
+ }
238
+
239
+ VALUE rb_plane_dot_normal(VALUE self, VALUE vec3) {
240
+ PLANE();
241
+ Vector3 *v;
242
+ Data_Get_Struct(vec3, Vector3, v);
243
+
244
+ return DBL2NUM(p->normal.x * v->x + p->normal.y * v->y + p->normal.z * v->z);
245
+ }
246
+
247
+ VALUE rb_plane_normalize(VALUE self) {
248
+ PLANE();
249
+ Plane *result = ALLOC(Plane);
250
+
251
+ float f = p->normal.x * p->normal.x + p->normal.y * p->normal.y + p->normal.z * p->normal.z;
252
+
253
+ if (fabsf(f - 1.0f) < FLT_EPSILON) {
254
+ // It already normalized, so we don't need to further process.
255
+ memcpy(result, p, sizeof(Plane));
256
+ } else {
257
+ float fInv = 1.0f / sqrtf(f);
258
+ result->normal.x = p->normal.x * fInv;
259
+ result->normal.y = p->normal.y * fInv;
260
+ result->normal.z = p->normal.z * fInv;
261
+ result->distance = p->distance * fInv;
262
+ }
263
+
264
+ return NUMERIX_WRAP(CLASS_OF(self), result);
265
+ }
266
+
267
+ VALUE rb_plane_normalize_bang(VALUE self) {
268
+ PLANE();
269
+ float f = p->normal.x * p->normal.x + p->normal.y * p->normal.y + p->normal.z * p->normal.z;
270
+
271
+ if (fabsf(f - 1.0f) >= FLT_EPSILON) {
272
+ float fInv = 1.0f / sqrtf(f);
273
+ p->normal.x = p->normal.x * fInv;
274
+ p->normal.y = p->normal.y * fInv;
275
+ p->normal.z = p->normal.z * fInv;
276
+ p->distance = p->distance * fInv;
277
+ }
278
+
279
+ return self;
280
+ }
281
+
282
+ VALUE rb_plane_from_vertices_s(VALUE klass, VALUE vert1, VALUE vert2, VALUE vert3) {
283
+ Vector3 *v1, *v2, *v3;
284
+ Data_Get_Struct(vert1, Vector3, v1);
285
+ Data_Get_Struct(vert2, Vector3, v2);
286
+ Data_Get_Struct(vert3, Vector3, v3);
287
+
288
+ float ax = v2->x - v1->x;
289
+ float ay = v2->y - v1->y;
290
+ float az = v2->z - v1->z;
291
+
292
+ float bx = v3->x - v1->x;
293
+ float by = v3->y - v1->y;
294
+ float bz = v3->z - v1->z;
295
+
296
+ // N=Cross(a,b)
297
+ float nx = ay * bz - az * by;
298
+ float ny = az * bx - ax * bz;
299
+ float nz = ax * by - ay * bx;
300
+
301
+ // Normalize(N)
302
+ float invNorm = 1.0f / sqrtf(nx * nx + ny * ny + nz * nz);
303
+
304
+ Plane *p = ALLOC(Plane);
305
+ p->normal.x = nx * invNorm;
306
+ p->normal.y = ny * invNorm;
307
+ p->normal.z = nz * invNorm;
308
+ p->distance = -(p->normal.x * v1->x + p->normal.y * v1->y + p->normal.z * v1->z);
309
+
310
+ return NUMERIX_WRAP(klass, p);
311
+ }
@@ -0,0 +1,34 @@
1
+ #ifndef NUMERIX_PLANE_H
2
+ #define NUMERIX_PLANE_H 1
3
+
4
+ #include "common.h"
5
+ #include "matrix4x4.h"
6
+
7
+ #define PLANE() \
8
+ Plane *p; \
9
+ Data_Get_Struct(self, Plane, p)
10
+
11
+ void Init_plane(VALUE outer);
12
+ static VALUE rb_plane_alloc(VALUE klass);
13
+ VALUE rb_plane_initialize(int argc, VALUE *argv, VALUE self);
14
+
15
+ // Instance
16
+ VALUE rb_plane_normal(VALUE self);
17
+ VALUE rb_plane_distance(VALUE self);
18
+ VALUE rb_plane_normal_set(VALUE self, VALUE value);
19
+ VALUE rb_plane_distance_set(VALUE self, VALUE value);
20
+ VALUE rb_plane_equal(VALUE self, VALUE other);
21
+ VALUE rb_plane_to_s(VALUE self);
22
+ VALUE rb_plane_equal(VALUE self, VALUE other);
23
+ VALUE rb_plane_transform(VALUE self, VALUE matrix);
24
+ VALUE rb_plane_transform_bang(VALUE self, VALUE matrix);
25
+ VALUE rb_plane_dot(VALUE self, VALUE vec4);
26
+ VALUE rb_plane_dot_coord(VALUE self, VALUE vec3);
27
+ VALUE rb_plane_dot_normal(VALUE self, VALUE vec3);
28
+ VALUE rb_plane_normalize(VALUE self);
29
+ VALUE rb_plane_normalize_bang(VALUE self);
30
+
31
+ // Class
32
+ VALUE rb_plane_from_vertices_s(VALUE klass, VALUE vert1, VALUE vert2, VALUE vert3);
33
+
34
+ #endif /* NUMERIX_PLANE_H */