numerix 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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 */