@zushah/chalkboard 1.6.0 → 2.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.
@@ -1,3815 +0,0 @@
1
- /*
2
- The Chalkboard Library
3
- Version 1.6.0 released 12/25/2023
4
- Authored by Zushah ===> https://www.github.com/Zushah
5
- Available under the MIT License ===> https://www.opensource.org/license/mit/
6
-
7
- The Chalkboard library is a JavaScript namespace that provides a plethora of both practical and abstract mathematical functionalities for its user.
8
-
9
- Repository ===> https://www.github.com/Zushah/Chalkboard
10
- Website ===> https://zushah.github.io/Chalkboard/home.html
11
- */
12
- var Chalkboard = {
13
- README: function() {
14
- console.log("The Chalkboard Library\nVersion 1.6.0 released 12/25/2023\nAuthored by Zushah ===> https://www.github.com/Zushah\nAvailable under the MIT License ===> https://www.opensource.org/license/mit/\n\nThe Chalkboard library is a JavaScript namespace that provides a plethora of both practical and abstract mathematical functionalities for its user.\n\nRepository ===> https://www.github.com/Zushah/Chalkboard\nWebsite ===> https://zushah.github.io/Chalkboard/home.html");
15
- },
16
- LOGO: function(x, y, s) {
17
- x = x || width / 2;
18
- y = y || height / 2;
19
- s = s || 1;
20
- pushMatrix();
21
- translate(x, y);
22
- scale(s);
23
- noStroke();
24
- fill(25, 25, 25);
25
- rect(-50, -50, 100, 100);
26
- fill(50, 125, 200);
27
- textAlign(CENTER, CENTER);
28
- textSize(75);
29
- textFont(createFont("Times New Roman"));
30
- text("C", -25, 0);
31
- text("B", 25, 0);
32
- stroke(50, 125, 200);
33
- strokeWeight(6);
34
- strokeCap(SQUARE);
35
- line(-30, 25, -30, -22.5);
36
- line(22, 25, 22, -22.5);
37
- textAlign(TOP, LEFT);
38
- popMatrix();
39
- },
40
- PI: function(coefficient) {
41
- coefficient = coefficient || 1;
42
- return coefficient * 4 * (4 * Math.atan(1/5) - Math.atan(1/239));
43
- },
44
- E: function(exponent) {
45
- exponent = exponent || 1;
46
- return Math.pow(Math.pow(10, 1 / Math.log(10)), exponent);
47
- },
48
- numb: {
49
- random: function(inf, sup) {
50
- if(inf === undefined) {
51
- inf = 0;
52
- }
53
- if(sup === undefined) {
54
- sup = 1;
55
- }
56
- return inf + (sup - inf) * Math.random();
57
- },
58
- exponential: function(l) {
59
- if(l === undefined) {
60
- l = 1;
61
- }
62
- return l <= 0 ? 0 : -Math.log(Math.random()) / l;
63
- },
64
- Gaussian: function(height, mean, deviation) {
65
- var u1 = Math.random(), u2 = Math.random();
66
- var random = Chalkboard.real.sqrt(-2 * Chalkboard.real.ln(u1)) * Chalkboard.trig.cos(Chalkboard.PI(2) * u2);
67
- return random * height * Chalkboard.real.sqrt(deviation) + mean;
68
- },
69
- Bernoullian: function(p) {
70
- if(p === undefined) {
71
- p = 0.5;
72
- }
73
- return Math.random() < p ? 1 : 0;
74
- },
75
- Poissonian: function(l) {
76
- if(l === undefined) {
77
- l = 1;
78
- }
79
- if(l > 0) {
80
- var L = Chalkboard.E(-l);
81
- var p = 1, k = 0;
82
- for(; p > L; ++k) {
83
- p *= Math.random();
84
- }
85
- return k - 1;
86
- } else {
87
- return 0;
88
- }
89
- },
90
- factorial: function(num) {
91
- if(num >= 0) {
92
- var n = 1;
93
- for(var i = 1; i <= num; i++) {
94
- n *= i;
95
- }
96
- i--;
97
- return n;
98
- } else if(num < 0) {
99
- return undefined;
100
- }
101
- },
102
- gcd: function(a, b) {
103
- if(b === 0) {
104
- return a;
105
- }
106
- return Chalkboard.numb.gcd(b, a % b);
107
- },
108
- lcm: function(a, b) {
109
- return a * (b / Chalkboard.numb.gcd(a, b));
110
- },
111
- sum: function(formula, inf, sup) {
112
- var result = 0;
113
- var f = Chalkboard.real.parse("n => " + formula);
114
- for(var i = inf; i <= sup; i++) {
115
- result += f(i);
116
- }
117
- return result;
118
- },
119
- mul: function(formula, inf, sup) {
120
- var result = 1;
121
- var f = Chalkboard.real.parse("n => " + formula);
122
- for(var i = inf; i <= sup; i++) {
123
- result *= f(i);
124
- }
125
- return result;
126
- },
127
- combination: function(n, r) {
128
- return Chalkboard.numb.factorial(n) / (Chalkboard.numb.factorial(n - r) * Chalkboard.numb.factorial(r));
129
- },
130
- permutation: function(n, r) {
131
- return Chalkboard.numb.factorial(n) / Chalkboard.numb.factorial(n - r);
132
- },
133
- prime: function(num) {
134
- if(num === 2) {
135
- return 2;
136
- }
137
- var n = 1;
138
- var prime = 3;
139
- while(n < num) {
140
- if(Chalkboard.numb.isPrime(prime)) {
141
- n++;
142
- }
143
- if(n < num) {
144
- prime += 2;
145
- }
146
- }
147
- return prime;
148
- },
149
- isPrime: function(num) {
150
- for(var i = 2; i <= Chalkboard.real.sqrt(num); i++) {
151
- if(num % i === 0) {
152
- return false;
153
- }
154
- }
155
- return num > 1;
156
- },
157
- nextPrime: function(num) {
158
- var result = num + 1;
159
- while(!Chalkboard.numb.isPrime(result)) {
160
- result++;
161
- }
162
- return result;
163
- },
164
- primeGap: function(inf, sup) {
165
- var prime = null;
166
- var gap = 0;
167
- for(var i = inf; i <= sup; i++) {
168
- if(Chalkboard.numb.isPrime(i)) {
169
- if(prime !== null) {
170
- var temp = i - prime;
171
- if(temp > gap) {
172
- gap = temp;
173
- }
174
- }
175
- prime = i;
176
- }
177
- }
178
- return gap;
179
- },
180
- primeArr: function(inf, sup) {
181
- var result = [];
182
- for(var i = inf; i <= sup; i++) {
183
- if(Chalkboard.numb.isPrime(i)) {
184
- result.push(i);
185
- }
186
- }
187
- return result;
188
- },
189
- primeCount: function(inf, sup) {
190
- return Chalkboard.numb.primeArr(inf, sup).length;
191
- },
192
- compositeArr: function(inf, sup) {
193
- var result = [];
194
- for(var i = inf; i <= sup; i++) {
195
- if(!Chalkboard.numb.isPrime(i)) {
196
- result.push(i);
197
- }
198
- }
199
- return result;
200
- },
201
- compositeCount: function(inf, sup) {
202
- return Chalkboard.numb.compositeArr(inf, sup).length;
203
- },
204
- factors: function(num) {
205
- var result = [];
206
- while(num % 2 === 0) {
207
- result.push(2);
208
- num /= 2;
209
- }
210
- for(var i = 3; i <= Chalkboard.real.sqrt(num); i += 2) {
211
- while(num % i === 0) {
212
- result.push(i);
213
- num /= i;
214
- }
215
- }
216
- if(num > 2) {
217
- result.push(num);
218
- }
219
- return result;
220
- },
221
- divisors: function(num) {
222
- var result = [];
223
- for(var i = 1; i <= num; i++) {
224
- if(num % i === 0) {
225
- result.push(i);
226
- }
227
- }
228
- return result;
229
- },
230
- sgn: function(num) {
231
- if(num < 0) {
232
- return -1;
233
- } else if(num === 0) {
234
- return 0;
235
- } else if(num > 0) {
236
- return 1;
237
- }
238
- },
239
- Kronecker: function(a, b) {
240
- if(a === b) {
241
- return 1;
242
- } else if(a !== b) {
243
- return 0;
244
- } else {
245
- return undefined;
246
- }
247
- },
248
- change: function(initial, final) {
249
- return (final - initial) / initial;
250
- },
251
- map: function(num, range1, range2) {
252
- return range2[0] + (range2[1] - range2[0]) * ((num - range1[0]) / (range1[1] - range1[0]));
253
- },
254
- constrain: function(num, range) {
255
- if(range === undefined) {
256
- return Math.max(Math.min(num, 1), 0);
257
- } else {
258
- return Math.max(Math.min(num, range[1]), range[0]);
259
- }
260
- },
261
- binomial: function(n, k) {
262
- if(k === 0 || k === n) {
263
- return 1;
264
- } else {
265
- return Chalkboard.numb.binomial(n - 1, k - 1) + Chalkboard.numb.binomial(n - 1, k);
266
- }
267
- },
268
- Fibonacci: function(num) {
269
- var sequence = [0, 1];
270
- if(sequence[num] === undefined) {
271
- sequence.push(Chalkboard.numb.Fibonacci(num - 1) + sequence[num - 2]);
272
- }
273
- return sequence[num];
274
- },
275
- Goldbach: function(num) {
276
- if(num % 2 === 0) {
277
- if(num !== 4) {
278
- var a = num / 2, b = num / 2;
279
- if(a % 2 === 0) {
280
- a--;
281
- b++;
282
- }
283
- while(a >= 3) {
284
- if(Chalkboard.numb.isPrime(a) && Chalkboard.numb.isPrime(b)) {
285
- return [a, b];
286
- }
287
- a -= 2;
288
- b += 2;
289
- }
290
- return undefined;
291
- } else {
292
- return [2, 2];
293
- }
294
- } else {
295
- return undefined;
296
- }
297
- },
298
- Euler: function(num) {
299
- if(num > 0) {
300
- var factors = Chalkboard.numb.factors(num);
301
- for(var i = 0; i < factors.length; i++) {
302
- num *= (factors[i] - 1) / factors[i];
303
- }
304
- return num;
305
- } else {
306
- return undefined;
307
- }
308
- }
309
- },
310
- real: {
311
- function: function(definition, type) {
312
- type = type || "expl";
313
- if(type === "expl") {
314
- return {definition: definition, type: type};
315
- } else if(type === "inve") {
316
- return {definition: definition, type: type};
317
- } else if(type === "pola") {
318
- return {definition: definition, type: type};
319
- } else if(type === "curv") {
320
- return definition.length === 2 ? {definition: [definition[0], definition[1]], type: type} : {definition: [definition[0], definition[1], definition[2]], type: type};
321
- } else if(type === "surf") {
322
- return {definition: [definition[0], definition[1], definition[2]], type: type};
323
- } else if(type === "mult") {
324
- return {definition: definition, type: type};
325
- } else {
326
- return "TypeError: Parameter \"type\" must be either \"expl\", \"inve\", \"pola\", \"curv\", \"surf\", or \"mult\".";
327
- }
328
- },
329
- parse: function(str, init) {
330
- init = init || '';
331
- return Function('"use strict"; ' + init + ' return (' + str + ')')();
332
- },
333
- val: function(func, val) {
334
- if(func.type === "expl") {
335
- var f = Chalkboard.real.parse("x => " + func.definition);
336
- return f(val);
337
- } else if(func.type === "inve") {
338
- var f = Chalkboard.real.parse("y => " + func.definition);
339
- return f(val);
340
- } else if(func.type === "pola") {
341
- var r = Chalkboard.real.parse("O => " + func.definition);
342
- return r(val);
343
- } else if(func.type === "curv") {
344
- if(func.definition.length === 2) {
345
- var x = Chalkboard.real.parse("t => " + func.definition[0]),
346
- y = Chalkboard.real.parse("t => " + func.definition[1]);
347
- return Chalkboard.vec2.new(x(val), y(val));
348
- } else if(func.definition.length === 3) {
349
- var x = Chalkboard.real.parse("t => " + func.definition[0]),
350
- y = Chalkboard.real.parse("t => " + func.definition[1]),
351
- z = Chalkboard.real.parse("t => " + func.definition[2]);
352
- return Chalkboard.vec3.new(x(val), y(val), z(val));
353
- }
354
- } else if(func.type === "surf") {
355
- var x = Chalkboard.real.parse("(s, t) => " + func.definition[0]),
356
- y = Chalkboard.real.parse("(s, t) => " + func.definition[1]),
357
- z = Chalkboard.real.parse("(s, t) => " + func.definition[2]);
358
- if(val.type === "vec2") {
359
- return Chalkboard.vec3.new(x(val.x, val.y), y(val.x, val.y), z(val.x, val.y));
360
- } else {
361
- return "TypeError: Parameter \"val\" must be of type \"vec2\".";
362
- }
363
- } else if(func.type === "mult") {
364
- if(val.type === "vec2") {
365
- var f = Chalkboard.real.parse("(x, y) => " + func.definition);
366
- return f(val.x, val.y);
367
- } else {
368
- return "TypeError: Parameter \"val\" must be of type \"vec2\".";
369
- }
370
- } else {
371
- return "TypeError: Parameter \"func\" must be of type \"expl\", \"pola\", \"curv\", \"surf\", or \"mult\".";
372
- }
373
- },
374
- pow: function(base, num) {
375
- if(base === 0 && num === 0) {
376
- return 1;
377
- } else {
378
- return Math.exp(num * Math.log(base));
379
- }
380
- },
381
- log: function(base, num) {
382
- return Chalkboard.real.ln(num) / Chalkboard.real.ln(base);
383
- },
384
- ln: function(num) {
385
- return Chalkboard.calc.fxdx(Chalkboard.real.function("1 / x"), 1, num);
386
- },
387
- log10: function(num) {
388
- return Chalkboard.real.log(10, num);
389
- },
390
- sqrt: function(num) {
391
- if(num >= 0) {
392
- return Math.exp(Math.log(num) / 2);
393
- } else if(num < 0) {
394
- return undefined;
395
- }
396
- },
397
- root: function(num, index) {
398
- index = index || 3;
399
- return Math.exp(Math.log(num) / index);
400
- },
401
- tetration: function(base, num) {
402
- if(num === 0) {
403
- return 1;
404
- } else if(num > 0) {
405
- return Math.pow(base, Chalkboard.real.tetration(base, num - 1));
406
- } else {
407
- return undefined;
408
- }
409
- },
410
- Heaviside: function(num, edge, scl) {
411
- edge = edge || 0;
412
- scl = scl || 1;
413
- if(num >= edge) {
414
- return scl;
415
- } else if(num < edge) {
416
- return 0;
417
- }
418
- },
419
- Dirac: function(num, edge, scl) {
420
- edge = edge || 0;
421
- scl = scl || 1;
422
- if(num === edge) {
423
- return scl;
424
- } else if(num !== edge) {
425
- return 0;
426
- }
427
- },
428
- ramp: function(num, edge, scl) {
429
- edge = edge || 0;
430
- scl = scl || 1;
431
- if(num >= edge) {
432
- return num * scl;
433
- } else if(num < edge) {
434
- return 0;
435
- }
436
- },
437
- rect: function(num, center, width, scl) {
438
- center = center || 0;
439
- width = width || 2;
440
- scl = scl || 1;
441
- if(num > (center + width / 2) || num < (center - width / 2)) {
442
- return 0;
443
- } else if(num <= (center + width / 2) || num >= (center - width / 2)) {
444
- return scl;
445
- }
446
- },
447
- pingpong: function(num, edge, scl) {
448
- edge = edge || 0;
449
- scl = scl || 1;
450
- if((num + edge) % (2 * scl) < scl) {
451
- return (num + edge) % scl;
452
- } else {
453
- return scl - (num + edge) % scl;
454
- }
455
- },
456
- slope: function(x1, y1, x2, y2) {
457
- return (y2 - y1) / (x2 - x1);
458
- },
459
- linear: function(x1, y1, x2, y2) {
460
- return Chalkboard.real.function(Chalkboard.real.slope(x1, y1, x2, y2).toString() + " * (x - " + x2.toString() + ") + " + y2.toString());
461
- },
462
- linearFormula: function(a, b, c, d) {
463
- if(c === undefined && d === undefined) {
464
- return -b / a;
465
- } else if(d === undefined) {
466
- return c / a;
467
- } else {
468
- return -b / Chalkboard.real.slope(a, b, c, d) + a;
469
- }
470
- },
471
- lerp: function(p, t) {
472
- return (p[1] - p[0]) * t + p[0];
473
- },
474
- quadratic: function(a, b, c, form) {
475
- form = form || "stan";
476
- if(form === "stan") {
477
- return Chalkboard.real.function(a.toString() + "* x * x + " + b.toString() + " * x +" + c.toString());
478
- } else if(form === "vert") {
479
- return Chalkboard.real.function(a.toString() + " * ((x - " + b.toString() + ") * (x - " + b.toString() + ")) +" + c.toString());
480
- } else {
481
- return "TypeError: Parameter \"form\" must be \"stan\" or \"vert\".";
482
- }
483
- },
484
- discriminant: function(a, b, c, form) {
485
- form = form || "stan";
486
- if(form === "stan") {
487
- return b * b - 4 * a * c;
488
- } else if(form === "vert") {
489
- return (2 * a * b) * (2 * a * b) - 4 * a * c;
490
- } else {
491
- return "TypeError: Parameter \"form\" must be \"stan\" or \"vert\".";
492
- }
493
- },
494
- quadraticFormula: function(a, b, c, form) {
495
- form = form || "stan";
496
- if(form === "stan") {
497
- return [(-b + Chalkboard.real.sqrt(Chalkboard.real.discriminant(a, b, c, "stan"))) / (2 * a), (-b - Math.sqrt(Chalkboard.real.discriminant(a, b, c, "stan"))) / (2 * a)];
498
- } else if(form === "vert") {
499
- return [b + Chalkboard.real.sqrt(-c / a), b - Chalkboard.real.sqrt(-c / a)];
500
- } else {
501
- return "TypeError: Parameter \"form\" must be \"stan\" or \"vert\".";
502
- }
503
- },
504
- qerp: function(p1, p2, p3, t) {
505
- var a = p1[1] / ((p1[0] - p2[0]) * (p1[0] - p3[0])) + p2[1] / ((p2[0] - p1[0]) * (p2[0] - p3[0])) + p3[1] / ((p3[0] - p1[0]) * (p3[0] - p2[0]));
506
- var b = -p1[1] * (p2[0] + p3[0]) / ((p1[0] - p2[0]) * (p1[0] - p3[0])) - p2[1] * (p1[0] + p3[0]) / ((p2[0] - p1[0]) * (p2[0] - p3[0])) - p3[1] * (p1[0] + p2[0]) / ((p3[0] - p1[0]) * (p3[0] - p2[0]));
507
- var c = p1[1] * p2[0] * p3[0] / ((p1[0] - p2[0]) * (p1[0] - p3[0])) + p2[1] * p1[0] * p3[0] / ((p2[0] - p1[0]) * (p2[0] - p3[0])) + p3[1] * p1[0] * p2[0] / ((p3[0] - p1[0]) * (p3[0] - p2[0]));
508
- return a * t * t + b * t + c;
509
- }
510
- },
511
- comp: {
512
- new: function(a, b) {
513
- return {a: a, b: b, type: "comp"};
514
- },
515
- function: function(realDefinition, imagDefinition) {
516
- return {definition: [realDefinition, imagDefinition], type: "comp"};
517
- },
518
- parse: function(str, init) {
519
- init = init || '';
520
- return Function('"use strict"; ' + init + ' return (' + str + ')')();
521
- },
522
- val: function(func, comp) {
523
- if(func.type === "comp") {
524
- var u = Chalkboard.comp.parse("(a, b) => " + func.definition[0]),
525
- v = Chalkboard.comp.parse("(a, b) => " + func.definition[1]);
526
- return Chalkboard.comp.new(u(comp.a, comp.b), v(comp.a, comp.b));
527
- } else {
528
- return "TypeError: Parameter \"func\" must be of type \"comp\".";
529
- }
530
- },
531
- Re: function(funcORcomp) {
532
- if(funcORcomp.definition !== undefined && funcORcomp.type === "comp") {
533
- return funcORcomp.definition[0];
534
- } else if(funcORcomp.a !== undefined && funcORcomp.type === "comp") {
535
- return funcORcomp.a;
536
- }
537
- },
538
- Im: function(funcORcomp) {
539
- if(funcORcomp.definition !== undefined && funcORcomp.type === "comp") {
540
- return funcORcomp.definition[1];
541
- } else if(funcORcomp.b !== undefined && funcORcomp.type === "comp") {
542
- return funcORcomp.b;
543
- }
544
- },
545
- random: function(inf, sup) {
546
- return Chalkboard.comp.new(Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup));
547
- },
548
- mag: function(comp) {
549
- return Chalkboard.real.sqrt((comp.a * comp.a) + (comp.b * comp.b));
550
- },
551
- magsq: function(comp) {
552
- return (comp.a * comp.a) + (comp.b * comp.b);
553
- },
554
- magset: function(comp, num) {
555
- return Chalkboard.comp.scl(Chalkboard.comp.normalize(comp), num);
556
- },
557
- arg: function(comp) {
558
- return Chalkboard.trig.arctan2(comp.b, comp.a);
559
- },
560
- slope: function(comp) {
561
- return comp.b / comp.a;
562
- },
563
- average: function(comp) {
564
- return (comp.a + comp.b) / 2;
565
- },
566
- normalize: function(comp) {
567
- return Chalkboard.comp.new(comp.a / Chalkboard.comp.mag(comp), comp.b / Chalkboard.comp.mag(comp));
568
- },
569
- zero: function(comp) {
570
- return Chalkboard.comp.new(comp.a * 0, comp.b * 0);
571
- },
572
- negate: function(comp) {
573
- return Chalkboard.comp.new(-comp.a, -comp.b);
574
- },
575
- reciprocate: function(comp) {
576
- return Chalkboard.comp.new(1 / comp.a, 1 / comp.b);
577
- },
578
- absolute: function(comp) {
579
- return Chalkboard.comp.new(Math.abs(comp.a), Math.abs(comp.b));
580
- },
581
- round: function(comp) {
582
- return Chalkboard.comp.new(Math.round(comp.a), Math.round(comp.b));
583
- },
584
- Euler: function(rad) {
585
- return Chalkboard.comp.new(Chalkboard.trig.cos(rad), Chalkboard.trig.sin(rad));
586
- },
587
- pow: function(comp, num) {
588
- return Chalkboard.comp.new(Chalkboard.real.pow(Chalkboard.comp.mag(comp), num) * Chalkboard.trig.cos(num * Chalkboard.comp.arg(comp)), Chalkboard.real.pow(Chalkboard.comp.mag(comp), num) * Chalkboard.trig.sin(num * Chalkboard.comp.arg(comp)));
589
- },
590
- ln: function(comp) {
591
- return Chalkboard.comp.new(Chalkboard.real.ln(Chalkboard.comp.mag(comp)), Chalkboard.trig.arctan2(comp.b, comp.a));
592
- },
593
- sq: function(comp) {
594
- return Chalkboard.comp.new((comp.a * comp.a) - (comp.b * comp.b), 2 * comp.a * comp.b);
595
- },
596
- sqrt: function(comp) {
597
- return Chalkboard.comp.new(Chalkboard.real.sqrt((comp.a + Chalkboard.real.sqrt((comp.a * comp.a) + (comp.b * comp.b))) / 2), Chalkboard.numb.sgn(comp.b) * Chalkboard.real.sqrt((-comp.a + Chalkboard.real.sqrt((comp.a * comp.a) + (comp.b * comp.b))) / 2));
598
- },
599
- root: function(comp, index) {
600
- index = index || 3;
601
- if(Number.isInteger(index) && index > 0) {
602
- var result = [];
603
- var r = Chalkboard.comp.mag(comp);
604
- var t = Chalkboard.comp.arg(comp);
605
- for(var i = 0; i < index; i++) {
606
- result.push(Chalkboard.comp.new(Chalkboard.real.root(r, index) * Chalkboard.trig.cos((t + Chalkboard.PI(2 * i)) / index), Chalkboard.real.root(r, index) * Chalkboard.trig.sin((t + Chalkboard.PI(2 * i)) / index)));
607
- }
608
- return result;
609
- }
610
- },
611
- rotate: function(comp, rad) {
612
- return Chalkboard.comp.new(Chalkboard.comp.mag(comp) * Chalkboard.trig.cos(Chalkboard.comp.arg(comp) + rad), Chalkboard.comp.mag(comp) * Chalkboard.trig.sin(Chalkboard.comp.arg(comp) + rad));
613
- },
614
- invert: function(comp) {
615
- return Chalkboard.comp.new(comp.a / Chalkboard.comp.magsq(comp), -comp.b / Chalkboard.comp.magsq(comp));
616
- },
617
- conjugate: function(comp) {
618
- return Chalkboard.comp.new(comp.a, -comp.b);
619
- },
620
- dist: function(comp_1, comp_2) {
621
- return Chalkboard.real.sqrt(((comp_2.a - comp_1.a) * (comp_2.a - comp_1.a)) + ((comp_2.b - comp_1.b) * (comp_2.b - comp_1.b)));
622
- },
623
- distsq: function(comp_1, comp_2) {
624
- return ((comp_2.a - comp_1.a) * (comp_2.a - comp_1.a)) + ((comp_2.b - comp_1.b) * (comp_2.b - comp_1.b));
625
- },
626
- scl: function(comp, num) {
627
- return Chalkboard.comp.new(comp.a * num, comp.b * num);
628
- },
629
- constrain: function(comp, range) {
630
- return Chalkboard.comp.new(Chalkboard.numb.constrain(comp.a, range), Chalkboard.numb.constrain(comp.b, range));
631
- },
632
- add: function(comp_1, comp_2) {
633
- return Chalkboard.comp.new(comp_1.a + comp_2.a, comp_1.b + comp_2.b);
634
- },
635
- sub: function(comp_1, comp_2) {
636
- return Chalkboard.comp.new(comp_1.a - comp_2.a, comp_1.b - comp_2.b);
637
- },
638
- mul: function(comp_1, comp_2) {
639
- return Chalkboard.comp.new((comp_1.a * comp_2.a) - (comp_1.b * comp_2.b), (comp_1.a * comp_2.b) + (comp_1.b * comp_2.a));
640
- },
641
- div: function(comp_1, comp_2) {
642
- return Chalkboard.comp.new(((comp_1.a * comp_2.a) - (comp_1.b * comp_2.b)) / Chalkboard.comp.magsq(comp_2), ((comp_1.a * comp_2.b) + (comp_1.b * comp_2.a)) / Chalkboard.comp.magsq(comp_2));
643
- },
644
- toVector: function(comp) {
645
- return Chalkboard.vec2.new(comp.a, comp.b);
646
- },
647
- toArray: function(comp) {
648
- return [comp.a, comp.b];
649
- },
650
- toString: function(comp) {
651
- if(comp.b >= 0) {
652
- return comp.a.toString() + " + " + comp.b.toString() + "i";
653
- } else if(comp.b < 0) {
654
- return comp.a.toString() + " - " + Math.abs(comp.b).toString() + "i";
655
- }
656
- },
657
- print: function(comp) {
658
- console.log(Chalkboard.comp.toString(comp));
659
- }
660
- },
661
- quat: {
662
- new: function(a, b, c, d) {
663
- return {a: a, b: b, c: c, d: d, type: "quat"};
664
- },
665
- random: function(inf, sup) {
666
- return Chalkboard.quat.new(Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup));
667
- },
668
- mag: function(quat) {
669
- return Chalkboard.real.sqrt((quat.a * quat.a) + (quat.b * quat.b) + (quat.c * quat.c) + (quat.d * quat.d));
670
- },
671
- magsq: function(quat) {
672
- return (quat.a * quat.a) + (quat.b * quat.b) + (quat.c * quat.c) + (quat.d * quat.d);
673
- },
674
- magset: function(quat, num) {
675
- return Chalkboard.quat.scl(Chalkboard.quat.normalize(quat), num);
676
- },
677
- average: function(quat) {
678
- return (quat.a + quat.b + quat.c + quat.d) / 4;
679
- },
680
- normalize: function(quat) {
681
- return Chalkboard.quat.new(quat.a / Chalkboard.quat.mag(quat), quat.b / Chalkboard.quat.mag(quat), quat.c / Chalkboard.quat.mag(quat), quat.d / Chalkboard.quat.mag(quat));
682
- },
683
- zero: function(quat) {
684
- return Chalkboard.quat.new(quat.a * 0, quat.b * 0, quat.c * 0, quat.d * 0);
685
- },
686
- negate: function(quat) {
687
- return Chalkboard.quat.new(-quat.a, -quat.b, -quat.c, -quat.d);
688
- },
689
- reciprocate: function(quat) {
690
- return Chalkboard.quat.new(1 / quat.a, 1 / quat.b, 1 / quat.c, 1 / quat.d);
691
- },
692
- absolute: function(quat) {
693
- return Chalkboard.quat.new(Math.abs(quat.a), Math.abs(quat.b), Math.abs(quat.c), Math.abs(quat.d));
694
- },
695
- round: function(quat) {
696
- return Chalkboard.quat.new(Math.round(quat.a), Math.round(quat.b), Math.round(quat.c), Math.round(quat.d));
697
- },
698
- invert: function(quat) {
699
- return Chalkboard.quat.new(quat.a / Chalkboard.quat.magsq(quat), -quat.b / Chalkboard.quat.magsq(quat), -quat.c / Chalkboard.quat.magsq(quat), -quat.d / Chalkboard.quat.magsq(quat));
700
- },
701
- conjugate: function(quat) {
702
- return Chalkboard.quat.new(quat.a, -quat.b, -quat.c, -quat.d);
703
- },
704
- dist: function(quat_1, quat_2) {
705
- return Chalkboard.real.sqrt(((quat_2.a - quat_1.a) * (quat_2.a - quat_1.a)) + ((quat_2.b - quat_1.b) * (quat_2.b - quat_1.b)) + ((quat_2.c - quat_1.c) * (quat_2.c - quat_1.c)) + ((quat_2.d - quat_1.d) * (quat_2.d - quat_1.d)));
706
- },
707
- distsq: function(quat_1, quat_2) {
708
- return ((quat_2.a - quat_1.a) * (quat_2.a - quat_1.a)) + ((quat_2.b - quat_1.b) * (quat_2.b - quat_1.b)) + ((quat_2.c - quat_1.c) * (quat_2.c - quat_1.c)) + ((quat_2.d - quat_1.d) * (quat_2.d - quat_1.d));
709
- },
710
- scl: function(quat, num) {
711
- return Chalkboard.quat.new(quat.a * num, quat.b * num, quat.c * num, quat.d * num);
712
- },
713
- constrain: function(quat, range) {
714
- return Chalkboard.quat.new(Chalkboard.numb.constrain(quat.a, range), Chalkboard.numb.constrain(quat.b, range), Chalkboard.numb.constrain(quat.c, range), Chalkboard.numb.constrain(quat.d, range));
715
- },
716
- add: function(quat_1, quat_2) {
717
- return Chalkboard.quat.new(quat_1.a + quat_2.a, quat_1.b + quat_2.b, quat_1.c + quat_2.c, quat_1.d + quat_2.d);
718
- },
719
- sub: function(quat_1, quat_2) {
720
- return Chalkboard.quat.new(quat_1.a - quat_2.a, quat_1.b - quat_2.b, quat_1.c - quat_2.c, quat_1.d - quat_2.d);
721
- },
722
- mul: function(quat_1, quat_2) {
723
- return Chalkboard.quat.new((quat_1.a * quat_2.a) - (quat_1.b * quat_2.b) - (quat_1.c * quat_2.c) - (quat_1.d * quat_2.d), (quat_1.a * quat_2.b) + (quat_1.b * quat_2.a) + (quat_1.c * quat_2.d) - (quat_1.d * quat_2.c), (quat_1.a * quat_2.c) - (quat_1.b * quat_2.d) + (quat_1.c * quat_2.a) + (quat_1.d * quat_2.b), (quat_1.a * quat_2.d) + (quat_1.b * quat_2.c) - (quat_1.c * quat_2.b) + (quat_1.d * quat_2.a));
724
- },
725
- fromAxis: function(vec3, rad) {
726
- return Chalkboard.quat.new(Chalkboard.trig.cos(rad / 2), vec3.x * Chalkboard.trig.sin(rad / 2), vec3.y * Chalkboard.trig.sin(rad / 2), vec3.z * Chalkboard.trig.sin(rad / 2));
727
- },
728
- fromVector: function(vec3) {
729
- return Chalkboard.quat.new(0, vec3.x, vec3.y, vec3.z);
730
- },
731
- toRotation: function(quat, vec3) {
732
- var vector = Chalkboard.quat.fromVector(vec3);
733
- var inverse = Chalkboard.quat.invert(quat);
734
- var quat_vector_inverse = Chalkboard.quat.mul(quat, Chalkboard.quat.mul(vector, inverse));
735
- return Chalkboard.vec3.new(quat_vector_inverse.b, quat_vector_inverse.c, quat_vector_inverse.d);
736
- },
737
- toVector: function(quat) {
738
- return Chalkboard.vec4.new(quat.a, quat.b, quat.c, quat.d);
739
- },
740
- toArray: function(quat) {
741
- return [quat.a, quat.b, quat.c, quat.d];
742
- },
743
- toString: function(quat) {
744
- var quat_b = "";
745
- var quat_c = "";
746
- var quat_d = "";
747
- if(quat.b >= 0) {
748
- quat_b = " + " + quat.b.toString() + "i ";
749
- } else if(quat.b < 0) {
750
- quat_b = " - " + Math.abs(quat.b.toString()) + "i ";
751
- }
752
- if(quat.c >= 0) {
753
- quat_c = "+ " + quat.c.toString() + "j ";
754
- } else if(quat.c < 0) {
755
- quat_c = "- " + Math.abs(quat.c.toString()) + "j ";
756
- }
757
- if(quat.d >= 0) {
758
- quat_d = "+ " + quat.d.toString() + "k ";
759
- } else if(quat.d < 0) {
760
- quat_d = "- " + Math.abs(quat.d.toString()) + "k ";
761
- }
762
- return quat.a.toString() + quat_b + quat_c + quat_d;
763
- },
764
- print: function(quat) {
765
- console.log(Chalkboard.quat.toString(quat));
766
- }
767
- },
768
- plot: {
769
- CONTEXT: "ctx",
770
- xyplane: function(config) {
771
- config = config || {};
772
- config = {
773
- size: config.size || 1,
774
- stroke: config.stroke || color(0),
775
- origin: config.origin || [width / 2, height / 2],
776
- strokeWeight: config.strokeWeight || 2
777
- };
778
- config.size /= 100;
779
- pushMatrix();
780
- translate(config.origin[0], config.origin[1]);
781
- stroke(config.stroke);
782
- strokeWeight(config.strokeWeight / 4);
783
- for(var i = Math.floor(-config.origin[0] / config.size); i <= (width - config.origin[0]) / config.size; i++) {
784
- line(i / config.size, -config.origin[1], i / config.size, width - config.origin[1]);
785
- }
786
- for(var i = Math.floor(-config.origin[1] / config.size); i <= (width - config.origin[1]) / config.size; i++) {
787
- line(-config.origin[0], i / config.size, width - config.origin[0], i / config.size);
788
- }
789
- strokeWeight(config.strokeWeight);
790
- line(-config.origin[0], 0, width - config.origin[0], 0);
791
- line(0, -config.origin[1], 0, width - config.origin[1]);
792
- popMatrix();
793
- },
794
- rOplane: function(config) {
795
- config = config || {};
796
- config = {
797
- size: config.size || 1,
798
- stroke: config.stroke || color(0),
799
- origin: config.origin || [width / 2, height / 2],
800
- strokeWeight: config.strokeWeight || 2
801
- };
802
- config.size /= 100;
803
- pushMatrix();
804
- translate(config.origin[0], config.origin[1]);
805
- noFill();
806
- stroke(config.stroke);
807
- strokeWeight(config.strokeWeight / 4);
808
- for(var i = 0; i <= config.size * width / 2; i++) {
809
- ellipse(0, 0, 2 * i / config.size, 2 * i / config.size);
810
- }
811
- strokeWeight(config.strokeWeight);
812
- line(-config.origin[0], 0, width - config.origin[0], 0);
813
- line(0, -config.origin[1], 0, width - config.origin[1]);
814
- popMatrix();
815
- },
816
- function: function(func, config) {
817
- config = config || {};
818
- config = {
819
- size: config.size || 1,
820
- stroke: config.stroke || color(0),
821
- domain: config.domain || (func.type === "comp" ? [[-10, 10], [-10, 10]] : [-10, 10]),
822
- origin: config.origin || [width / 2, height / 2],
823
- strokeWeight: config.strokeWeight || 2
824
- };
825
- config.size /= 100;
826
- var data = [];
827
- pushMatrix();
828
- translate(config.origin[0], config.origin[1]);
829
- noFill();
830
- strokeWeight(config.strokeWeight);
831
- stroke(config.stroke);
832
- beginShape();
833
- if(func.type === "expl") {
834
- var f = Chalkboard.real.parse("x => " + func.definition);
835
- for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i++) {
836
- vertex(i, -f(i * config.size) / config.size);
837
- data.push([i, f(i)]);
838
- }
839
- } else if(func.type === "inve") {
840
- var f = Chalkboard.real.parse("y => " + func.definition);
841
- for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i++) {
842
- vertex(f(i * config.size) / config.size, -i);
843
- data.push([f(i), i]);
844
- }
845
- } else if(func.type === "pola") {
846
- var r = Chalkboard.real.parse("O => " + func.definition);
847
- for(var i = config.domain[0] / config.size; i < config.domain[1] / config.size; i++) {
848
- vertex(r(i * config.size) / config.size * Chalkboard.trig.cos(i * config.size), -r(i * config.size) / config.size * Chalkboard.trig.sin(i * config.size));
849
- data.push([i, r(i)]);
850
- }
851
- } else if(func.type === "curv") {
852
- var x = Chalkboard.real.parse("t => " + func.definition[0]),
853
- y = Chalkboard.real.parse("t => " + func.definition[1]);
854
- for(var i = config.domain[0] / config.size; i < config.domain[1] / config.size; i++) {
855
- vertex(x(i * config.size) / config.size, -y(i * config.size) / config.size);
856
- data.push([x(i), y(i)]);
857
- }
858
- } else if(func.type === "comp") {
859
- var u = Chalkboard.comp.parse("(a, b) => " + func.definition[0]),
860
- v = Chalkboard.comp.parse("(a, b) => " + func.definition[1]);
861
- for(var i = config.domain[0][0] / config.size; i <= config.domain[0][1] / config.size; i += 5) {
862
- for(var j = config.domain[1][0] / config.size; j <= config.domain[1][1] / config.size; j += 5) {
863
- var z = Chalkboard.comp.new(u(i * config.size, j * config.size) / config.size, v(i * config.size, j * config.size) / config.size);
864
- noStroke();
865
- if(z.a === 0 && z.b === 0) {
866
- fill(0, 0, 0);
867
- } else if(z.a === Infinity && z.b === Infinity) {
868
- fill(255, 255, 255);
869
- } else {
870
- colorMode(HSB);
871
- fill(Chalkboard.numb.map(Chalkboard.trig.toDeg(Chalkboard.comp.arg(z)), [0, 360], [0, 255]), 255, Chalkboard.numb.map((Chalkboard.trig.tanh(Chalkboard.comp.mag(z) / Chalkboard.real.pow(10, 20)) + 0.5) * 100, [0, 100], [0, 255]));
872
- colorMode(RGB);
873
- }
874
- rect(i, j, 5, 5);
875
- data.push([u(i, j), v(i, j)]);
876
- }
877
- }
878
- } else {
879
- return "TypeError: Property \"type\" of parameter \"func\" must be either \"expl\", \"inve\", \"pola\", \"curv\", or \"comp\".";
880
- }
881
- endShape();
882
- popMatrix();
883
- return data;
884
- },
885
- barplot: function(arr, bins, config) {
886
- config = config || {};
887
- config = {
888
- size: config.size || 1,
889
- stroke: config.stroke || color(0),
890
- fill: config.fill || color(255),
891
- origin: config.origin || [width / 2, height / 2],
892
- strokeWeight: config.strokeWeight || 2
893
- };
894
- config.size /= 100;
895
- pushMatrix();
896
- translate(config.origin[0], config.origin[1]);
897
- strokeWeight(config.strokeWeight);
898
- stroke(config.stroke);
899
- fill(config.fill);
900
- var bars = [];
901
- for(var i = 0; i < bins.length; i++) {
902
- if(i === 0) {
903
- bars.push(Chalkboard.stat.lt(arr, bins[0], true));
904
- } else if(i === bins.length) {
905
- bars.push(Chalkboard.stat.gt(arr, bins[bins.length - 1], true));
906
- } else {
907
- bars.push(Chalkboard.stat.ineq(arr, bins[i - 1], bins[i], false, true));
908
- }
909
- }
910
- var counts = [];
911
- for(var i = 0; i < bars.length; i++) {
912
- counts.push(bars[i].length);
913
- }
914
- var x = 0, width = counts.length / (2 * config.size);
915
- for(var i = 0; i < counts.length; i++) {
916
- rect(x - width, 0, 1 / config.size, -counts[i] / config.size);
917
- x += 1 / config.size;
918
- }
919
- popMatrix();
920
- return bars;
921
- },
922
- lineplot: function(arr, bins, config) {
923
- config = config || {};
924
- config = {
925
- size: config.size || 1,
926
- stroke: config.stroke || color(0),
927
- origin: config.origin || [width / 2, height / 2],
928
- strokeWeight: config.strokeWeight || 2
929
- };
930
- config.size /= 100;
931
- pushMatrix();
932
- translate(config.origin[0], config.origin[1]);
933
- noFill();
934
- strokeWeight(config.strokeWeight);
935
- stroke(config.stroke);
936
- var verts = [];
937
- for(var i = 0; i < bins.length; i++) {
938
- if(i === 0) {
939
- verts.push(Chalkboard.stat.lt(arr, bins[0], true));
940
- } else if(i === bins.length) {
941
- verts.push(Chalkboard.stat.gt(arr, bins[bins.length - 1], true));
942
- } else {
943
- verts.push(Chalkboard.stat.ineq(arr, bins[i - 1], bins[i], false, true));
944
- }
945
- }
946
- var counts = [];
947
- for(var i = 0; i < verts.length; i++) {
948
- counts.push(verts[i].length);
949
- }
950
- beginShape();
951
- for(var i = 0; i < counts.length; i++) {
952
- vertex(i / config.size, -counts[i] / config.size);
953
- }
954
- endShape();
955
- popMatrix();
956
- return verts;
957
- },
958
- scatterplot: function(arr1, arr2, config) {
959
- config = config || {};
960
- config = {
961
- size: config.size || 1,
962
- stroke: config.stroke || color(0),
963
- origin: config.origin || [width / 2, height / 2],
964
- strokeWeight: config.strokeWeight || 5
965
- };
966
- config.size /= 100;
967
- var data = [];
968
- pushMatrix();
969
- translate(config.origin[0], config.origin[1]);
970
- strokeWeight(config.strokeWeight);
971
- stroke(config.stroke);
972
- if(arr1.length === arr2.length) {
973
- for(var i = 0; i < arr1.length; i++) {
974
- point(arr1[i] / config.size - arr1.length / (2 * config.size), -arr2[i] / config.size + arr1.length / (2 * config.size));
975
- data.push([arr1[i], arr2[i]]);
976
- }
977
- }
978
- popMatrix();
979
- return data;
980
- },
981
- comp: function(comp, config) {
982
- config = config || {};
983
- config = {
984
- size: config.size || 1,
985
- stroke: config.stroke || color(0),
986
- origin: config.origin || [width / 2, height / 2],
987
- strokeWeight: config.strokeWeight || 5
988
- };
989
- config.size /= 100;
990
- stroke(config.stroke);
991
- strokeWeight(config.strokeWeight);
992
- pushMatrix();
993
- translate(config.origin[0], config.origin[1]);
994
- point(comp.a / config.size, -comp.b / config.size);
995
- popMatrix();
996
- noStroke();
997
- noFill();
998
- return [[comp.a], [comp.b]];
999
- },
1000
- vec2: function(vec2, config) {
1001
- config = config || {};
1002
- config = {
1003
- size: config.size || 1,
1004
- stroke: config.stroke || color(0),
1005
- origin: config.origin || [width / 2, height / 2],
1006
- strokeWeight: config.strokeWeight || 2
1007
- };
1008
- config.size /= 100;
1009
- stroke(config.stroke);
1010
- strokeWeight(config.strokeWeight);
1011
- pushMatrix();
1012
- translate(config.origin[0], config.origin[1]);
1013
- line(0, 0, vec2.x / config.size, -vec2.y / config.size);
1014
- popMatrix();
1015
- return [[vec2.x], [vec2.y]];
1016
- },
1017
- field: function(vec2field, config) {
1018
- config = config || {};
1019
- config = {
1020
- size: config.size || 1,
1021
- stroke: config.stroke || color(0),
1022
- domain: config.domain || [[-10, 10], [-10, 10]],
1023
- origin: config.origin || [width / 2, height / 2],
1024
- strokeWeight: config.strokeWeight || 2,
1025
- res: config.res || 25
1026
- };
1027
- config.size /= 100;
1028
- var data = [];
1029
- stroke(config.stroke);
1030
- strokeWeight(config.strokeWeight);
1031
- pushMatrix();
1032
- translate(config.origin[0], config.origin[1]);
1033
- for(var i = config.domain[0][0] / config.size; i <= config.domain[0][1] / config.size; i += config.res) {
1034
- for(var j = config.domain[1][0] / config.size; j <= config.domain[1][1] / config.size; j += config.res) {
1035
- var v = Chalkboard.vec2.fromField(vec2field, Chalkboard.vec2.new(i, j));
1036
- line(i, j, i + v.x, j + v.y);
1037
- data.push([i + v.x, j + v.y]);
1038
- }
1039
- }
1040
- popMatrix();
1041
- return data;
1042
- },
1043
- vec3: function(vec3, config) {
1044
- config = config || {};
1045
- config = {
1046
- size: config.size || 1,
1047
- stroke: config.stroke || color(0),
1048
- origin: config.origin || [width / 2, height / 2],
1049
- strokeWeight: config.strokeWeight || 2
1050
- };
1051
- config.size /= 100;
1052
- stroke(config.stroke);
1053
- strokeWeight(config.strokeWeight);
1054
- pushMatrix();
1055
- translate(config.origin[0], config.origin[1]);
1056
- line(0, 0, (vec3.x / config.size) / (vec3.z * 0.25 + 1), (-vec3.y / config.size) / (vec3.z * 0.25 + 1));
1057
- popMatrix();
1058
- return [[vec3.x], [vec3.y], [vec3.z]];
1059
- },
1060
- matr: function(matr, config) {
1061
- config = config || {};
1062
- config = {
1063
- size: config.size || 1,
1064
- stroke: config.stroke || color(0),
1065
- origin: config.origin || [width / 2, height / 2],
1066
- strokeWeight: config.strokeWeight || 2
1067
- };
1068
- config.size /= 100;
1069
- var plotposx = Chalkboard.vec2.new(matr[0][0], matr[1][0]);
1070
- var plotnegx = Chalkboard.vec2.new(-matr[0][0], -matr[1][0]);
1071
- var plotposy = Chalkboard.vec2.new(matr[0][1], matr[1][1]);
1072
- var plotnegy = Chalkboard.vec2.new(-matr[0][1], -matr[1][1]);
1073
- for(var i = -10; i <= 10; i++) {
1074
- Chalkboard.vec2.plot(plotposx, {origin: [config.origin[0], config.origin[1] + (i / config.size) * matr[1][1]], strokeWeight: config.strokeWeight / 4});
1075
- Chalkboard.vec2.plot(plotnegx, {origin: [config.origin[0], config.origin[1] + (i / config.size) * matr[1][1]], strokeWeight: config.strokeWeight / 4});
1076
- Chalkboard.vec2.plot(plotposy, {origin: [config.origin[0] + (i / config.size) * matr[0][0], config.origin[1]], strokeWeight: config.strokeWeight / 4});
1077
- Chalkboard.vec2.plot(plotnegy, {origin: [config.origin[0] + (i / config.size) * matr[0][0], config.origin[1]], strokeWeight: config.strokeWeight / 4});
1078
- }
1079
- var plotposaxisx = Chalkboard.vec2.new(matr[0][0], matr[1][0]);
1080
- var plotnegaxisx = Chalkboard.vec2.new(-matr[0][0], -matr[1][0]);
1081
- var plotposaxisy = Chalkboard.vec2.new(matr[0][1], matr[1][1]);
1082
- var plotnegaxisy = Chalkboard.vec2.new(-matr[0][1], -matr[1][1]);
1083
- Chalkboard.vec2.plot(plotposaxisx, config);
1084
- Chalkboard.vec2.plot(plotnegaxisx, config);
1085
- Chalkboard.vec2.plot(plotposaxisy, config);
1086
- Chalkboard.vec2.plot(plotnegaxisy, config);
1087
- return matr;
1088
- },
1089
- dfdx: function(func, config) {
1090
- config = config || {};
1091
- config = {
1092
- size: config.size || 1,
1093
- stroke: config.stroke || color(0),
1094
- domain: config.domain || [-10, 10],
1095
- origin: config.origin || [width / 2, height / 2],
1096
- strokeWeight: config.strokeWeight || 2,
1097
- res: config.res || 25
1098
- };
1099
- config.size /= 100;
1100
- var data = [];
1101
- pushMatrix();
1102
- translate(config.origin[0], config.origin[1]);
1103
- noFill();
1104
- strokeWeight(config.strokeWeight);
1105
- stroke(config.stroke);
1106
- beginShape();
1107
- for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i += config.res) {
1108
- if(func.type === "expl") {
1109
- vertex(i, -Chalkboard.calc.dfdx(func, i * config.size) / config.size);
1110
- data.push([i, Chalkboard.calc.dfdx(func, i)]);
1111
- } else if(func.type === "inve") {
1112
- vertex(Chalkboard.calc.dfdx(func, i * config.size) / config.size, -i);
1113
- data.push([Chalkboard.calc.dfdx(func, i), i]);
1114
- }
1115
- }
1116
- endShape();
1117
- popMatrix();
1118
- return data;
1119
- },
1120
- d2fdx2: function(func, config) {
1121
- config = config || {};
1122
- config = {
1123
- size: config.size || 1,
1124
- stroke: config.stroke || color(0),
1125
- domain: config.domain || [-10, 10],
1126
- origin: config.origin || [width / 2, height / 2],
1127
- strokeWeight: config.strokeWeight || 2,
1128
- res: config.res || 25
1129
- };
1130
- config.size /= 100;
1131
- var data = [];
1132
- pushMatrix();
1133
- translate(config.origin[0], config.origin[1]);
1134
- noFill();
1135
- strokeWeight(config.strokeWeight);
1136
- stroke(config.stroke);
1137
- beginShape();
1138
- for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i += config.res) {
1139
- if(func.type === "expl") {
1140
- vertex(i, -Chalkboard.calc.d2fdx2(func, i * config.size) / config.size);
1141
- data.push([i, Chalkboard.calc.d2fdx2(func, i)]);
1142
- } else if(func.type === "inve") {
1143
- vertex(Chalkboard.calc.d2fdx2(func, i * config.size) / config.size, -i);
1144
- data.push([Chalkboard.calc.d2fdx2(func, i), i]);
1145
- }
1146
- }
1147
- endShape();
1148
- popMatrix();
1149
- return data;
1150
- },
1151
- fxdx: function(func, config) {
1152
- config = config || {};
1153
- config = {
1154
- size: config.size || 1,
1155
- stroke: config.stroke || color(0),
1156
- domain: config.domain || [-10, 10],
1157
- origin: config.origin || [width / 2, height / 2],
1158
- strokeWeight: config.strokeWeight || 2,
1159
- res: config.res || 25
1160
- };
1161
- config.size /= 100;
1162
- var data = [];
1163
- pushMatrix();
1164
- translate(config.origin[0], config.origin[1]);
1165
- noFill();
1166
- strokeWeight(config.strokeWeight);
1167
- stroke(config.stroke);
1168
- beginShape();
1169
- for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i += config.res) {
1170
- if(func.type === "expl") {
1171
- vertex(i, -Chalkboard.calc.fxdx(func, 0, i * config.size) / config.size);
1172
- data.push([i, Chalkboard.calc.fxdx(func, 0, i)]);
1173
- } else if(func.type === "inve") {
1174
- vertex(Chalkboard.calc.fxdx(func, 0, i * config.size) / config.size, -i);
1175
- data.push([Chalkboard.calc.fxdx(func, 0, i), i]);
1176
- }
1177
- }
1178
- endShape();
1179
- popMatrix();
1180
- return data;
1181
- },
1182
- convolution: function(func_1, func_2, config) {
1183
- config = config || {};
1184
- config = {
1185
- size: config.size || 1,
1186
- stroke: config.stroke || color(0),
1187
- domain: config.domain || [-10, 10],
1188
- origin: config.origin || [width / 2, height / 2],
1189
- strokeWeight: config.strokeWeight || 2,
1190
- res: config.res || 25
1191
- };
1192
- config.size /= 100;
1193
- var data = [];
1194
- pushMatrix();
1195
- translate(config.origin[0], config.origin[1]);
1196
- noFill();
1197
- strokeWeight(config.strokeWeight);
1198
- stroke(config.stroke);
1199
- beginShape();
1200
- for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i += config.res) {
1201
- vertex(i, -Chalkboard.calc.convolution(func_1, func_2, i * config.size) / config.size);
1202
- data.push([i, Chalkboard.calc.convolution(func_1, func_2, i)]);
1203
- }
1204
- endShape();
1205
- popMatrix();
1206
- return data;
1207
- },
1208
- correlation: function(func_1, func_2, config) {
1209
- config = config || {};
1210
- config = {
1211
- size: config.size || 1,
1212
- stroke: config.stroke || color(0),
1213
- domain: config.domain || [-10, 10],
1214
- origin: config.origin || [width / 2, height / 2],
1215
- strokeWeight: config.strokeWeight || 2,
1216
- res: config.res || 25
1217
- };
1218
- config.size /= 100;
1219
- var data = [];
1220
- pushMatrix();
1221
- translate(config.origin[0], config.origin[1]);
1222
- noFill();
1223
- strokeWeight(config.strokeWeight);
1224
- stroke(config.stroke);
1225
- beginShape();
1226
- for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i += config.res) {
1227
- vertex(i, -Chalkboard.calc.correlation(func_1, func_2, i * config.size) / config.size);
1228
- data.push([i, Chalkboard.calc.correlation(func_1, func_2, i)]);
1229
- }
1230
- endShape();
1231
- popMatrix();
1232
- return data;
1233
- },
1234
- autocorrelation: function(func, config) {
1235
- config = config || {};
1236
- config = {
1237
- size: config.size || 1,
1238
- stroke: config.stroke || color(0),
1239
- domain: config.domain || [-10, 10],
1240
- origin: config.origin || [width / 2, height / 2],
1241
- strokeWeight: config.strokeWeight || 2,
1242
- res: config.res || 25
1243
- };
1244
- config.size /= 100;
1245
- var data = [];
1246
- pushMatrix();
1247
- translate(config.origin[0], config.origin[1]);
1248
- noFill();
1249
- strokeWeight(config.strokeWeight);
1250
- stroke(config.stroke);
1251
- beginShape();
1252
- for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i += config.res) {
1253
- vertex(i, -Chalkboard.calc.autocorrelation(func, i * config.size) / config.size);
1254
- data.push([i, Chalkboard.calc.autocorrelation(func, i)]);
1255
- }
1256
- endShape();
1257
- popMatrix();
1258
- return data;
1259
- },
1260
- Taylor: function(func, n, a, config) {
1261
- config = config || {};
1262
- config = {
1263
- size: config.size || 1,
1264
- stroke: config.stroke || color(0),
1265
- domain: config.domain || [-10, 10],
1266
- origin: config.origin || [width / 2, height / 2],
1267
- strokeWeight: config.strokeWeight || 2,
1268
- res: config.res || 25
1269
- };
1270
- config.size /= 100;
1271
- var data = [];
1272
- pushMatrix();
1273
- translate(config.origin[0], config.origin[1]);
1274
- noFill();
1275
- strokeWeight(config.strokeWeight);
1276
- stroke(config.stroke);
1277
- beginShape();
1278
- for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i += config.res) {
1279
- vertex(i, -Chalkboard.calc.Taylor(func, i * config.size, n, a) / config.size);
1280
- data.push([i, Chalkboard.calc.Taylor(func, i, n, a)]);
1281
- }
1282
- endShape();
1283
- popMatrix();
1284
- return data;
1285
- },
1286
- Laplace: function(func, config) {
1287
- config = config || {};
1288
- config = {
1289
- size: config.size || 1,
1290
- stroke: config.stroke || color(0),
1291
- domain: config.domain || [-10, 10],
1292
- origin: config.origin || [width / 2, height / 2],
1293
- strokeWeight: config.strokeWeight || 2,
1294
- res: config.res || 25
1295
- };
1296
- config.size /= 100;
1297
- var data = [];
1298
- pushMatrix();
1299
- translate(config.origin[0], config.origin[1]);
1300
- noFill();
1301
- strokeWeight(config.strokeWeight);
1302
- stroke(config.stroke);
1303
- beginShape();
1304
- if(config.domain[0] >= 0) {
1305
- for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i += config.res) {
1306
- vertex(i, -Chalkboard.calc.Laplace(func, i * config.size) / config.size);
1307
- data.push([i, Chalkboard.calc.Laplace(func, i)]);
1308
- }
1309
- } else {
1310
- for(var i = 0; i <= config.domain[1] / config.size; i += config.res) {
1311
- vertex(i, -Chalkboard.calc.Laplace(func, i * config.size) / config.size);
1312
- data.push([i, Chalkboard.calc.Laplace(func, i)]);
1313
- }
1314
- }
1315
- endShape();
1316
- popMatrix();
1317
- return data;
1318
- },
1319
- Fourier: function(func, config) {
1320
- config = config || {};
1321
- config = {
1322
- size: config.size || 1,
1323
- stroke: config.stroke || color(0),
1324
- domain: config.domain || [-10, 10],
1325
- origin: config.origin || [width / 2, height / 2],
1326
- strokeWeight: config.strokeWeight || 2,
1327
- res: config.res || 25
1328
- };
1329
- config.size /= 100;
1330
- var data = [];
1331
- pushMatrix();
1332
- translate(config.origin[0], config.origin[1]);
1333
- noFill();
1334
- strokeWeight(config.strokeWeight);
1335
- stroke(config.stroke);
1336
- beginShape();
1337
- for(var i = config.domain[0] / config.size; i <= config.domain[1] / config.size; i += config.res) {
1338
- vertex(i, -Chalkboard.calc.Fourier(func, i * config.size) / config.size);
1339
- data.push([i, Chalkboard.calc.Fourier(func, i)]);
1340
- }
1341
- endShape();
1342
- popMatrix();
1343
- return data;
1344
- }
1345
- },
1346
- geom: {
1347
- EulerCharacteristic: function(v, e, f) {
1348
- return v - e + f;
1349
- },
1350
- Pythagorean: function(a, b, type) {
1351
- type = type || "hyp";
1352
- if(type === "hyp") {
1353
- return Math.sqrt((a * a) + (b * b));
1354
- } else if(type === "leg") {
1355
- return Math.sqrt((b * b) - (a * a));
1356
- } else {
1357
- return undefined;
1358
- }
1359
- },
1360
- PythagoreanTriple: function(inf, sup) {
1361
- var a = 2 * Math.round(Chalkboard.numb.random(inf, sup)) - 1,
1362
- b = ((a * a) / 2) - 0.5,
1363
- c = ((a * a) / 2) + 0.5;
1364
- return a + ", " + b + ", " + c;
1365
- },
1366
- dist: function(p1, p2) {
1367
- if(p1.length === p2.length) {
1368
- var result = 0;
1369
- for(var i = 0; i < p1.length; i++) {
1370
- result += (p1[i] - p2[i]) * (p1[i] - p2[i]);
1371
- }
1372
- return Chalkboard.real.sqrt(result);
1373
- } else {
1374
- return undefined;
1375
- }
1376
- },
1377
- distsq: function(p1, p2) {
1378
- if(p1.length === p2.length) {
1379
- var result = 0;
1380
- for(var i = 0; i < p1.length; i++) {
1381
- result += (p1[i] - p2[i]) * (p1[i] - p2[i]);
1382
- }
1383
- return result;
1384
- } else {
1385
- return undefined;
1386
- }
1387
- },
1388
- mid: function(p1, p2) {
1389
- if(p1.length === p2.length) {
1390
- var result = [];
1391
- for(var i = 0; i < p1.length; i++) {
1392
- result[i] = (p1[i] + p2[i]) / 2;
1393
- }
1394
- return result;
1395
- } else {
1396
- return undefined;
1397
- }
1398
- },
1399
- circleP: function(r) {
1400
- return 2 * Chalkboard.PI() * r;
1401
- },
1402
- circleA: function(r) {
1403
- return Chalkboard.PI() * r * r;
1404
- },
1405
- sectorP: function(r, rad) {
1406
- return r * rad;
1407
- },
1408
- sectorA: function(r, rad) {
1409
- return (r * r * rad) / 2;
1410
- },
1411
- ellipseP: function(a, b) {
1412
- var h = ((a - b) * (a - b)) / ((a + b) * (a + b));
1413
- return Chalkboard.PI() * (a + b) * (1 + (3 * h) / (10 + Math.sqrt(4 - 3 * h)));
1414
- },
1415
- ellipseA: function(a, b) {
1416
- return Chalkboard.PI() * a * b;
1417
- },
1418
- squareP: function(s) {
1419
- return 4 * s;
1420
- },
1421
- squareA: function(s) {
1422
- return s * s;
1423
- },
1424
- parallelogramP: function(l, w) {
1425
- return 2 * (l + w);
1426
- },
1427
- parallelogramA: function(l, w) {
1428
- return l * w;
1429
- },
1430
- triangleP: function(a, b, c) {
1431
- return a + b + c;
1432
- },
1433
- triangleA: function(b, h) {
1434
- return (b * h) / 2;
1435
- },
1436
- trianglesidesA: function(a, b, c) {
1437
- var s = (a + b + c) / 2;
1438
- return Chalkboard.real.sqrt(s * ((s - a) * (s - b) * (s - c)));
1439
- },
1440
- trapezoidP: function(a, b, c, d) {
1441
- return a + b + c + d;
1442
- },
1443
- trapezoidA: function(b1, b2, h) {
1444
- return ((b1 + b2) / 2) * h;
1445
- },
1446
- polygonP: function(n, s) {
1447
- return n * s;
1448
- },
1449
- polygonA: function(n, s, a) {
1450
- return (n * s * a) / 2;
1451
- },
1452
- sphereA: function(r) {
1453
- return 4 * Chalkboard.PI() * r * r;
1454
- },
1455
- sphereV: function(r) {
1456
- return (4 * Chalkboard.PI() * r * r * r) / 3;
1457
- },
1458
- cylinderA: function(r, h) {
1459
- return 2 * Chalkboard.PI() * r * r + 2 * Math.PI * r * h;
1460
- },
1461
- cylinderV: function(r, h) {
1462
- return Chalkboard.PI() * r * r * h;
1463
- },
1464
- coneA: function(r, h) {
1465
- return Chalkboard.PI() * r * (r + Math.sqrt(h * h + r * r));
1466
- },
1467
- coneV: function(r, h) {
1468
- return (Chalkboard.PI() * r * r * h) / 3;
1469
- },
1470
- cubeA: function(s) {
1471
- return 6 * s * s;
1472
- },
1473
- cubeV: function(s) {
1474
- return s * s * s;
1475
- },
1476
- rectangularprismA: function(l, w, h) {
1477
- return 2 * (l * h + l * h + w * h);
1478
- },
1479
- rectangularprismV: function(l, w, h) {
1480
- return l * w * h;
1481
- },
1482
- triangularprismA: function(a, b, c, h) {
1483
- var s = (a + b + c) / 2;
1484
- return 2 * Chalkboard.real.sqrt(s * ((s - a) * (s - b) * (s - c))) + h * (a + b + c);
1485
- },
1486
- triangularprismV: function(a, b, c, h) {
1487
- return h * (Chalkboard.real.sqrt(-(a * a * a * a) + 2 * (a * b) * (a * b) + 2 * (a * c) * (a * c) - (b * b * b * b) + 2 * (b * c) * (b * c) - (c * c * c * c))) / 4;
1488
- },
1489
- line3D: function(x1, y1, z1, x2, y2, z2) {
1490
- line(x1 / (z1 * 0.0025 + 1), y1 / (z1 * 0.0025 + 1), x2 / (z2 * 0.0025 + 1), y2 / (z2 * 0.0025 + 1));
1491
- }
1492
- },
1493
- trig: {
1494
- toRad: function(deg) {
1495
- return deg * (Chalkboard.PI() / 180);
1496
- },
1497
- toDeg: function(rad) {
1498
- return rad * (180 / Chalkboard.PI());
1499
- },
1500
- coterminal: function(rad) {
1501
- return rad % (2 * Chalkboard.PI());
1502
- },
1503
- sin: function(rad) {
1504
- rad = Chalkboard.trig.coterminal(rad);
1505
- return ((rad) - (Math.pow(rad, 3) / Chalkboard.numb.factorial(3)) + (Math.pow(rad, 5) / Chalkboard.numb.factorial(5)) - (Math.pow(rad, 7) / Chalkboard.numb.factorial(7)) + (Math.pow(rad, 9) / Chalkboard.numb.factorial(9)) - (Math.pow(rad, 11) / Chalkboard.numb.factorial(11)) + (Math.pow(rad, 13) / Chalkboard.numb.factorial(13)) - (Math.pow(rad, 15) / Chalkboard.numb.factorial(15)) + (Math.pow(rad, 17) / Chalkboard.numb.factorial(17)) - (Math.pow(rad, 19) / Chalkboard.numb.factorial(19)) + (Math.pow(rad, 21) / Chalkboard.numb.factorial(21)) - (Math.pow(rad, 23) / Chalkboard.numb.factorial(23)) + (Math.pow(rad, 25) / Chalkboard.numb.factorial(25)) - (Math.pow(rad, 27) / Chalkboard.numb.factorial(27)) + (Math.pow(rad, 29) / Chalkboard.numb.factorial(29)));
1506
- },
1507
- cos: function(rad) {
1508
- rad = Chalkboard.trig.coterminal(rad);
1509
- return ((1) - (Math.pow(rad, 2) / Chalkboard.numb.factorial(2)) + (Math.pow(rad, 4) / Chalkboard.numb.factorial(4)) - (Math.pow(rad, 6) / Chalkboard.numb.factorial(6)) + (Math.pow(rad, 8) / Chalkboard.numb.factorial(8)) - (Math.pow(rad, 10) / Chalkboard.numb.factorial(10)) + (Math.pow(rad, 12) / Chalkboard.numb.factorial(12)) - (Math.pow(rad, 14) / Chalkboard.numb.factorial(14)) + (Math.pow(rad, 16) / Chalkboard.numb.factorial(16)) - (Math.pow(rad, 18) / Chalkboard.numb.factorial(18)) + (Math.pow(rad, 20) / Chalkboard.numb.factorial(20)) - (Math.pow(rad, 22) / Chalkboard.numb.factorial(22)) + (Math.pow(rad, 24) / Chalkboard.numb.factorial(24)) - (Math.pow(rad, 26) / Chalkboard.numb.factorial(26)) + (Math.pow(rad, 28) / Chalkboard.numb.factorial(28)));
1510
- },
1511
- tan: function(rad) {
1512
- return Chalkboard.trig.sin(rad) / Chalkboard.trig.cos(rad);
1513
- },
1514
- csc: function(rad) {
1515
- return 1 / Chalkboard.trig.sin(rad);
1516
- },
1517
- sec: function(rad) {
1518
- return 1 / Chalkboard.trig.cos(rad);
1519
- },
1520
- cot: function(rad) {
1521
- return 1 / Chalkboard.trig.tan(rad);
1522
- },
1523
- sinh: function(rad) {
1524
- return (Math.pow(Chalkboard.E(), rad) - Math.pow(Chalkboard.E(), -rad)) / 2;
1525
- },
1526
- cosh: function(rad) {
1527
- return (Math.pow(Chalkboard.E(), rad) + Math.pow(Chalkboard.E(), -rad)) / 2;
1528
- },
1529
- tanh: function(rad) {
1530
- return Chalkboard.trig.sinh(rad) / Chalkboard.trig.cosh(rad);
1531
- },
1532
- csch: function(rad) {
1533
- return 1 / Chalkboard.trig.sinh(rad);
1534
- },
1535
- sech: function(rad) {
1536
- return 1 / Chalkboard.trig.cosh(rad);
1537
- },
1538
- coth: function(rad) {
1539
- return 1 / Chalkboard.trig.tanh(rad);
1540
- },
1541
- arcsin: function(rad) {
1542
- if(rad > -1 && rad < 1) {
1543
- return Chalkboard.calc.fxdx(Chalkboard.real.function("1 / (Math.sqrt(1 - x * x))"), 0, rad);
1544
- } else if(rad === 1) {
1545
- return Chalkboard.PI() / 2;
1546
- } else if(rad === -1) {
1547
- return -Chalkboard.PI() / 2;
1548
- } else {
1549
- return undefined;
1550
- }
1551
- },
1552
- arccos: function(rad) {
1553
- if(rad > -1 && rad < 1) {
1554
- return Chalkboard.calc.fxdx(Chalkboard.real.function("1 / (Math.sqrt(1 - x * x))"), rad, 1);
1555
- } else if(rad === 1) {
1556
- return 0;
1557
- } else if(rad === -1) {
1558
- return Chalkboard.PI();
1559
- } else {
1560
- return undefined;
1561
- }
1562
- },
1563
- arctan: function(rad) {
1564
- return Chalkboard.calc.fxdx(Chalkboard.real.function("1 / (1 + x * x)"), 0, rad);
1565
- },
1566
- arctan2: function(y, x) {
1567
- if(x === 0) {
1568
- if(y > 0) {
1569
- return Math.PI / 2;
1570
- } else if(y < 0) {
1571
- return -Math.PI / 2;
1572
- } else {
1573
- return 0;
1574
- }
1575
- } else {
1576
- if(x > 0 && y >= 0) {
1577
- return Math.atan(Math.abs(y / x));
1578
- } else if(x < 0 && y >= 0) {
1579
- return Math.PI - Math.atan(Math.abs(y / x));
1580
- } else if(x < 0 && y < 0) {
1581
- return -Math.PI + Math.atan(Math.abs(y / x));
1582
- } else {
1583
- return -Math.atan(Math.abs(y / x));
1584
- }
1585
- }
1586
- },
1587
- arccsc: function(rad) {
1588
- if(rad > 1) {
1589
- return Chalkboard.calc.fxdx(Chalkboard.real.function("1 / (x * Math.sqrt(x * x - 1))"), rad, 1000);
1590
- } else if(rad === 1) {
1591
- return Chalkboard.PI() / 2;
1592
- } else if(rad === -1) {
1593
- return -Chalkboard.PI() / 2;
1594
- } else if(rad < 1) {
1595
- return -Chalkboard.calc.fxdx(Chalkboard.real.function("1 / (x * Math.sqrt(x * x - 1))"), Math.abs(rad), 1000);
1596
- } else {
1597
- return undefined;
1598
- }
1599
- },
1600
- arcsec: function(rad) {
1601
- if(rad > 1) {
1602
- return Chalkboard.calc.fxdx(Chalkboard.real.function("1 / (x * Math.sqrt(x * x - 1))"), 1.000001, rad);
1603
- } else if(rad === 1) {
1604
- return 0;
1605
- } else if(rad === -1) {
1606
- return Chalkboard.PI();
1607
- } else {
1608
- return undefined;
1609
- }
1610
- },
1611
- arccot: function(rad) {
1612
- return Chalkboard.calc.fxdx(Chalkboard.real.function("1 / (1 + x * x)"), rad, 1000);
1613
- },
1614
- arcsinh: function(rad) {
1615
- return Math.log(rad + Math.sqrt(rad * rad + 1));
1616
- },
1617
- arccosh: function(rad) {
1618
- if(rad >= 1) {
1619
- return Math.log(rad + Math.sqrt(rad * rad - 1));
1620
- } else {
1621
- return undefined;
1622
- }
1623
- },
1624
- arctanh: function(rad) {
1625
- if(rad > -1 && rad < 1) {
1626
- return (Math.log((1 + rad) / (1 - rad))) / 2;
1627
- } else {
1628
- return undefined;
1629
- }
1630
- },
1631
- arccsch: function(rad) {
1632
- if(rad !== 0) {
1633
- return Math.log((1 / rad) + Math.sqrt((1 / (rad * rad)) + 1));
1634
- } else {
1635
- return undefined;
1636
- }
1637
- },
1638
- arcsech: function(rad) {
1639
- if(rad > 0 && rad <= 1) {
1640
- return Math.log((1 / rad) + Math.sqrt((1 / (rad * rad)) - 1));
1641
- } else {
1642
- return undefined;
1643
- }
1644
- },
1645
- arccoth: function(rad) {
1646
- if(rad < -1 || rad > 1) {
1647
- return (Math.log((rad + 1) / (rad - 1))) / 2;
1648
- } else {
1649
- return undefined;
1650
- }
1651
- }
1652
- },
1653
- stat: {
1654
- array: function(inf, sup, length) {
1655
- length = length || sup - inf + 1;
1656
- var result = [];
1657
- var step = (sup - inf) / (length - 1);
1658
- for(var i = 0; i < length; i++) {
1659
- result.push(inf + (step * i));
1660
- }
1661
- return result;
1662
- },
1663
- random: function(inf, sup, length) {
1664
- var result = [];
1665
- for(var i = 0; i < length; i++) {
1666
- result.push(Chalkboard.numb.random(inf, sup));
1667
- }
1668
- return result;
1669
- },
1670
- shuffle: function(arr) {
1671
- var index, temp, rindex;
1672
- for(index = arr.length - 1; index > 0; index--) {
1673
- rindex = Math.floor(Chalkboard.numb.random(0, index + 1));
1674
- temp = arr[index];
1675
- arr[index] = arr[rindex];
1676
- arr[rindex] = temp;
1677
- }
1678
- return arr;
1679
- },
1680
- norm: function(arr, type) {
1681
- type = type || "L2";
1682
- var result = 0;
1683
- if(type === "L0") {
1684
- for(var i = 0; i < arr.length; i++) {
1685
- if(arr[i] !== 0) {
1686
- result += 1;
1687
- }
1688
- }
1689
- return result;
1690
- } else if(type === "L1") {
1691
- for(var i = 0; i < arr.length; i++) {
1692
- result += Math.abs(arr[i]);
1693
- }
1694
- return result;
1695
- } else if(type === "L2") {
1696
- for(var i = 0; i < arr.length; i++) {
1697
- result += arr[i] * arr[i];
1698
- }
1699
- return Chalkboard.real.sqrt(result);
1700
- } else if(type === "LInfinity") {
1701
- return Math.abs(Chalkboard.stat.max(arr));
1702
- } else {
1703
- return "TypeError: Parameter \"type\" must be \"L0\", \"L1\", \"L2\", or \"LInfinity\".";
1704
- }
1705
- },
1706
- normsq: function(arr, type) {
1707
- type = type || "L2";
1708
- var result = 0;
1709
- if(type === "L0") {
1710
- for(var i = 0; i < arr.length; i++) {
1711
- if(arr[i] !== 0) {
1712
- result += 1;
1713
- }
1714
- }
1715
- return result * result;
1716
- } else if(type === "L1") {
1717
- for(var i = 0; i < arr.length; i++) {
1718
- result += Math.abs(arr[i]);
1719
- }
1720
- return result * result;
1721
- } else if(type === "L2") {
1722
- for(var i = 0; i < arr.length; i++) {
1723
- result += arr[i] * arr[i];
1724
- }
1725
- return result;
1726
- } else if(type === "LInfinity") {
1727
- return Math.abs(Chalkboard.stat.max(arr)) * Math.abs(Chalkboard.stat.max(arr));
1728
- } else {
1729
- return "TypeError: Parameter \"type\" must be \"L0\", \"L1\", \"L2\", or \"LInfinity\".";
1730
- }
1731
- },
1732
- normalize: function(arr, type) {
1733
- if(type === "L0" || type === "L1" || type === "L2" || type === "LInfinity") {
1734
- var result = [];
1735
- var norm = Chalkboard.stat.norm(arr, type);
1736
- for(var i = 0; i < arr.length; i++) {
1737
- result.push(arr[i] / norm);
1738
- }
1739
- return result;
1740
- } else {
1741
- return "TypeError: Parameter \"type\" must be \"L0\", \"L1\", \"L2\", or \"LInfinity\".";
1742
- }
1743
- },
1744
- constrain: function(arr, range) {
1745
- var result = [];
1746
- for(var i = 0; i < arr.length; i++) {
1747
- result.push(Chalkboard.numb.constrain(arr[i], range));
1748
- }
1749
- return result;
1750
- },
1751
- eq: function(arr, arrORnum) {
1752
- var result = [];
1753
- if(arrORnum.constructor === Array) {
1754
- if(arr.length === arrORnum.length) {
1755
- for(var i = 0; i < arr.length; i++) {
1756
- if(arr[i] === arrORnum[i]) {
1757
- result.push(arr[i]);
1758
- }
1759
- }
1760
- }
1761
- } else {
1762
- for(var i = 0; i < arr.length; i++) {
1763
- if(arr[i] === arrORnum) {
1764
- result.push(arr[i]);
1765
- }
1766
- }
1767
- }
1768
- return result;
1769
- },
1770
- ineq: function(arr, inf, sup, includeInf, includeSup) {
1771
- includeInf = includeInf || false;
1772
- includeSup = includeSup || false;
1773
- var result = [];
1774
- if(inf.constructor === Array && sup.constructor === Array) {
1775
- if(arr.length === inf.length && arr.length === sup.length) {
1776
- for(var i = 0; i < arr.length; i++) {
1777
- if(includeInf) {
1778
- if(includeSup) {
1779
- if(arr[i] >= inf[i] && arr[i] <= sup[i]) {
1780
- result.push(arr[i]);
1781
- }
1782
- } else {
1783
- if(arr[i] >= inf[i] && arr[i] < sup[i]) {
1784
- result.push(arr[i]);
1785
- }
1786
- }
1787
- } else {
1788
- if(includeSup) {
1789
- if(arr[i] > inf[i] && arr[i] <= sup[i]) {
1790
- result.push(arr[i]);
1791
- }
1792
- } else {
1793
- if(arr[i] > inf[i] && arr[i] < sup[i]) {
1794
- result.push(arr[i]);
1795
- }
1796
- }
1797
- }
1798
- }
1799
- }
1800
- } else {
1801
- for(var i = 0; i < arr.length; i++) {
1802
- if(includeInf) {
1803
- if(includeSup) {
1804
- if(arr[i] >= inf && arr[i] <= sup) {
1805
- result.push(arr[i]);
1806
- }
1807
- } else {
1808
- if(arr[i] >= inf && arr[i] < sup) {
1809
- result.push(arr[i]);
1810
- }
1811
- }
1812
- } else {
1813
- if(includeSup) {
1814
- if(arr[i] > inf && arr[i] <= sup) {
1815
- result.push(arr[i]);
1816
- }
1817
- } else {
1818
- if(arr[i] > inf && arr[i] < sup) {
1819
- result.push(arr[i]);
1820
- }
1821
- }
1822
- }
1823
- }
1824
- }
1825
- return result;
1826
- },
1827
- lt: function(arr, arrORnum, includeEnd) {
1828
- includeEnd = includeEnd || false;
1829
- var result = [];
1830
- if(arrORnum.constructor === Array) {
1831
- if(arr.length === arrORnum.length) {
1832
- for(var i = 0; i < arr.length; i++) {
1833
- if(includeEnd) {
1834
- if(arr[i] <= arrORnum[i]) {
1835
- result.push(arr[i]);
1836
- }
1837
- } else {
1838
- if(arr[i] < arrORnum[i]) {
1839
- result.push(arr[i]);
1840
- }
1841
- }
1842
- }
1843
- }
1844
- } else {
1845
- for(var i = 0; i < arr.length; i++) {
1846
- if(includeEnd) {
1847
- if(arr[i] <= arrORnum) {
1848
- result.push(arr[i]);
1849
- }
1850
- } else {
1851
- if(arr[i] < arrORnum) {
1852
- result.push(arr[i]);
1853
- }
1854
- }
1855
- }
1856
- }
1857
- return result;
1858
- },
1859
- gt: function(arr, arrORnum, includeEnd) {
1860
- includeEnd = includeEnd || false;
1861
- var result = [];
1862
- if(arrORnum.constructor === Array) {
1863
- if(arr.length === arrORnum.length) {
1864
- for(var i = 0; i < arr.length; i++) {
1865
- if(includeEnd) {
1866
- if(arr[i] >= arrORnum[i]) {
1867
- result.push(arr[i]);
1868
- }
1869
- } else {
1870
- if(arr[i] > arrORnum[i]) {
1871
- result.push(arr[i]);
1872
- }
1873
- }
1874
- }
1875
- }
1876
- } else {
1877
- for(var i = 0; i < arr.length; i++) {
1878
- if(includeEnd) {
1879
- if(arr[i] >= arrORnum) {
1880
- result.push(arr[i]);
1881
- }
1882
- } else {
1883
- if(arr[i] > arrORnum) {
1884
- result.push(arr[i]);
1885
- }
1886
- }
1887
- }
1888
- }
1889
- return result;
1890
- },
1891
- subsets: function(arr) {
1892
- var result = [[]];
1893
- arr.sort();
1894
- for(var i = 0; i < arr.length; i++) {
1895
- if(i === 0 || arr[i] !== arr[i - 1]) {
1896
- var curr = arr[i];
1897
- var subsetsWithCurr = [];
1898
- for(var j = 0; j < result.length; j++) {
1899
- var subset = result[j].slice();
1900
- subset.push(curr);
1901
- subsetsWithCurr.push(subset);
1902
- }
1903
- result = result.concat(subsetsWithCurr);
1904
- }
1905
- }
1906
- return result;
1907
- },
1908
- max: function(arr) {
1909
- var max = arr[0];
1910
- for(var i = 0; i < arr.length; i++) {
1911
- if(arr[i] > max) {
1912
- max = arr[i];
1913
- }
1914
- }
1915
- return max;
1916
- },
1917
- min: function(arr) {
1918
- var min = arr[0];
1919
- for(var i = 0; i < arr.length; i++) {
1920
- if(arr[i] < min) {
1921
- min = arr[i];
1922
- }
1923
- }
1924
- return min;
1925
- },
1926
- range: function(arr) {
1927
- return Chalkboard.stat.max(arr) - Chalkboard.stat.min(arr);
1928
- },
1929
- mean: function(arr, type) {
1930
- type = type || "arithmetic";
1931
- var result = 0;
1932
- if(type === "arithmetic") {
1933
- for(var i = 0; i < arr.length; i++) {
1934
- result += arr[i];
1935
- }
1936
- return result / arr.length;
1937
- } else if(type === "geometric") {
1938
- for(var i = 0; i < arr.length; i++) {
1939
- result *= arr[i];
1940
- }
1941
- return Chalkboard.real.root(Math.abs(result), arr.length);
1942
- } else if(type === "harmonic") {
1943
- for(var i = 0; i < arr.length; i++) {
1944
- result += 1 / arr[i];
1945
- }
1946
- return arr.length / result;
1947
- } else {
1948
- return "TypeError: Parameter \"type\" must be \"arithmetic\", \"geometric\", or \"harmonic\".";
1949
- }
1950
- },
1951
- median: function(arr) {
1952
- var temp = arr.slice().sort(function(a, b) {
1953
- return a - b;
1954
- });
1955
- if(temp.length % 2 === 1) {
1956
- return temp[Math.floor(temp.length / 2)];
1957
- } else {
1958
- return (temp[temp.length / 2] + temp[(temp.length / 2) - 1]) / 2;
1959
- }
1960
- },
1961
- mode: function(arr) {
1962
- var temp = arr.slice().sort(function(a, b) {
1963
- return a - b;
1964
- });
1965
- var bestStr = 1;
1966
- var currStr = 1;
1967
- var bestElm = temp[0];
1968
- var currElm = temp[0];
1969
- for(var i = 1; i < temp.length; i++) {
1970
- if(temp[i - 1] !== temp[i]) {
1971
- if(currStr > bestStr) {
1972
- bestStr = currStr;
1973
- bestElm = currElm;
1974
- }
1975
- currStr = 0;
1976
- currElm = temp[i];
1977
- }
1978
- currStr++;
1979
- }
1980
- if(currStr > bestStr) {
1981
- return currElm;
1982
- } else {
1983
- return bestElm;
1984
- }
1985
- },
1986
- deviation: function(arr) {
1987
- var result = 0;
1988
- for(var i = 0; i < arr.length; i++) {
1989
- result += (arr[i] - Chalkboard.stat.mean(arr)) * (arr[i] - Chalkboard.stat.mean(arr));
1990
- }
1991
- return Chalkboard.real.sqrt(result / arr.length);
1992
- },
1993
- variance: function(arr) {
1994
- var result = 0;
1995
- for(var i = 0; i < arr.length; i++) {
1996
- result += (arr[i] - Chalkboard.stat.mean(arr)) * (arr[i] - Chalkboard.stat.mean(arr));
1997
- }
1998
- return result / arr.length;
1999
- },
2000
- mad: function(arr) {
2001
- var result = 0;
2002
- for(var i = 0; i < arr.length; i++) {
2003
- result += Math.abs(arr[i] - Chalkboard.stat.mean(arr));
2004
- }
2005
- return result / arr.length;
2006
- },
2007
- error: function(arr) {
2008
- return Chalkboard.stat.deviation(arr) / Chalkboard.real.sqrt(arr.length);
2009
- },
2010
- skewness: function(arr) {
2011
- var result = 0;
2012
- var mean = Chalkboard.stat.mean(arr);
2013
- var deviation = Chalkboard.stat.deviation(arr);
2014
- for(var i = 0; i < arr.length; i++) {
2015
- result += (arr[i] - mean) * (arr[i] - mean) * (arr[i] - mean);
2016
- }
2017
- return result / ((arr.length - 1) * (deviation * deviation * deviation));
2018
- },
2019
- kurtosis: function(arr) {
2020
- var result = 0;
2021
- var mean = Chalkboard.stat.mean(arr);
2022
- var deviation = Chalkboard.stat.deviation(arr);
2023
- for(var i = 0; i < arr.length; i++) {
2024
- result += (arr[i] - mean) * (arr[i] - mean) * (arr[i] - mean) * (arr[i] - mean);
2025
- }
2026
- return result / (deviation * deviation * deviation * deviation) - 3;
2027
- },
2028
- confidenceInterval: function(arr) {
2029
- return [Chalkboard.stat.mean(arr) - 1.96 * (Chalkboard.stat.deviation(arr) / Chalkboard.real.sqrt(arr.length)), Chalkboard.stat.mean(arr) + 1.96 * (Chalkboard.stat.deviation(arr) / Chalkboard.real.sqrt(arr.length))];
2030
- },
2031
- percentile: function(arr, num) {
2032
- var result = 0;
2033
- for(var i = 0; i < arr.length; i++) {
2034
- if(num >= arr[i]) {
2035
- result++;
2036
- }
2037
- }
2038
- return (result / arr.length) * 100;
2039
- },
2040
- quartile: function(arr, type) {
2041
- var temp = arr.slice().sort(function(a, b) {
2042
- return a - b;
2043
- });
2044
- var lo = temp.slice(0, Math.floor(temp.length / 2));
2045
- var hi = temp.slice(Math.ceil(temp.length / 2));
2046
- if(type === "Q1") {
2047
- return Chalkboard.stat.median(lo);
2048
- } else if(type === "Q2") {
2049
- return Chalkboard.stat.median(arr);
2050
- } else if(type === "Q3") {
2051
- return Chalkboard.stat.median(hi);
2052
- } else {
2053
- return "TypeError: Parameter \"type\" must be either \"Q1\", \"Q2\", or \"Q3\".";
2054
- }
2055
- },
2056
- convolution: function(arr1, arr2) {
2057
- var result = [];
2058
- for(var i = 0; i < arr1.length + arr2.length - 1; i++) {
2059
- var sum = 0;
2060
- for(var j = Math.max(0, i - arr2.length + 1); j < Math.min(arr1.length, i + 1); j++) {
2061
- sum += arr1[j] * arr2[i - j];
2062
- }
2063
- result.push(sum);
2064
- }
2065
- return result;
2066
- },
2067
- correlation: function(arr1, arr2) {
2068
- var result = [];
2069
- for(var i = 0; i < arr1.length + arr2.length - 1; i++) {
2070
- var sum = 0;
2071
- for(var j = Math.max(0, i - arr2.length + 1); j < Math.min(arr1.length, i + 1); j++) {
2072
- sum += arr1[j] * arr2[arr2.length - 1 - i + j];
2073
- }
2074
- result.push(sum);
2075
- }
2076
- return result;
2077
- },
2078
- autocorrelation: function(arr) {
2079
- return Chalkboard.stat.correlation(arr, arr);
2080
- },
2081
- change: function(initialArr, finalArr) {
2082
- var result = [];
2083
- if(initialArr.length === finalArr.length) {
2084
- for(var i = 0; i < initialArr.length; i++) {
2085
- result.push(Chalkboard.numb.change(initialArr[i], finalArr[i]));
2086
- }
2087
- return result;
2088
- } else {
2089
- return undefined;
2090
- }
2091
- },
2092
- chiSquared: function(observedArr, expectedArr) {
2093
- var result = [];
2094
- if(observedArr.length === expectedArr.length) {
2095
- for(var i = 0; i < observedArr.length; i++) {
2096
- result.push(((observedArr[i] - expectedArr[i]) * (observedArr[i] - expectedArr[i])) / expectedArr[i]);
2097
- }
2098
- return result;
2099
- } else {
2100
- return undefined;
2101
- }
2102
- },
2103
- Gaussian: function(height, mean, deviation) {
2104
- return Chalkboard.real.function(height.toString() + " * Math.exp(-((x - " + mean.toString() + ") * (x - " + mean.toString() + ")) / (2 * " + deviation.toString() + " * " + deviation.toString() + "))");
2105
- },
2106
- regression: function(data, type, degree) {
2107
- type = type || "linear";
2108
- degree = degree || 2;
2109
- if(type === "linear") {
2110
- var x = 0, y = 0;
2111
- var xx = 0, xy = 0;
2112
- for(var i = 0; i < data.length; i++) {
2113
- x += data[i][0];
2114
- y += data[i][1];
2115
- xx += data[i][0] * data[i][0];
2116
- xy += data[i][0] * data[i][1];
2117
- }
2118
- var a = (data.length * xy - x * y) / (data.length * xx - x * x),
2119
- b = (y / data.length) - (a * x) / data.length;
2120
- return Chalkboard.real.function(a + " * x + " + b);
2121
- } else if(type === "polynomial") {
2122
- var A = Chalkboard.matr.new();
2123
- for(var i = 0; i < data.length; i++) {
2124
- A.push([]);
2125
- for(var j = 0; j <= degree; j++) {
2126
- A[i].push(Chalkboard.real.pow(data[i][0], j));
2127
- }
2128
- }
2129
- var AT = Chalkboard.matr.transpose(A);
2130
- var B = Chalkboard.matr.new();
2131
- for(var i = 0; i < data.length; i++) {
2132
- B.push([data[i][1]]);
2133
- }
2134
- var ATA = Chalkboard.matr.mul(AT, A);
2135
- var ATAI = Chalkboard.matr.invert(ATA);
2136
- var x = Chalkboard.matr.mul(Chalkboard.matr.mul(ATAI, AT), B);
2137
- var coeff = [];
2138
- for(var i = 0; i < x.length; i++) {
2139
- coeff.push(x[i][0]);
2140
- }
2141
- var f = coeff[0].toString() + " + " + coeff[1].toString() + " * x";
2142
- for(var i = 2; i <= degree; i++) {
2143
- f += " + " + coeff[i].toString() + " * Math.pow(x, " + i + ")";
2144
- }
2145
- return Chalkboard.real.function(f);
2146
- } else if(type === "power") {
2147
- var arr = [0, 0, 0, 0];
2148
- for(var i = 0; i < data.length; i++) {
2149
- arr[0] += Chalkboard.real.ln(data[i][0]);
2150
- arr[1] += data[i][1] * Chalkboard.real.ln(data[i][0]);
2151
- arr[2] += data[i][1];
2152
- arr[3] += Chalkboard.real.ln(data[i][0]) * Chalkboard.real.ln(data[i][0]);
2153
- }
2154
- var a = Chalkboard.E((arr[2] - ((data.length * arr[1] - arr[2] * arr[0]) / (data.length * arr[3] - arr[0] * arr[0])) * arr[0]) / data.length),
2155
- b = (data.length * arr[1] - arr[2] * arr[0]) / (data.length * arr[3] - arr[0] * arr[0]);
2156
- return Chalkboard.real.function(a + " * Math.pow(x, " + b + ")");
2157
- } else if(type === "exponential") {
2158
- var arr = [0, 0, 0, 0, 0, 0];
2159
- for(var i = 0; i < data.length; i++) {
2160
- arr[0] += data[i][0];
2161
- arr[1] += data[i][1];
2162
- arr[2] += data[i][0] * data[i][0] * data[i][1];
2163
- arr[3] += data[i][1] * Chalkboard.real.ln(data[i][1]);
2164
- arr[4] += data[i][0] & data[i][1] * Chalkboard.real.ln(data[i][1]);
2165
- arr[5] += data[i][0] * data[i][1];
2166
- }
2167
- var a = Chalkboard.E((arr[2] * arr[3] - arr[5] * arr[4]) / (arr[1] * arr[2] - arr[5] * arr[5])),
2168
- b = (arr[1] * arr[4] - arr[5] * arr[3]) / (arr[1] * arr[2] - arr[5] * arr[5]);
2169
- return Chalkboard.real.function(a + "* Math.exp(" + b + " * x)");
2170
- } else if(type === "logarithmic") {
2171
- var arr = [0, 0, 0, 0];
2172
- for(var i = 0; i < data.length; i++) {
2173
- arr[0] += Chalkboard.real.ln(data[i][0]);
2174
- arr[1] += data[i][1] * Chalkboard.real.ln(data[i][0]);
2175
- arr[2] += data[i][1];
2176
- arr[3] += Chalkboard.real.ln(data[i][0]) * Chalkboard.real.ln(data[i][0]);
2177
- }
2178
- var a = (arr[2] - ((data.length * arr[1] - arr[2] * arr[0]) / (data.length * arr[3] - arr[0] * arr[0])) * arr[0]) / data.length,
2179
- b = (data.length * arr[1] - arr[2] * arr[0]) / (data.length * arr[3] - arr[0] * arr[0]);
2180
- return Chalkboard.real.function(a + " + " + b + " * Math.log(x)");
2181
- } else {
2182
- return "TypeError: Parameter \"type\" must be either \"linear\", \"polynomial\", \"power\", \"exponential\", or \"logarithmic\".";
2183
- }
2184
- },
2185
- toVector: function(arr, type) {
2186
- if(type === "vec2") {
2187
- return Chalkboard.vec2.new(arr[0], arr[1]);
2188
- } else if(type === "vec3") {
2189
- return Chalkboard.vec3.new(arr[0], arr[1], arr[2]);
2190
- } else if(type === "vec4") {
2191
- return Chalkboard.vec4.new(arr[0], arr[1], arr[2], arr[3]);
2192
- } else {
2193
- return "TypeError: Parameter \"type\" should be \"vec2\", \"vec3\", or \"vec4\".";
2194
- }
2195
- },
2196
- toMatrix: function(arr, rows, cols) {
2197
- var result = Chalkboard.matr.new();
2198
- var index = 0;
2199
- for(var i = 0; i < rows; i++) {
2200
- result[i] = [];
2201
- for(var j = 0; j < cols; j++) {
2202
- if(index < arr.length) {
2203
- result[i].push(arr[index]);
2204
- } else {
2205
- result[i].push(0);
2206
- }
2207
- index++;
2208
- }
2209
- }
2210
- return result;
2211
- },
2212
- toObject: function(arr) {
2213
- var result = {};
2214
- for(var i = 0; i < arr.length; i++) {
2215
- result["_" + i] = arr[i];
2216
- }
2217
- return result;
2218
- },
2219
- toString: function(arr) {
2220
- return "[" + arr.join(", ") + "]";
2221
- },
2222
- print: function(arr) {
2223
- console.log(Chalkboard.stat.toString(arr));
2224
- }
2225
- },
2226
- vec2: {
2227
- new: function(x, y) {
2228
- if(y === undefined) {
2229
- return {x: x, y: x, type: "vec2"};
2230
- } else {
2231
- return {x: x, y: y, type: "vec2"};
2232
- }
2233
- },
2234
- random: function(inf, sup) {
2235
- return Chalkboard.vec2.new(Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup));
2236
- },
2237
- mag: function(vec2) {
2238
- return Chalkboard.real.sqrt((vec2.x * vec2.x) + (vec2.y * vec2.y));
2239
- },
2240
- magsq: function(vec2) {
2241
- return (vec2.x * vec2.x) + (vec2.y * vec2.y);
2242
- },
2243
- magset: function(vec2, num) {
2244
- return Chalkboard.vec2.scl(Chalkboard.vec2.normalize(vec2), num);
2245
- },
2246
- ang: function(vec2) {
2247
- return Chalkboard.trig.arctan2(vec2.y, vec2.x);
2248
- },
2249
- slope: function(vec2) {
2250
- return vec2.y / vec2.x;
2251
- },
2252
- azimuth: function(vec2) {
2253
- return Chalkboard.trig.arctan(vec2.x / vec2.y);
2254
- },
2255
- average: function(vec2) {
2256
- return (vec2.x + vec2.y) / 2;
2257
- },
2258
- normalize: function(vec2) {
2259
- return Chalkboard.vec2.new(vec2.x / Chalkboard.vec2.mag(vec2), vec2.y / Chalkboard.vec2.mag(vec2));
2260
- },
2261
- zero: function(vec2) {
2262
- return Chalkboard.vec2.new(vec2.x * 0, vec2.y * 0);
2263
- },
2264
- negate: function(vec2) {
2265
- return Chalkboard.vec2.new(-vec2.x, -vec2.y);
2266
- },
2267
- reciprocate: function(vec2) {
2268
- return Chalkboard.vec2.new(1 / vec2.x, 1 / vec2.y);
2269
- },
2270
- absolute: function(vec2) {
2271
- return Chalkboard.vec2.new(Math.abs(vec2.x), Math.abs(vec2.y));
2272
- },
2273
- round: function(vec2) {
2274
- return Chalkboard.vec2.new(Math.round(vec2.x), Math.round(vec2.y));
2275
- },
2276
- dist: function(vec2_1, vec2_2) {
2277
- return Chalkboard.real.sqrt(((vec2_2.x - vec2_1.x) * (vec2_2.x - vec2_1.x)) + ((vec2_2.y - vec2_1.y) * (vec2_2.y - vec2_1.y)));
2278
- },
2279
- distsq: function(vec2_1, vec2_2) {
2280
- return ((vec2_2.x - vec2_1.x) * (vec2_2.x - vec2_1.x)) + ((vec2_2.y - vec2_1.y) * (vec2_2.y - vec2_1.y));
2281
- },
2282
- angBtwn: function(vec2_1, vec2_2) {
2283
- return Math.acos((Chalkboard.vec2.dot(vec2_1, vec2_2)) / (Chalkboard.vec2.mag(vec2_1) * Chalkboard.vec2.mag(vec2_2)));
2284
- },
2285
- scl: function(vec2, num) {
2286
- return Chalkboard.vec2.new(vec2.x * num, vec2.y * num);
2287
- },
2288
- constrain: function(vec2, range) {
2289
- return Chalkboard.vec2.new(Chalkboard.numb.constrain(vec2.x, range), Chalkboard.numb.constrain(vec2.y, range));
2290
- },
2291
- add: function(vec2_1, vec2_2) {
2292
- return Chalkboard.vec2.new(vec2_1.x + vec2_2.x, vec2_1.y + vec2_2.y);
2293
- },
2294
- sub: function(vec2_1, vec2_2) {
2295
- return Chalkboard.vec2.new(vec2_1.x - vec2_2.x, vec2_1.y - vec2_2.y);
2296
- },
2297
- mid: function(vec2_1, vec2_2) {
2298
- return Chalkboard.vec2.new((vec2_1.x + vec2_2.x) / 2, (vec2_1.y + vec2_2.y) / 2);
2299
- },
2300
- dot: function(vec2_1, vec2_2) {
2301
- return (vec2_1.x * vec2_2.x) + (vec2_1.y * vec2_2.y);
2302
- },
2303
- cross: function(vec2_1, vec2_2) {
2304
- return Chalkboard.vec3.new(0, 0, (vec2_1.x * vec2_2.y) - (vec2_1.y * vec2_2.x));
2305
- },
2306
- proj: function(vec2_1, vec2_2) {
2307
- return Chalkboard.vec2.scl(vec2_2, Chalkboard.vec2.dot(vec2_1, vec2_2) / Chalkboard.vec2.dot(vec2_2, vec2_2));
2308
- },
2309
- oproj: function(vec2_1, vec2_2) {
2310
- return Chalkboard.vec2.sub(vec2_1, Chalkboard.vec2.proj(vec2_1, vec2_2));
2311
- },
2312
- reflect: function(vec2_1, vec2_2) {
2313
- return Chalkboard.vec2.sub(vec2_1, Chalkboard.vec2.scl(vec2_2, 2 * Chalkboard.vec2.dot(vec2_1, vec2_2)));
2314
- },
2315
- refract: function(vec2_1, vec2_2, refractiveIndex) {
2316
- if(refractiveIndex > 0) {
2317
- var perp = Chalkboard.vec2.scl(Chalkboard.vec2.sub(vec2_1, Chalkboard.vec2.scl(vec2_2, Chalkboard.vec2.dot(vec2_1, vec2_2))), refractiveIndex);
2318
- var parr = Chalkboard.vec2.scl(vec2_2, -Chalkboard.real.sqrt(1 - (refractiveIndex * refractiveIndex) * (1 - (Chalkboard.vec2.dot(vec2_1, vec2_2) * Chalkboard.vec2.dot(vec2_1, vec2_2)))));
2319
- return Chalkboard.vec2.add(perp, parr);
2320
- } else {
2321
- return undefined;
2322
- }
2323
- },
2324
- fromAngle: function(rad) {
2325
- return Chalkboard.vec2.new(Chalkboard.trig.cos(rad), Chalkboard.trig.sin(rad));
2326
- },
2327
- fromPolar: function(vec2) {
2328
- return Chalkboard.vec2.new(vec2.x * Chalkboard.trig.cos(vec2.y), vec2.x * Chalkboard.trig.sin(vec2.y));
2329
- },
2330
- fromBipolar: function(vec2) {
2331
- return Chalkboard.vec2.new((vec2.x * vec2.x - vec2.y * vec2.y) / 4, Chalkboard.real.sqrt(16 * vec2.x * vec2.x - (vec2.x * vec2.x - vec2.y * vec2.y + 4) * (vec2.x * vec2.x - vec2.y * vec2.y + 4)));
2332
- },
2333
- toPolar: function(vec2) {
2334
- return Chalkboard.vec2.new(Chalkboard.vec2.mag(vec2), Chalkboard.vec2.ang(vec2));
2335
- },
2336
- toBipolar: function(vec2) {
2337
- return Chalkboard.vec2.new((vec2.x + 1) * (vec2.x + 1) + (vec2.y * vec2.y), (vec2.x - 1) * (vec2.x - 1) + (vec2.y * vec2.y));
2338
- },
2339
- toMatrix: function(vec2, type) {
2340
- type = type || "col";
2341
- if(type === "col") {
2342
- return Chalkboard.matr.new([vec2.x], [vec2.y]);
2343
- } else if(type === "row") {
2344
- return Chalkboard.matr.new([vec2.x, vec2.y]);
2345
- } else {
2346
- return "TypeError: Parameter \"type\" should be \"row\" or \"col\".";
2347
- }
2348
- },
2349
- toComplex: function(vec2) {
2350
- return Chalkboard.comp.new(vec2.x, vec2.y);
2351
- },
2352
- toArray: function(vec2) {
2353
- return [vec2.x, vec2.y];
2354
- },
2355
- toString: function(vec2) {
2356
- return "(" + vec2.x.toString() + ", " + vec2.y.toString() + ")";
2357
- },
2358
- field: function(p, q) {
2359
- return {p: p, q: q, type: "vec2field"};
2360
- },
2361
- fromField: function(vec2field, vec2) {
2362
- var p = Chalkboard.real.parse("(x, y) => " + vec2field.p),
2363
- q = Chalkboard.real.parse("(x, y) => " + vec2field.q);
2364
- return Chalkboard.vec2.new(p(vec2.x, vec2.y), q(vec2.x, vec2.y));
2365
- },
2366
- print: function(vec2) {
2367
- console.log(Chalkboard.vec2.toString(vec2));
2368
- }
2369
- },
2370
- vec3: {
2371
- new: function(x, y, z) {
2372
- if(y === undefined && z === undefined) {
2373
- return {x: x, y: x, z: x, type: "vec3"};
2374
- } else {
2375
- return {x: x, y: y, z: z, type: "vec3"};
2376
- }
2377
- },
2378
- random: function(inf, sup) {
2379
- return Chalkboard.vec3.new(Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup));
2380
- },
2381
- mag: function(vec3) {
2382
- return Chalkboard.real.sqrt((vec3.x * vec3.x) + (vec3.y * vec3.y) + (vec3.z * vec3.z));
2383
- },
2384
- magsq: function(vec3) {
2385
- return (vec3.x * vec3.x) + (vec3.y * vec3.y) + (vec3.z * vec3.z);
2386
- },
2387
- magset: function(vec3, num) {
2388
- return Chalkboard.vec3.scl(Chalkboard.vec3.normalize(vec3), num);
2389
- },
2390
- ang: function(vec3) {
2391
- return [Math.acos(vec3.x / Chalkboard.vec3.mag(vec3)), Math.acos(vec3.y / Chalkboard.vec3.mag(vec3)), Math.acos(vec3.z / Chalkboard.vec3.mag(vec3))];
2392
- },
2393
- slope: function(vec3) {
2394
- return vec3.z / Chalkboard.real.sqrt((vec3.x * vec3.x) + (vec3.y * vec3.y));
2395
- },
2396
- azimuth: function(vec3) {
2397
- return Chalkboard.trig.arctan(vec3.x / vec3.y);
2398
- },
2399
- average: function(vec3) {
2400
- return (vec3.x + vec3.y + vec3.z) / 3;
2401
- },
2402
- normalize: function(vec3) {
2403
- return Chalkboard.vec3.new(vec3.x / Chalkboard.vec3.mag(vec3), vec3.y / Chalkboard.vec3.mag(vec3), vec3.z / Chalkboard.vec3.mag(vec3));
2404
- },
2405
- zero: function(vec3) {
2406
- return Chalkboard.vec3.new(vec3.x * 0, vec3.y * 0, vec3.z * 0);
2407
- },
2408
- negate: function(vec3) {
2409
- return Chalkboard.vec3.new(-vec3.x, -vec3.y, -vec3.z);
2410
- },
2411
- reciprocate: function(vec3) {
2412
- return Chalkboard.vec3.new(1 / vec3.x, 1 / vec3.y, 1 / vec3.z);
2413
- },
2414
- absolute: function(vec3) {
2415
- return Chalkboard.vec3.new(Math.abs(vec3.x), Math.abs(vec3.y), Math.abs(vec3.z));
2416
- },
2417
- round: function(vec3) {
2418
- return Chalkboard.vec3.new(Math.round(vec3.x), Math.round(vec3.y), Math.round(vec3.z));
2419
- },
2420
- dist: function(vec3_1, vec3_2) {
2421
- return Chalkboard.real.sqrt(((vec3_2.x - vec3_1.x) * (vec3_2.x - vec3_1.x)) + ((vec3_2.y - vec3_1.y) * (vec3_2.y - vec3_1.y)) + ((vec3_2.z - vec3_1.z) * (vec3_2.z - vec3_1.z)));
2422
- },
2423
- distsq: function(vec3_1, vec3_2) {
2424
- return ((vec3_2.x - vec3_1.x) * (vec3_2.x - vec3_1.x)) + ((vec3_2.y - vec3_1.y) * (vec3_2.y - vec3_1.y)) + ((vec3_2.z - vec3_1.z) * (vec3_2.z - vec3_1.z));
2425
- },
2426
- angBtwn: function(vec3_1, vec3_2) {
2427
- return Math.acos((Chalkboard.vec3.dot(vec3_1, vec3_2)) / (Chalkboard.vec3.mag(vec3_1) * Chalkboard.vec3.mag(vec3_2)));
2428
- },
2429
- scl: function(vec3, num) {
2430
- return Chalkboard.vec3.new(vec3.x * num, vec3.y * num, vec3.z * num);
2431
- },
2432
- constrain: function(vec3, range) {
2433
- return Chalkboard.vec3.new(Chalkboard.numb.constrain(vec3.x, range), Chalkboard.numb.constrain(vec3.y, range), Chalkboard.numb.constrain(vec3.z, range));
2434
- },
2435
- add: function(vec3_1, vec3_2) {
2436
- return Chalkboard.vec3.new(vec3_1.x + vec3_2.x, vec3_1.y + vec3_2.y, vec3_1.z + vec3_2.z);
2437
- },
2438
- sub: function(vec3_1, vec3_2) {
2439
- return Chalkboard.vec3.new(vec3_1.x - vec3_2.x, vec3_1.y - vec3_2.y, vec3_1.z - vec3_2.z);
2440
- },
2441
- mid: function(vec3_1, vec3_2) {
2442
- return Chalkboard.vec3.new((vec3_1.x + vec3_2.x) / 2, (vec3_1.y + vec3_2.y) / 2, (vec3_1.z + vec3_2.z) / 2);
2443
- },
2444
- dot: function(vec3_1, vec3_2) {
2445
- return (vec3_1.x * vec3_2.x) + (vec3_1.y * vec3_2.y) + (vec3_1.z * vec3_2.z);
2446
- },
2447
- cross: function(vec3_1, vec3_2) {
2448
- return Chalkboard.vec3.new((vec3_1.y * vec3_2.z) - (vec3_1.z * vec3_2.y), (vec3_1.z * vec3_2.x) - (vec3_1.x * vec3_2.z), (vec3_1.x * vec3_2.y) - (vec3_1.y * vec3_2.x));
2449
- },
2450
- scalarTriple: function(vec3_1, vec3_2, vec3_3) {
2451
- return Chalkboard.vec3.dot(vec3_1, Chalkboard.vec3.cross(vec3_2, vec3_3));
2452
- },
2453
- vectorTriple: function(vec3_1, vec3_2, vec3_3) {
2454
- return Chalkboard.vec3.cross(vec3_1, Chalkboard.vec3.cross(vec3_2, vec3_3));
2455
- },
2456
- proj: function(vec3_1, vec3_2) {
2457
- return Chalkboard.vec3.scl(vec3_2, Chalkboard.vec3.dot(vec3_1, vec3_2) / Chalkboard.vec3.dot(vec3_2, vec3_2));
2458
- },
2459
- oproj: function(vec3_1, vec3_2) {
2460
- return Chalkboard.vec3.sub(vec3_1, Chalkboard.vec3.proj(vec3_1, vec3_2));
2461
- },
2462
- reflect: function(vec3_1, vec3_2) {
2463
- return Chalkboard.vec3.sub(vec3_1, Chalkboard.vec3.scl(vec3_2, 2 * Chalkboard.vec3.dot(vec3_1, vec3_2)));
2464
- },
2465
- refract: function(vec3_1, vec3_2, refractiveIndex) {
2466
- if(refractiveIndex > 0) {
2467
- var perp = Chalkboard.vec3.scl(Chalkboard.vec3.sub(vec3_1, Chalkboard.vec3.scl(vec3_2, Chalkboard.vec3.dot(vec3_1, vec3_2))), refractiveIndex);
2468
- var parr = Chalkboard.vec3.scl(vec3_2, -Chalkboard.real.sqrt(1 - (refractiveIndex * refractiveIndex) * (1 - (Chalkboard.vec3.dot(vec3_1, vec3_2) * Chalkboard.vec3.dot(vec3_1, vec3_2)))));
2469
- return Chalkboard.vec3.add(perp, parr);
2470
- } else {
2471
- return undefined;
2472
- }
2473
- },
2474
- fromAngles: function(rad1, rad2) {
2475
- return Chalkboard.vec3.new(Chalkboard.trig.cos(rad1) * Chalkboard.trig.cos(rad2), Chalkboard.trig.sin(rad1) * Chalkboard.trig.cos(rad2), Chalkboard.trig.sin(rad2));
2476
- },
2477
- fromVector: function(vec2) {
2478
- return Chalkboard.vec3.new(vec2.x, vec2.y, 0);
2479
- },
2480
- fromCylindrical: function(vec3) {
2481
- return Chalkboard.vec3.new(vec3.x * Chalkboard.trig.cos(vec3.y), vec3.x * Chalkboard.trig.sin(vec3.y), vec3.z);
2482
- },
2483
- fromSpherical: function(vec3) {
2484
- return Chalkboard.vec3.new(vec3.x * Chalkboard.trig.sin(vec3.z) * Chalkboard.trig.cos(vec3.y), vec3.x * Chalkboard.trig.sin(vec3.z) * Chalkboard.trig.sin(vec3.y), vec3.x * Chalkboard.trig.cos(vec3.z));
2485
- },
2486
- toCylindrical: function(vec3) {
2487
- return Chalkboard.vec3.new(Chalkboard.vec2.mag(vec3), Chalkboard.vec2.ang(vec3), vec3.z);
2488
- },
2489
- toSpherical: function(vec3) {
2490
- return Chalkboard.vec3.new(Chalkboard.vec3.mag(vec3), Chalkboard.vec2.ang(vec3), Chalkboard.vec3.ang(vec3)[2]);
2491
- },
2492
- toMatrix: function(vec3, type) {
2493
- type = type || "col";
2494
- if(type === "col") {
2495
- return Chalkboard.matr.new([vec3.x], [vec3.y], [vec3.z]);
2496
- } else if(type === "row") {
2497
- return Chalkboard.matr.new([vec3.x, vec3.y, vec3.z]);
2498
- } else {
2499
- return "TypeError: Parameter \"type\" should be \"row\" or \"col\".";
2500
- }
2501
- },
2502
- toArray: function(vec3) {
2503
- return [vec3.x, vec3.y, vec3.z];
2504
- },
2505
- toString: function(vec3) {
2506
- return "(" + vec3.x.toString() + ", " + vec3.y.toString() + ", " + vec3.z.toString() + ")";
2507
- },
2508
- field: function(p, q, r) {
2509
- return {p: p, q: q, r: r, type: "vec3field"};
2510
- },
2511
- fromField: function(vec3field, vec3) {
2512
- var p = Chalkboard.real.parse("(x, y, z) => " + vec3field.p),
2513
- q = Chalkboard.real.parse("(x, y, z) => " + vec3field.q),
2514
- r = Chalkboard.real.parse("(x, y, z) => " + vec3field.r);
2515
- return Chalkboard.vec3.new(p(vec3.x, vec3.y, vec3.z), q(vec3.x, vec3.y, vec3.z), r(vec3.x, vec3.y, vec3.z));
2516
- },
2517
- print: function(vec3) {
2518
- console.log(Chalkboard.vec3.toString(vec3));
2519
- }
2520
- },
2521
- vec4: {
2522
- new: function(x, y, z, w) {
2523
- if(y === undefined && z === undefined && w === undefined) {
2524
- return {x: x, y: x, z: x, w: x, type: "vec4"};
2525
- } else {
2526
- return {x: x, y: y, z: z, w: w, type: "vec4"};
2527
- }
2528
- },
2529
- random: function(inf, sup) {
2530
- return Chalkboard.vec4.new(Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup), Chalkboard.numb.random(inf, sup));
2531
- },
2532
- mag: function(vec4) {
2533
- return Chalkboard.real.sqrt((vec4.x * vec4.x) + (vec4.y * vec4.y) + (vec4.z * vec4.z) + (vec4.w * vec4.w));
2534
- },
2535
- magsq: function(vec4) {
2536
- return (vec4.x * vec4.x) + (vec4.y * vec4.y) + (vec4.z * vec4.z) + (vec4.w * vec4.w);
2537
- },
2538
- magset: function(vec4, num) {
2539
- return Chalkboard.vec4.scl(Chalkboard.vec4.normalize(vec4), num);
2540
- },
2541
- ang: function(vec4) {
2542
- return [Math.acos(vec4.x / Chalkboard.vec4.mag(vec4)), Math.acos(vec4.y / Chalkboard.vec4.mag(vec4)), Math.acos(vec4.z / Chalkboard.vec4.mag(vec4)), Math.acos(vec4.w / Chalkboard.vec4.mag(vec4))];
2543
- },
2544
- slope: function(vec4) {
2545
- return vec4.w / Chalkboard.real.sqrt((vec4.x * vec4.x) + (vec4.y * vec4.y) + (vec4.z * vec4.z));
2546
- },
2547
- average: function(vec4) {
2548
- return (vec4.x + vec4.y + vec4.z + vec4.w) / 4;
2549
- },
2550
- normalize: function(vec4) {
2551
- return Chalkboard.vec4.new(vec4.x / Chalkboard.vec4.mag(vec4), vec4.y / Chalkboard.vec4.mag(vec4), vec4.z / Chalkboard.vec4.mag(vec4), vec4.w / Chalkboard.vec4.mag(vec4));
2552
- },
2553
- zero: function(vec4) {
2554
- return Chalkboard.vec4.new(vec4.x * 0, vec4.y * 0, vec4.z * 0, vec4.w * 0);
2555
- },
2556
- negate: function(vec4) {
2557
- return Chalkboard.vec4.new(-vec4.x, -vec4.y, -vec4.z, -vec4.w);
2558
- },
2559
- reciprocate: function(vec4) {
2560
- return Chalkboard.vec4.new(1 / vec4.x, 1 / vec4.y, 1 / vec4.z, 1 / vec4.w);
2561
- },
2562
- absolute: function(vec4) {
2563
- return Chalkboard.vec4.new(Math.abs(vec4.x), Math.abs(vec4.y), Math.abs(vec4.z), Math.abs(vec4.w));
2564
- },
2565
- round: function(vec4) {
2566
- return Chalkboard.vec4.new(Math.round(vec4.x), Math.round(vec4.y), Math.round(vec4.z), Math.round(vec4.w));
2567
- },
2568
- dist: function(vec4_1, vec4_2) {
2569
- return Chalkboard.real.sqrt(((vec4_2.x - vec4_1.x) * (vec4_2.x - vec4_1.x)) + ((vec4_2.y - vec4_1.y) * (vec4_2.y - vec4_1.y)) + ((vec4_2.z - vec4_1.z) * (vec4_2.z - vec4_1.z)) + ((vec4_2.w - vec4_1.w) * (vec4_2.w - vec4_1.w)));
2570
- },
2571
- distsq: function(vec4_1, vec4_2) {
2572
- return ((vec4_2.x - vec4_1.x) * (vec4_2.x - vec4_1.x)) + ((vec4_2.y - vec4_1.y) * (vec4_2.y - vec4_1.y)) + ((vec4_2.z - vec4_1.z) * (vec4_2.z - vec4_1.z)) + ((vec4_2.w - vec4_1.w) * (vec4_2.w - vec4_1.w));
2573
- },
2574
- angBtwn: function(vec4_1, vec4_2) {
2575
- return Math.acos((Chalkboard.vec4.dot(vec4_1, vec4_2)) / (Chalkboard.vec4.mag(vec4_1) * Chalkboard.vec4.mag(vec4_2)));
2576
- },
2577
- scl: function(vec4, num) {
2578
- return Chalkboard.vec4.new(vec4.x * num, vec4.y * num, vec4.z * num, vec4.w * num);
2579
- },
2580
- constrain: function(vec4, range) {
2581
- return Chalkboard.vec4.new(Chalkboard.numb.constrain(vec4.x, range), Chalkboard.numb.constrain(vec4.y, range), Chalkboard.numb.constrain(vec4.z, range), Chalkboard.numb.constrain(vec4.w, range));
2582
- },
2583
- add: function(vec4_1, vec4_2) {
2584
- return Chalkboard.vec4.new(vec4_1.x + vec4_2.x, vec4_1.y + vec4_2.y, vec4_1.z + vec4_2.z, vec4_1.w + vec4_2.w);
2585
- },
2586
- sub: function(vec4_1, vec4_2) {
2587
- return Chalkboard.vec4.new(vec4_1.x - vec4_2.x, vec4_1.y - vec4_2.y, vec4_1.z - vec4_2.z, vec4_1.w - vec4_2.w);
2588
- },
2589
- mid: function(vec4_1, vec4_2) {
2590
- return Chalkboard.vec4.new((vec4_1.x + vec4_2.x) / 2, (vec4_1.y + vec4_2.y) / 2, (vec4_1.z + vec4_2.z) / 2, (vec4_1.w + vec4_2.w) / 2);
2591
- },
2592
- dot: function(vec4_1, vec4_2) {
2593
- return (vec4_1.x * vec4_2.x) + (vec4_1.y * vec4_2.y) + (vec4_1.z * vec4_2.z) + (vec4_1.w * vec4_2.w);
2594
- },
2595
- proj: function(vec4_1, vec4_2) {
2596
- return Chalkboard.vec4.scl(vec4_2, Chalkboard.vec4.dot(vec4_1, vec4_2) / Chalkboard.vec4.dot(vec4_2, vec4_2));
2597
- },
2598
- oproj: function(vec4_1, vec4_2) {
2599
- return Chalkboard.vec4.sub(vec4_1, Chalkboard.vec4.proj(vec4_1, vec4_2));
2600
- },
2601
- reflect: function(vec4_1, vec4_2) {
2602
- return Chalkboard.vec4.sub(vec4_1, Chalkboard.vec4.scl(vec4_2, 2 * Chalkboard.vec4.dot(vec4_1, vec4_2)));
2603
- },
2604
- refract: function(vec4_1, vec4_2, refractiveIndex) {
2605
- if(refractiveIndex > 0) {
2606
- var perp = Chalkboard.vec4.scl(Chalkboard.vec4.sub(vec4_1, Chalkboard.vec4.scl(vec4_2, Chalkboard.vec4.dot(vec4_1, vec4_2))), refractiveIndex);
2607
- var parr = Chalkboard.vec4.scl(vec4_2, -Chalkboard.real.sqrt(1 - (refractiveIndex * refractiveIndex) * (1 - (Chalkboard.vec4.dot(vec4_1, vec4_2) * Chalkboard.vec4.dot(vec4_1, vec4_2)))));
2608
- return Chalkboard.vec4.add(perp, parr);
2609
- } else {
2610
- return undefined;
2611
- }
2612
- },
2613
- fromVector: function(vec3) {
2614
- return Chalkboard.vec4.new(vec3.x, vec3.y, vec3.z, 0);
2615
- },
2616
- fromHypercylindrical: function(vec4) {
2617
- return Chalkboard.vec4.new(vec4.x * Chalkboard.trig.cos(vec4.y) * Chalkboard.trig.cos(vec4.z), vec4.x * Chalkboard.trig.cos(vec4.y) * Chalkboard.trig.sin(vec4.z), vec4.x * Chalkboard.trig.sin(vec4.y), vec4.w);
2618
- },
2619
- fromHyperspherical: function(vec4) {
2620
- return Chalkboard.vec4.new(vec4.x * Chalkboard.trig.cos(vec4.y) * Chalkboard.trig.cos(vec4.z) * Chalkboard.trig.cos(vec4.w), vec4.x * Chalkboard.trig.cos(vec4.y) * Chalkboard.trig.sin(vec4.z) * Chalkboard.trig.cos(vec4.w), vec4.x * Chalkboard.trig.sin(vec4.y) * Chalkboard.trig.cos(vec4.w), vec4.x * Chalkboard.trig.sin(vec4.w));
2621
- },
2622
- toHypercylindrical: function(vec4) {
2623
- return Chalkboard.vec4.new(Chalkboard.vec3.mag(vec4), Chalkboard.vec2.ang(vec4), Chalkboard.vec3.ang(vec4)[2], vec4.w);
2624
- },
2625
- toHyperspherical: function(vec4) {
2626
- return Chalkboard.vec4.new(Chalkboard.vec4.mag(vec4), Chalkboard.vec2.ang(vec4), Chalkboard.vec3.ang(vec4)[2], Chalkboard.vec4.ang(vec4)[3]);
2627
- },
2628
- toMatrix: function(vec4, type) {
2629
- type = type || "col";
2630
- if(type === "col") {
2631
- return Chalkboard.matr.new([vec4.x], [vec4.y], [vec4.z], [vec4.w]);
2632
- } else if(type === "row") {
2633
- return Chalkboard.matr.new([vec4.x, vec4.y, vec4.z, vec4.w]);
2634
- } else {
2635
- return "TypeError: Parameter \"type\" should be \"row\" or \"col\".";
2636
- }
2637
- },
2638
- toQuaternion: function(vec4) {
2639
- return Chalkboard.quat.new(vec4.x, vec4.y, vec4.z, vec4.w);
2640
- },
2641
- toArray: function(vec4) {
2642
- return [vec4.x, vec4.y, vec4.z, vec4.w];
2643
- },
2644
- toString: function(vec4) {
2645
- return "(" + vec4.x.toString() + ", " + vec4.y.toString() + ", " + vec4.z.toString() + ", " + vec4.w.toString() + ")";
2646
- },
2647
- field: function(p, q, r, s) {
2648
- return {p: p, q: q, r: r, s: s, type: "vec4field"};
2649
- },
2650
- fromField: function(vec4field, vec4) {
2651
- var p = Chalkboard.real.parse("(x, y, z, w) => " + vec4field.p),
2652
- q = Chalkboard.real.parse("(x, y, z, w) => " + vec4field.q),
2653
- r = Chalkboard.real.parse("(x, y, z, w) => " + vec4field.r),
2654
- s = Chalkboard.real.parse("(x, y, z, w) => " + vec4field.s);
2655
- return Chalkboard.vec4.new(p(vec4.x, vec4.y, vec4.z, vec4.w), q(vec4.x, vec4.y, vec4.z, vec4.w), r(vec4.x, vec4.y, vec4.z, vec4.w), s(vec4.x, vec4.y, vec4.z, vec4.w));
2656
- },
2657
- print: function(vec4) {
2658
- console.log(Chalkboard.vec4.toString(vec4));
2659
- }
2660
- },
2661
- matr: {
2662
- new: function(matrix) {
2663
- matrix = Array.from(arguments);
2664
- return matrix;
2665
- },
2666
- rows: function(matr) {
2667
- return matr.length;
2668
- },
2669
- cols: function(matr) {
2670
- return matr[0].length;
2671
- },
2672
- push: function(matr, type, rowORcol, elements) {
2673
- rowORcol -= 1;
2674
- if(type === "row") {
2675
- matr.splice(rowORcol, 0, elements);
2676
- return matr;
2677
- } else if(type === "col") {
2678
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
2679
- matr[i].splice(rowORcol, 0, elements[i]);
2680
- }
2681
- return matr;
2682
- } else {
2683
- return "TypeError: Parameter \"type\" must be either \"row\" or \"col\".";
2684
- }
2685
- },
2686
- pull: function(matr, type, rowORcol) {
2687
- rowORcol -= 1;
2688
- if(type === "row") {
2689
- matr.splice(rowORcol, 1);
2690
- return matr;
2691
- } else if(type === "col") {
2692
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
2693
- matr[i].splice(rowORcol, 1);
2694
- }
2695
- return matr;
2696
- } else {
2697
- return "TypeError: Parameter \"type\" must be either \"row\" or \"col\".";
2698
- }
2699
- },
2700
- fill: function(element, rows, cols) {
2701
- if(Number.isInteger(rows) && Number.isInteger(cols) && rows > 0 && cols > 0) {
2702
- var result = Chalkboard.matr.new();
2703
- for(var i = 0; i < rows; i++) {
2704
- result.push([]);
2705
- for(var j = 0; j < cols; j++) {
2706
- result[i].push(element);
2707
- }
2708
- }
2709
- return result;
2710
- } else {
2711
- return undefined;
2712
- }
2713
- },
2714
- empty: function(rows, cols) {
2715
- if(Number.isInteger(rows) && Number.isInteger(cols) && rows > 0 && cols > 0) {
2716
- var result = Chalkboard.matr.new();
2717
- for(var i = 0; i < rows; i++) {
2718
- result.push([]);
2719
- for(var j = 0; j < cols; j++) {
2720
- result[i].push(null);
2721
- }
2722
- }
2723
- return result;
2724
- } else {
2725
- return undefined;
2726
- }
2727
- },
2728
- identity: function(size) {
2729
- if(Number.isInteger(size) && size > 0) {
2730
- var result = Chalkboard.matr.new();
2731
- for(var i = 0; i < size; i++) {
2732
- result.push(Array(size).fill(0));
2733
- result[i][i] = 1;
2734
- }
2735
- return result;
2736
- } else {
2737
- return undefined;
2738
- }
2739
- },
2740
- random: function(rows, cols, inf, sup) {
2741
- if(Number.isInteger(rows) && Number.isInteger(cols) && rows > 0 && cols > 0) {
2742
- var result = Chalkboard.matr.new();
2743
- for(var i = 0; i < rows; i++) {
2744
- result.push([]);
2745
- for(var j = 0; j < cols; j++) {
2746
- result[i].push(Chalkboard.numb.random(inf, sup));
2747
- }
2748
- }
2749
- return result;
2750
- } else {
2751
- return undefined;
2752
- }
2753
- },
2754
- cofactor: function(matr, row, col) {
2755
- return matr.slice(0, row - 1).concat(matr.slice(row)).map(function(row) {
2756
- return row.slice(0, col - 1).concat(row.slice(col));
2757
- });
2758
- },
2759
- adjugate: function(matr, row, col) {
2760
- return Chalkboard.matr.transpose(Chalkboard.matr.cofactor(matr, row, col));
2761
- },
2762
- det: function(matr) {
2763
- if(Chalkboard.matr.rows(matr) === Chalkboard.matr.cols(matr)) {
2764
- var result = 0;
2765
- if(Chalkboard.matr.rows(matr) === 1) {
2766
- return matr[0][0];
2767
- } else if(Chalkboard.matr.rows(matr) === 2) {
2768
- return (matr[0][0] * matr[1][1]) - (matr[0][1] * matr[1][0]);
2769
- } else {
2770
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
2771
- var cofactor = matr[0][i] * Chalkboard.matr.det(Chalkboard.matr.cofactor(matr, 1, i + 1));
2772
- result += i % 2 === 0 ? cofactor : -cofactor;
2773
- }
2774
- return result;
2775
- }
2776
- } else {
2777
- return undefined;
2778
- }
2779
- },
2780
- trace: function(matr) {
2781
- if(Chalkboard.matr.rows(matr) === Chalkboard.matr.cols(matr)) {
2782
- var result = 0;
2783
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
2784
- result += matr[i][i];
2785
- }
2786
- return result;
2787
- } else {
2788
- return undefined;
2789
- }
2790
- },
2791
- rank: function(matr) {
2792
- return Chalkboard.matr.reduce(matr).filter(function(row) {
2793
- return row.some(function(element) {
2794
- return element !== 0;
2795
- });
2796
- }).length;
2797
- },
2798
- rowspace: function(matr) {
2799
- return Chalkboard.matr.reduce(matr).filter(function(row) {
2800
- return row.some(function(element) {
2801
- return element !== 0;
2802
- });
2803
- });
2804
- },
2805
- colspace: function(matr) {
2806
- return Chalkboard.matr.transpose(Chalkboard.matr.rowspace(Chalkboard.matr.transpose(matr)));
2807
- },
2808
- nullspace: function(matr) {
2809
- var augmented = matr.map(function(row) {
2810
- return row.slice().concat(Array(Chalkboard.matr.rows(matr)).fill(0));
2811
- });
2812
- var reduced = Chalkboard.matr.reduce(augmented);
2813
- return reduced.filter(function(row) {
2814
- return row.slice(0, Chalkboard.matr.rows(matr)).every(function(element) {
2815
- return element === 0;
2816
- });
2817
- }).map(function(row) {
2818
- return row.slice(Chalkboard.matr.rows(matr));
2819
- });
2820
- },
2821
- transpose: function(matr) {
2822
- var result = Chalkboard.matr.new();
2823
- for(var i = 0; i < Chalkboard.matr.cols(matr); i++) {
2824
- result[i] = [];
2825
- for(var j = 0; j < Chalkboard.matr.rows(matr); j++) {
2826
- result[i][j] = matr[j][i];
2827
- }
2828
- }
2829
- return result;
2830
- },
2831
- invert: function(matr) {
2832
- if(Chalkboard.matr.rows(matr) === Chalkboard.matr.cols(matr)) {
2833
- var result = Chalkboard.matr.new();
2834
- var augmented = Chalkboard.matr.new();
2835
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
2836
- augmented.push(matr[i].concat(Array(Chalkboard.matr.rows(matr)).fill(0)));
2837
- augmented[i][Chalkboard.matr.cols(matr) + i] = 1;
2838
- }
2839
- for(var row = 0; row < Chalkboard.matr.rows(matr); row++) {
2840
- var diagonal = augmented[row][row];
2841
- if(diagonal === 0) {
2842
- var max = row;
2843
- for(var i = row + 1; i < Chalkboard.matr.rows(matr); i++) {
2844
- if(Math.abs(augmented[i][row]) > Math.abs(augmented[max][row])) {
2845
- max = i;
2846
- }
2847
- }
2848
- var temp = augmented[row];
2849
- augmented[row] = augmented[max];
2850
- augmented[max] = temp;
2851
- diagonal = augmented[row][row];
2852
- }
2853
- for(var col = 0; col < 2 * Chalkboard.matr.cols(matr); col++) {
2854
- augmented[row][col] /= diagonal;
2855
- }
2856
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
2857
- if(i !== row) {
2858
- var coeff = augmented[i][row];
2859
- for(var j = 0; j < 2 * Chalkboard.matr.cols(matr); j++) {
2860
- augmented[i][j] -= coeff * augmented[row][j];
2861
- }
2862
- }
2863
- }
2864
- }
2865
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
2866
- result.push(augmented[i].slice(Chalkboard.matr.cols(matr), 2 * Chalkboard.matr.cols(matr)));
2867
- }
2868
- return result;
2869
- } else {
2870
- return undefined;
2871
- }
2872
- },
2873
- LUdecomp: function(matr) {
2874
- if(Chalkboard.matr.rows(matr) === Chalkboard.matr.cols(matr)) {
2875
- var L = Chalkboard.matr.identity(Chalkboard.matr.rows(matr)),
2876
- U = Chalkboard.matr.zero(Chalkboard.matr.empty(Chalkboard.matr.rows(matr)));
2877
- for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
2878
- for(var i = 0; i <= j; i++) {
2879
- var sum = 0;
2880
- for(var k = 0; k < i; k++) {
2881
- sum += L[i][k] * U[k][j];
2882
- }
2883
- U[i][j] = matr[i][j] - sum;
2884
- }
2885
- for(var i = j + 1; i < Chalkboard.matr.rows(matr); i++) {
2886
- var sum = 0;
2887
- for(var k = 0; k < j; k++) {
2888
- sum += L[i][k] * U[k][j];
2889
- }
2890
- L[i][j] = (matr[i][j] - sum) / U[j][j];
2891
- }
2892
- }
2893
- return {L: L, U: U};
2894
- } else {
2895
- return undefined;
2896
- }
2897
- },
2898
- QRdecomp: function(matr) {
2899
- if(Chalkboard.matr.rows(matr) === Chalkboard.matr.cols(matr)) {
2900
- var Q = Chalkboard.matr.zero(Chalkboard.matr.empty(Chalkboard.matr.rows(matr))),
2901
- R = Chalkboard.matr.zero(Chalkboard.matr.empty(Chalkboard.matr.rows(matr)));
2902
- var dot = function(v1, v2) {
2903
- var result = 0;
2904
- for(var i = 0; i < v1.length; i++) {
2905
- result += v1[i] * v2[i];
2906
- }
2907
- return result;
2908
- }
2909
- var mag = function(v) {
2910
- var result = 0;
2911
- for(var i = 0; i < v.length; i++) {
2912
- result += v[i] * v[i];
2913
- }
2914
- return Math.sqrt(result);
2915
- }
2916
- for(var j = 0; j < Chalkboard.matr.rows(matr); j++) {
2917
- var v = matr.map(function(row) {
2918
- return row[j];
2919
- });
2920
- for(var i = 0; i < j; i++) {
2921
- var q = Q.map(function(row) {
2922
- return row[i];
2923
- });
2924
- var coeff = dot(v, q) / (mag(q) * mag(q));
2925
- v = v.map(function(e, index) {
2926
- return e - coeff * q[index];
2927
- });
2928
- }
2929
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
2930
- Q[i][j] = v[i] / mag(v);
2931
- }
2932
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
2933
- R[j][i] = i < j ? 0 : matr.map(function(row) {
2934
- return row[i];
2935
- }).reduce(function(a, v, index) {
2936
- return a + v * Q[index][j];
2937
- }, 0);
2938
- }
2939
- }
2940
- return {Q: Q, R: R};
2941
- } else {
2942
- return undefined;
2943
- }
2944
- },
2945
- zero: function(matr) {
2946
- var result = Chalkboard.matr.new();
2947
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
2948
- result[i] = [];
2949
- for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
2950
- result[i][j] = 0;
2951
- }
2952
- }
2953
- return result;
2954
- },
2955
- negate: function(matr) {
2956
- var result = Chalkboard.matr.new();
2957
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
2958
- result[i] = [];
2959
- for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
2960
- result[i][j] = -matr[i][j];
2961
- }
2962
- }
2963
- return result;
2964
- },
2965
- reciprocate: function(matr) {
2966
- var result = Chalkboard.matr.new();
2967
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
2968
- result[i] = [];
2969
- for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
2970
- result[i][j] = 1 / matr[i][j];
2971
- }
2972
- }
2973
- return result;
2974
- },
2975
- absolute: function(matr) {
2976
- var result = Chalkboard.matr.new();
2977
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
2978
- result[i] = [];
2979
- for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
2980
- result[i][j] = Math.abs(matr[i][j]);
2981
- }
2982
- }
2983
- return result;
2984
- },
2985
- round: function(matr) {
2986
- var result = Chalkboard.matr.new();
2987
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
2988
- result[i] = [];
2989
- for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
2990
- result[i][j] = Math.round(matr[i][j]);
2991
- }
2992
- }
2993
- return result;
2994
- },
2995
- scaler: function(vec) {
2996
- if(vec.type === "vec2") {
2997
- return Chalkboard.matr.new([vec.x, 0], [0, vec.y]);
2998
- } else if(vec.type === "vec3") {
2999
- return Chalkboard.matr.new([vec.x, 0, 0], [0, vec.y, 0], [0, 0, vec.z]);
3000
- } else if(vec.type === "vec4") {
3001
- return Chalkboard.matr.new([vec.x, 0, 0, 0], [0, vec.y, 0, 0], [0, 0, vec.z, 0], [0, 0, 0, vec.w]);
3002
- }
3003
- },
3004
- translator: function(vec) {
3005
- if(vec.type === "vec2") {
3006
- return Chalkboard.matr.new([1, 0, vec.x], [0, 1, vec.y], [0, 0, 1]);
3007
- } else if(vec.type === "vec3") {
3008
- return Chalkboard.matr.new([1, 0, 0, vec.x], [0, 1, 0, vec.y], [0, 0, 1, vec.z], [0, 0, 0, 1]);
3009
- } else if(vec.type === "vec4") {
3010
- return Chalkboard.matr.new([1, 0, 0, 0, vec.x], [0, 1, 0, 0, vec.y], [0, 0, 1, 0, vec.z], [0, 0, 0, 1, vec.w], [0, 0, 0, 0, 1]);
3011
- } else {
3012
- return "TypeError: Parameter \"vec\" should be \"vec2\", \"vec3\", or \"vec4\".";
3013
- }
3014
- },
3015
- rotator: function(radx, rady, radz) {
3016
- if(rady === undefined && radz === undefined) {
3017
- return Chalkboard.matr.new([Chalkboard.trig.cos(radx), -Chalkboard.trig.sin(radx)], [Chalkboard.trig.sin(radx), Chalkboard.trig.cos(radx)]);
3018
- } else {
3019
- var matr_x = Chalkboard.matr.new([1, 0, 0], [0, Chalkboard.trig.cos(radx), -Chalkboard.trig.sin(radx)], [0, Chalkboard.trig.sin(radx), Chalkboard.trig.cos(radx)]),
3020
- matr_y = Chalkboard.matr.new([Chalkboard.trig.cos(rady), 0, Chalkboard.trig.sin(rady)], [0, 1, 0], [-Chalkboard.trig.sin(rady), 0, Chalkboard.trig.cos(rady)]),
3021
- matr_z = Chalkboard.matr.new([Chalkboard.trig.cos(radz), -Chalkboard.trig.sin(radz), 0], [Chalkboard.trig.sin(radz), Chalkboard.trig.cos(radz), 0], [0, 0, 1]);
3022
- return Chalkboard.matr.mul(matr_x, Chalkboard.matr.mul(matr_y, matr_z));
3023
- }
3024
- },
3025
- scl: function(matr, num) {
3026
- var result = Chalkboard.matr.new();
3027
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
3028
- result[i] = [];
3029
- for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
3030
- result[i][j] = matr[i][j] * num;
3031
- }
3032
- }
3033
- return result;
3034
- },
3035
- constrain: function(matr, range) {
3036
- var result = Chalkboard.matr.new();
3037
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
3038
- result[i] = [];
3039
- for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
3040
- result[i][j] = Chalkboard.numb.constrain(matr[i][j], range);
3041
- }
3042
- }
3043
- return result;
3044
- },
3045
- add: function(matr_1, matr_2) {
3046
- if(Chalkboard.matr.rows(matr_1) === Chalkboard.matr.rows(matr_2) && Chalkboard.matr.cols(matr_1) === Chalkboard.matr.cols(matr_2)) {
3047
- var result = Chalkboard.matr.new();
3048
- for(var i = 0; i < Chalkboard.matr.rows(matr_1); i++) {
3049
- result[i] = [];
3050
- for(var j = 0; j < Chalkboard.matr.cols(matr_1); j++) {
3051
- result[i][j] = matr_1[i][j] + matr_2[i][j];
3052
- }
3053
- }
3054
- return result;
3055
- } else {
3056
- return undefined;
3057
- }
3058
- },
3059
- sub: function(matr_1, matr_2) {
3060
- if(Chalkboard.matr.rows(matr_1) === Chalkboard.matr.rows(matr_2) && Chalkboard.matr.cols(matr_1) === Chalkboard.matr.cols(matr_2)) {
3061
- var result = Chalkboard.matr.new();
3062
- for(var i = 0; i < Chalkboard.matr.rows(matr_1); i++) {
3063
- result[i] = [];
3064
- for(var j = 0; j < Chalkboard.matr.cols(matr_1); j++) {
3065
- result[i][j] = matr_1[i][j] - matr_2[i][j];
3066
- }
3067
- }
3068
- return result;
3069
- } else {
3070
- return undefined;
3071
- }
3072
- },
3073
- mul: function(matr_1, matr_2) {
3074
- if(Chalkboard.matr.cols(matr_1) === Chalkboard.matr.rows(matr_2)) {
3075
- var result = Chalkboard.matr.new();
3076
- for(var i = 0; i < Chalkboard.matr.rows(matr_1); i++) {
3077
- result[i] = [];
3078
- for(var j = 0; j < Chalkboard.matr.cols(matr_2); j++) {
3079
- result[i][j] = 0;
3080
- for(var k = 0; k < Chalkboard.matr.cols(matr_1); k++) {
3081
- result[i][j] += matr_1[i][k] * matr_2[k][j];
3082
- }
3083
- }
3084
- }
3085
- return result;
3086
- } else {
3087
- return undefined;
3088
- }
3089
- },
3090
- pow: function(matr, num) {
3091
- if(Chalkboard.matr.rows(matr) === Chalkboard.matr.cols(matr)) {
3092
- if(Number.isInteger(num) && num >= 0) {
3093
- if(num === 0) {
3094
- return Chalkboard.matr.identity(Chalkboard.matr.rows(matr));
3095
- } else {
3096
- var result = matr;
3097
- for(var i = 1; i < num; i++) {
3098
- result = Chalkboard.matr.mul(matr, result);
3099
- }
3100
- return result;
3101
- }
3102
- } else {
3103
- return undefined;
3104
- }
3105
- } else {
3106
- return undefined;
3107
- }
3108
- },
3109
- reduce: function(matr) {
3110
- var lead = 0;
3111
- for(var row = 0; row < Chalkboard.matr.rows(matr); row++) {
3112
- if(lead >= Chalkboard.matr.cols(matr)) {
3113
- break;
3114
- }
3115
- var i = row;
3116
- while(matr[i][lead] === 0) {
3117
- i++;
3118
- if(i === Chalkboard.matr.rows(matr)) {
3119
- i = row;
3120
- lead++;
3121
- if(Chalkboard.matr.cols(matr) === lead) {
3122
- return matr;
3123
- }
3124
- }
3125
- }
3126
- var temp = matr[i];
3127
- matr[i] = matr[row];
3128
- matr[row] = temp;
3129
- var scl = matr[row][lead];
3130
- for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
3131
- matr[row][j] /= scl;
3132
- }
3133
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
3134
- if(i !== row) {
3135
- var coeff = matr[i][lead];
3136
- for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
3137
- matr[i][j] -= coeff * matr[row][j];
3138
- }
3139
- }
3140
- }
3141
- lead++;
3142
- }
3143
- return matr;
3144
- },
3145
- solve: function(matr_A, matr_B) {
3146
- if(Chalkboard.matr.rows(matr_A) === Chalkboard.matr.cols(matr_A)) {
3147
- if(Chalkboard.matr.rows(matr_A) === Chalkboard.matr.rows(matr_B)) {
3148
- if(Chalkboard.matr.det(matr_A) !== 0) {
3149
- return Chalkboard.matr.mul(Chalkboard.matr.invert(matr_A), matr_B);
3150
- } else {
3151
- return undefined;
3152
- }
3153
- } else {
3154
- return undefined;
3155
- }
3156
- } else {
3157
- return undefined;
3158
- }
3159
- },
3160
- toVector: function(matr, vec, type, rowORcol) {
3161
- type = type || "col";
3162
- rowORcol = rowORcol || 1;
3163
- rowORcol -= 1;
3164
- if(vec === "vec2") {
3165
- if(type === "col") {
3166
- return Chalkboard.vec2.new(matr[0][rowORcol], matr[1][rowORcol]);
3167
- } else if(type === "row") {
3168
- return Chalkboard.vec2.new(matr[rowORcol][0], matr[rowORcol][1]);
3169
- } else {
3170
- return "TypeError: Parameter \"type\" should be \"row\" or \"col\".";
3171
- }
3172
- } else if(vec === "vec3") {
3173
- if(type === "col") {
3174
- return Chalkboard.vec3.new(matr[0][rowORcol], matr[1][rowORcol], matr[2][rowORcol]);
3175
- } else if(type === "row") {
3176
- return Chalkboard.vec3.new(matr[rowORcol][0], matr[rowORcol][1], matr[rowORcol][2]);
3177
- } else {
3178
- return "TypeError: Parameter \"type\" should be \"row\" or \"col\".";
3179
- }
3180
- } else if(vec === "vec4") {
3181
- if(type === "col") {
3182
- return Chalkboard.vec4.new(matr[0][rowORcol], matr[1][rowORcol], matr[2][rowORcol], matr[3][rowORcol]);
3183
- } else if(type === "row") {
3184
- return Chalkboard.vec4.new(matr[rowORcol][0], matr[rowORcol][1], matr[rowORcol][2], matr[rowORcol][3]);
3185
- } else {
3186
- return "TypeError: Parameter \"type\" should be \"row\" or \"col\".";
3187
- }
3188
- } else {
3189
- return "TypeError: Parameter \"vec\" should be \"vec2\", \"vec3\", or \"vec4\".";
3190
- }
3191
- },
3192
- toArray: function(matr) {
3193
- var result = [];
3194
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
3195
- for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
3196
- result.push(matr[i][j]);
3197
- }
3198
- }
3199
- return result;
3200
- },
3201
- toString: function(matr) {
3202
- var result = "";
3203
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
3204
- result += "[ ";
3205
- for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
3206
- result += matr[i][j].toString() + " ";
3207
- }
3208
- result = result.trimEnd() + " ]\n";
3209
- }
3210
- return result;
3211
- },
3212
- toObject: function(matr) {
3213
- var result = {};
3214
- for(var i = 0; i < Chalkboard.matr.rows(matr); i++) {
3215
- result["i" + (i + 1)] = {};
3216
- for(var j = 0; j < Chalkboard.matr.cols(matr); j++) {
3217
- result["i" + (i + 1)]["j" + (j + 1)] = matr[i][j];
3218
- }
3219
- }
3220
- return result;
3221
- },
3222
- print: function(matr) {
3223
- console.log(Chalkboard.matr.toString(matr));
3224
- }
3225
- },
3226
- calc: {
3227
- lim: function(func, val) {
3228
- if(func.type === "expl") {
3229
- if(val === Infinity) {
3230
- if(Chalkboard.real.val(func, 101) > Chalkboard.real.val(func, 100)) {
3231
- return Infinity;
3232
- } else if(Chalkboard.real.val(func, 101) < Chalkboard.real.val(func, 100)) {
3233
- return -Infinity;
3234
- }
3235
- } else if(val === -Infinity) {
3236
- if(Chalkboard.real.val(func, -101) > Chalkboard.real.val(func, -100)) {
3237
- return Infinity;
3238
- } else if(Chalkboard.real.val(func, -101) < Chalkboard.real.val(func, -100)) {
3239
- return -Infinity;
3240
- }
3241
- } else {
3242
- if(Chalkboard.real.val(func, val - 0.000001).toFixed(4) === Chalkboard.real.val(func, val + 0.000001).toFixed(4)) {
3243
- if(Chalkboard.real.val(func, val) !== Infinity || Chalkboard.real.val(func, val) !== -Infinity) {
3244
- return Chalkboard.real.val(func, val);
3245
- } else {
3246
- return undefined;
3247
- }
3248
- } else {
3249
- return undefined;
3250
- }
3251
- }
3252
- } else {
3253
- return "TypeError: Parameter \"func\" must be of type \"expl\".";
3254
- }
3255
- },
3256
- dfdx: function(func, val) {
3257
- var h = 0.000000001;
3258
- if(func.type === "expl") {
3259
- var f = Chalkboard.real.parse("x => " + func.definition);
3260
- return (f(val + h) - f(val)) / h;
3261
- } else if(func.type === "inve") {
3262
- var f = Chalkboard.real.parse("y => " + func.definition);
3263
- return (f(val + h) - f(val)) / h;
3264
- } else if(func.type === "pola") {
3265
- var r = Chalkboard.real.parse("O => " + func.definition);
3266
- return (r(val + h) - r(val)) / h;
3267
- } else if(func.type === "curv") {
3268
- if(func.definition.length === 2) {
3269
- var x = Chalkboard.real.parse("t => " + func.definition[0]),
3270
- y = Chalkboard.real.parse("t => " + func.definition[1]);
3271
- return Chalkboard.vec2.new((x(val + h) - x(val)) / h, (y(val + h) - y(val)) / h);
3272
- } else if(func.definition.length === 3) {
3273
- var x = Chalkboard.real.parse("t => " + func.definition[0]),
3274
- y = Chalkboard.real.parse("t => " + func.definition[1]),
3275
- z = Chalkboard.real.parse("t => " + func.definition[2]);
3276
- return Chalkboard.vec3.new((x(val + h) - x(val)) / h, (y(val + h) - y(val)) / h, (z(val + h) - z(val)) / h);
3277
- }
3278
- } else {
3279
- return "TypeError: Parameter \"func\" must be of type \"expl\", \"inve\", \"pola\", or \"curv\".";
3280
- }
3281
- },
3282
- d2fdx2: function(func, val) {
3283
- var h = 0.00001;
3284
- if(func.type === "expl") {
3285
- var f = Chalkboard.real.parse("x => " + func.definition);
3286
- return (f(val + h) - 2 * f(val) + f(val - h)) / (h * h);
3287
- } else if(func.type === "inve") {
3288
- var f = Chalkboard.real.parse("y => " + func.definition);
3289
- return (f(val + h) - 2 * f(val) + f(val - h)) / (h * h);
3290
- } else if(func.type === "pola") {
3291
- var r = Chalkboard.real.parse("O => " + func.definition);
3292
- return (r(val + h) - 2 * r(val) + r(val - h)) / (h * h);
3293
- } else if(func.type === "curv") {
3294
- if(func.definition.length === 2) {
3295
- var x = Chalkboard.real.parse("t => " + func.definition[0]),
3296
- y = Chalkboard.real.parse("t => " + func.definition[1]);
3297
- return Chalkboard.vec2.new((x(val + h) - 2 * x(val) + x(val - h)) / (h * h), (y(val + h) - 2 * y(val) + y(val - h)) / (h * h));
3298
- } else if(func.definition.length === 3) {
3299
- var x = Chalkboard.real.parse("t => " + func.definition[0]),
3300
- y = Chalkboard.real.parse("t => " + func.definition[1]),
3301
- z = Chalkboard.real.parse("t => " + func.definition[2]);
3302
- return Chalkboard.vec3.new((x(val + h) - 2 * x(val) + x(val - h)) / (h * h), (y(val + h) - 2 * y(val) + y(val - h)) / (h * h), (z(val + h) - 2 * z(val) + z(val - h)) / (h * h));
3303
- }
3304
- } else {
3305
- return "TypeError: Parameter \"func\" must be of type \"expl\", \"inve\", \"pola\", or \"curv\".";
3306
- }
3307
- },
3308
- tangent: function(func, val) {
3309
- if(func.type === "curv") {
3310
- if(func.definition.length === 2) {
3311
- return Chalkboard.vec2.normalize(Chalkboard.calc.dfdx(func, val));
3312
- } else if(func.definition.length === 3) {
3313
- return Chalkboard.vec3.normalize(Chalkboard.calc.dfdx(func, val));
3314
- }
3315
- } else {
3316
- return "TypeError: Parameter \"func\" must be of type \"curv\".";
3317
- }
3318
- },
3319
- normal: function(func, val) {
3320
- if(func.type === "curv") {
3321
- if(func.definition.length === 2) {
3322
- return Chalkboard.vec2.normalize(Chalkboard.calc.d2fdx2(func, val));
3323
- } else if(func.definition.length === 3) {
3324
- return Chalkboard.vec3.normalize(Chalkboard.calc.d2fdx2(func, val));
3325
- }
3326
- } else {
3327
- return "TypeError: Parameter \"func\" must be of type \"curv\".";
3328
- }
3329
- },
3330
- binormal: function(func, val) {
3331
- if(func.type === "curv") {
3332
- if(func.definition.length === 2) {
3333
- return Chalkboard.vec2.cross(Chalkboard.calc.tangent(func, val), Chalkboard.calc.normal(func, val));
3334
- } else if(func.definition.length === 3) {
3335
- return Chalkboard.vec3.cross(Chalkboard.calc.tangent(func, val), Chalkboard.calc.normal(func, val));
3336
- }
3337
- } else {
3338
- return "TypeError: Parameter \"func\" must be of type \"curv\".";
3339
- }
3340
- },
3341
- dfdv: function(func, vec2_pos, vec2_dir) {
3342
- if(func.type === "mult") {
3343
- return Chalkboard.vec2.dot(Chalkboard.calc.grad(func, vec2_pos), Chalkboard.vec2.normalize(vec2_dir));
3344
- } else {
3345
- return "TypeError: Parameter \"func\" must be of type \"mult\".";
3346
- }
3347
- },
3348
- dfrdt: function(func_1, func_2, val) {
3349
- if(func_1.type === "mult") {
3350
- if(func_2.type === "curv") {
3351
- if(func_2.definition.length === 2) {
3352
- var dfdx = Chalkboard.calc.grad(func_1, Chalkboard.real.val(func_2, val)).x,
3353
- dfdy = Chalkboard.calc.grad(func_1, Chalkboard.real.val(func_2, val)).y,
3354
- dxdt = Chalkboard.calc.dfdx(func_2, val).x,
3355
- dydt = Chalkboard.calc.dfdx(func_2, val).y;
3356
- return dfdx * dxdt + dfdy * dydt;
3357
- }
3358
- } else {
3359
- return "TypeError: Parameter \"func_2\" must be of type \"curv\".";
3360
- }
3361
- } else {
3362
- return "TypeError: Parameter \"func_1\" must be of type \"mult\".";
3363
- }
3364
- },
3365
- grad: function(funcORvecfield, vec) {
3366
- var h = 0.000000001;
3367
- if(funcORvecfield.type === "surf") {
3368
- var x = Chalkboard.real.parse("(s, t) => " + funcORvecfield.definition[0]),
3369
- y = Chalkboard.real.parse("(s, t) => " + funcORvecfield.definition[1]),
3370
- z = Chalkboard.real.parse("(s, t) => " + funcORvecfield.definition[2]);
3371
- var dxds = (x(vec.x + h, vec.y) - x(vec.x, vec.y)) / h,
3372
- dxdt = (x(vec.x, vec.y + h) - x(vec.x, vec.y)) / h,
3373
- dyds = (y(vec.x + h, vec.y) - y(vec.x, vec.y)) / h,
3374
- dydt = (y(vec.x, vec.y + h) - y(vec.x, vec.y)) / h,
3375
- dzds = (z(vec.x + h, vec.y) - z(vec.x, vec.y)) / h,
3376
- dzdt = (z(vec.x, vec.y + h) - z(vec.x, vec.y)) / h;
3377
- return Chalkboard.matr.new([dxds, dxdt],
3378
- [dyds, dydt],
3379
- [dzds, dzdt]);
3380
- } else if(funcORvecfield.type === "mult") {
3381
- var f = Chalkboard.real.parse("(x, y) => " + funcORvecfield.definition);
3382
- var dfdx = (f(vec.x + h, vec.y) - f(vec.x, vec.y)) / h,
3383
- dfdy = (f(vec.x, vec.y + h) - f(vec.x, vec.y)) / h;
3384
- return Chalkboard.vec2.new(dfdx, dfdy);
3385
- } else if(funcORvecfield.type === "vec2field") {
3386
- var p = Chalkboard.real.parse("(x, y) => " + funcORvecfield.p),
3387
- q = Chalkboard.real.parse("(x, y) => " + funcORvecfield.q);
3388
- var dpdx = (p(vec.x + h, vec.y) - p(vec.x, vec.y)) / h,
3389
- dpdy = (p(vec.x, vec.y + h) - p(vec.x, vec.y)) / h,
3390
- dqdx = (q(vec.x + h, vec.y) - q(vec.x, vec.y)) / h,
3391
- dqdy = (q(vec.x, vec.y + h) - q(vec.x, vec.y)) / h;
3392
- return Chalkboard.matr.new([dpdx, dpdy],
3393
- [dqdx, dqdy]);
3394
- } else if(funcORvecfield.type === "vec3field") {
3395
- var p = Chalkboard.real.parse("(x, y, z) => " + funcORvecfield.p),
3396
- q = Chalkboard.real.parse("(x, y, z) => " + funcORvecfield.q),
3397
- r = Chalkboard.real.parse("(x, y, z) => " + funcORvecfield.r);
3398
- var dpdx = (p(vec.x + h, vec.y, vec.z) - p(vec.x, vec.y, vec.z)) / h,
3399
- dpdy = (p(vec.x, vec.y + h, vec.z) - p(vec.x, vec.y, vec.z)) / h,
3400
- dpdz = (p(vec.x, vec.y, vec.z + h) - p(vec.x, vec.y, vec.z)) / h,
3401
- dqdx = (q(vec.x + h, vec.y, vec.z) - q(vec.x, vec.y, vec.z)) / h,
3402
- dqdy = (q(vec.x, vec.y + h, vec.z) - q(vec.x, vec.y, vec.z)) / h,
3403
- dqdz = (q(vec.x, vec.y, vec.z + h) - q(vec.x, vec.y, vec.z)) / h,
3404
- drdx = (r(vec.x + h, vec.y, vec.z) - r(vec.x, vec.y, vec.z)) / h,
3405
- drdy = (r(vec.x, vec.y + h, vec.z) - r(vec.x, vec.y, vec.z)) / h,
3406
- drdz = (r(vec.x, vec.y, vec.z + h) - r(vec.x, vec.y, vec.z)) / h;
3407
- return Chalkboard.matr.new([dpdx, dpdy, dpdz],
3408
- [dqdx, dqdy, dqdz],
3409
- [drdx, drdy, drdz]);
3410
- } else if(funcORvecfield.type === "vec4field") {
3411
- var p = Chalkboard.real.parse("(x, y, z, w) => " + funcORvecfield.p),
3412
- q = Chalkboard.real.parse("(x, y, z, w) => " + funcORvecfield.q),
3413
- r = Chalkboard.real.parse("(x, y, z, w) => " + funcORvecfield.r),
3414
- s = Chalkboard.real.parse("(x, y, z, w) => " + funcORvecfield.s);
3415
- var dpdx = (p(vec.x + h, vec.y, vec.z, vec.w) - p(vec.x, vec.y, vec.z, vec.w)) / h,
3416
- dpdy = (p(vec.x, vec.y + h, vec.z, vec.w) - p(vec.x, vec.y, vec.z, vec.w)) / h,
3417
- dpdz = (p(vec.x, vec.y, vec.z + h, vec.w) - p(vec.x, vec.y, vec.z, vec.w)) / h,
3418
- dpdw = (p(vec.x, vec.y, vec.z, vec.w + h) - p(vec.x, vec.y, vec.z, vec.w)) / h,
3419
- dqdx = (q(vec.x + h, vec.y, vec.z, vec.w) - q(vec.x, vec.y, vec.z, vec.w)) / h,
3420
- dqdy = (q(vec.x, vec.y + h, vec.z, vec.w) - q(vec.x, vec.y, vec.z, vec.w)) / h,
3421
- dqdz = (q(vec.x, vec.y, vec.z + h, vec.w) - q(vec.x, vec.y, vec.z, vec.w)) / h,
3422
- dqdw = (q(vec.x, vec.y, vec.z, vec.w + h) - q(vec.x, vec.y, vec.z, vec.w)) / h,
3423
- drdx = (r(vec.x + h, vec.y, vec.z, vec.w) - r(vec.x, vec.y, vec.z, vec.w)) / h,
3424
- drdy = (r(vec.x, vec.y + h, vec.z, vec.w) - r(vec.x, vec.y, vec.z, vec.w)) / h,
3425
- drdz = (r(vec.x, vec.y, vec.z + h, vec.w) - r(vec.x, vec.y, vec.z, vec.w)) / h,
3426
- drdw = (r(vec.x, vec.y, vec.z, vec.w + h) - r(vec.x, vec.y, vec.z, vec.w)) / h,
3427
- dsdx = (s(vec.x + h, vec.y, vec.z, vec.w) - s(vec.x, vec.y, vec.z, vec.w)) / h,
3428
- dsdy = (s(vec.x, vec.y + h, vec.z, vec.w) - s(vec.x, vec.y, vec.z, vec.w)) / h,
3429
- dsdz = (s(vec.x, vec.y, vec.z + h, vec.w) - s(vec.x, vec.y, vec.z, vec.w)) / h,
3430
- dsdw = (s(vec.x, vec.y, vec.z, vec.w + h) - s(vec.x, vec.y, vec.z, vec.w)) / h;
3431
- return Chalkboard.matr.new([dpdx, dpdy, dpdz, dpdw],
3432
- [dqdx, dqdy, dqdz, dqdw],
3433
- [drdx, drdy, drdz, drdw],
3434
- [dsdx, dsdy, dsdz, dsdw]);
3435
- } else {
3436
- return "TypeError: Parameter \"funcORvecfield\" must be of type \"surf\", \"mult\", \"vec2field\", \"vec3field\", or \"vec4field\".";
3437
- }
3438
- },
3439
- grad2: function(funcORvecfield, vec) {
3440
- var h = 0.00001;
3441
- if(funcORvecfield.type === "surf") {
3442
- var x = Chalkboard.real.parse("(s, t) => " + funcORvecfield.definition[0]),
3443
- y = Chalkboard.real.parse("(s, t) => " + funcORvecfield.definition[1]),
3444
- z = Chalkboard.real.parse("(s, t) => " + funcORvecfield.definition[2]);
3445
- var d2xds2 = (x(vec.x + h, vec.y) - 2 * x(vec.x, vec.y) + x(vec.x - h, vec.y)) / (h * h),
3446
- d2xdt2 = (x(vec.x, vec.y + h) - 2 * x(vec.x, vec.y) + x(vec.x, vec.y - h)) / (h * h),
3447
- d2yds2 = (y(vec.x + h, vec.y) - 2 * y(vec.x, vec.y) + y(vec.x - h, vec.y)) / (h * h),
3448
- d2ydt2 = (y(vec.x, vec.y + h) - 2 * y(vec.x, vec.y) + y(vec.x, vec.y - h)) / (h * h),
3449
- d2zds2 = (z(vec.x + h, vec.y) - 2 * z(vec.x, vec.y) + z(vec.x - h, vec.y)) / (h * h),
3450
- d2zdt2 = (z(vec.x, vec.y + h) - 2 * z(vec.x, vec.y) + z(vec.x, vec.y - h)) / (h * h);
3451
- return Chalkboard.matr.new([d2xds2, d2xdt2],
3452
- [d2yds2, d2ydt2],
3453
- [d2zds2, d2zdt2]);
3454
- } else if(funcORvecfield.type === "mult") {
3455
- var f = Chalkboard.real.parse("(x, y) => " + funcORvecfield.definition);
3456
- var d2fdx2 = (f(vec.x + h, vec.y) - 2 * f(vec.x, vec.y) + f(vec.x - h, vec.y)) / (h * h),
3457
- d2fdy2 = (f(vec.x, vec.y + h) - 2 * f(vec.x, vec.y) + f(vec.x, vec.y - h)) / (h * h),
3458
- d2fdxdy = (f(vec.x + h, vec.y + h) - f(vec.x + h, vec.y) - f(vec.x, vec.y + h) + f(vec.x, vec.y)) / (h * h),
3459
- d2fdydx = (f(vec.x + h, vec.y + h) - f(vec.x, vec.y + h) - f(vec.x + h, vec.y) + f(vec.x, vec.y)) / (h * h);
3460
- return Chalkboard.matr.new([d2fdx2, d2fdxdy],
3461
- [d2fdydx, d2fdy2]);
3462
- } else if(funcORvecfield.type === "vec2field") {
3463
- var p = Chalkboard.real.parse("(x, y) => " + funcORvecfield.p),
3464
- q = Chalkboard.real.parse("(x, y) => " + funcORvecfield.q);
3465
- var d2pdx2 = (p(vec.x + h, vec.y) - 2 * p(vec.x, vec.y) + p(vec.x - h, vec.y)) / (h * h),
3466
- d2pdy2 = (p(vec.x, vec.y + h) - 2 * p(vec.x, vec.y) + p(vec.x, vec.y - h)) / (h * h),
3467
- d2qdx2 = (q(vec.x + h, vec.y) - 2 * q(vec.x, vec.y) + q(vec.x - h, vec.y)) / (h * h),
3468
- d2qdy2 = (q(vec.x, vec.y + h) - 2 * q(vec.x, vec.y) + q(vec.x, vec.y - h)) / (h * h);
3469
- return Chalkboard.matr.new([d2pdx2, d2pdy2],
3470
- [d2qdx2, d2qdy2]);
3471
- } else if(funcORvecfield.type === "vec3field") {
3472
- var p = Chalkboard.real.parse("(x, y, z) => " + funcORvecfield.p),
3473
- q = Chalkboard.real.parse("(x, y, z) => " + funcORvecfield.q),
3474
- r = Chalkboard.real.parse("(x, y, z) => " + funcORvecfield.r);
3475
- var d2pdx2 = (p(vec.x + h, vec.y, vec.z) - 2 * p(vec.x, vec.y, vec.z) + p(vec.x - h, vec.y, vec.z)) / (h * h),
3476
- d2pdy2 = (p(vec.x, vec.y + h, vec.z) - 2 * p(vec.x, vec.y, vec.z) + p(vec.x, vec.y - h, vec.z)) / (h * h),
3477
- d2pdz2 = (p(vec.x, vec.y, vec.z + h) - 2 * p(vec.x, vec.y, vec.z) + p(vec.x, vec.y, vec.z - h)) / (h * h),
3478
- d2qdx2 = (q(vec.x + h, vec.y, vec.z) - 2 * q(vec.x, vec.y, vec.z) + q(vec.x - h, vec.y, vec.z)) / (h * h),
3479
- d2qdy2 = (q(vec.x, vec.y + h, vec.z) - 2 * q(vec.x, vec.y, vec.z) + q(vec.x, vec.y - h, vec.z)) / (h * h),
3480
- d2qdz2 = (q(vec.x, vec.y, vec.z + h) - 2 * q(vec.x, vec.y, vec.z) + q(vec.x, vec.y, vec.z - h)) / (h * h),
3481
- d2rdx2 = (r(vec.x + h, vec.y, vec.z) - 2 * r(vec.x, vec.y, vec.z) + r(vec.x - h, vec.y, vec.z)) / (h * h),
3482
- d2rdy2 = (r(vec.x, vec.y + h, vec.z) - 2 * r(vec.x, vec.y, vec.z) + r(vec.x, vec.y - h, vec.z)) / (h * h),
3483
- d2rdz2 = (r(vec.x, vec.y, vec.z + h) - 2 * r(vec.x, vec.y, vec.z) + r(vec.x, vec.y, vec.z - h)) / (h * h);
3484
- return Chalkboard.matr.new([d2pdx2, d2pdy2, d2pdz2],
3485
- [d2qdx2, d2qdy2, d2qdz2],
3486
- [d2rdx2, d2rdy2, d2rdz2]);
3487
- } else if(funcORvecfield.type === "vec4field") {
3488
- var p = Chalkboard.real.parse("(x, y, z, w) => " + funcORvecfield.p),
3489
- q = Chalkboard.real.parse("(x, y, z, w) => " + funcORvecfield.q),
3490
- r = Chalkboard.real.parse("(x, y, z, w) => " + funcORvecfield.r),
3491
- s = Chalkboard.real.parse("(x, y, z, w) => " + funcORvecfield.s);
3492
- var d2pdx2 = (p(vec.x + h, vec.y, vec.z, vec.w) - 2 * p(vec.x, vec.y, vec.z, vec.w) + p(vec.x - h, vec.y, vec.z, vec.w)) / (h * h),
3493
- d2pdy2 = (p(vec.x, vec.y + h, vec.z, vec.w) - 2 * p(vec.x, vec.y, vec.z, vec.w) + p(vec.x, vec.y - h, vec.z, vec.w)) / (h * h),
3494
- d2pdz2 = (p(vec.x, vec.y, vec.z + h, vec.w) - 2 * p(vec.x, vec.y, vec.z, vec.w) + p(vec.x, vec.y, vec.z - h, vec.w)) / (h * h),
3495
- d2pdw2 = (p(vec.x, vec.y, vec.z, vec.w + h) - 2 * p(vec.x, vec.y, vec.z, vec.w) + p(vec.x, vec.y, vec.z, vec.w - h)) / (h * h),
3496
- d2qdx2 = (q(vec.x + h, vec.y, vec.z, vec.w) - 2 * q(vec.x, vec.y, vec.z, vec.w) + q(vec.x - h, vec.y, vec.z, vec.w)) / (h * h),
3497
- d2qdy2 = (q(vec.x, vec.y + h, vec.z, vec.w) - 2 * q(vec.x, vec.y, vec.z, vec.w) + q(vec.x, vec.y - h, vec.z, vec.w)) / (h * h),
3498
- d2qdz2 = (q(vec.x, vec.y, vec.z + h, vec.w) - 2 * q(vec.x, vec.y, vec.z, vec.w) + q(vec.x, vec.y, vec.z - h, vec.w)) / (h * h),
3499
- d2qdw2 = (q(vec.x, vec.y, vec.z, vec.w + h) - 2 * q(vec.x, vec.y, vec.z, vec.w) + q(vec.x, vec.y, vec.z, vec.w - h)) / (h * h),
3500
- d2rdx2 = (r(vec.x + h, vec.y, vec.z, vec.w) - 2 * r(vec.x, vec.y, vec.z, vec.w) + r(vec.x - h, vec.y, vec.z, vec.w)) / (h * h),
3501
- d2rdy2 = (r(vec.x, vec.y + h, vec.z, vec.w) - 2 * r(vec.x, vec.y, vec.z, vec.w) + r(vec.x, vec.y - h, vec.z, vec.w)) / (h * h),
3502
- d2rdz2 = (r(vec.x, vec.y, vec.z + h, vec.w) - 2 * r(vec.x, vec.y, vec.z, vec.w) + r(vec.x, vec.y, vec.z - h, vec.w)) / (h * h),
3503
- d2rdw2 = (r(vec.x, vec.y, vec.z, vec.w + h) - 2 * r(vec.x, vec.y, vec.z, vec.w) + r(vec.x, vec.y, vec.z, vec.w - h)) / (h * h),
3504
- d2sdx2 = (s(vec.x + h, vec.y, vec.z, vec.w) - 2 * s(vec.x, vec.y, vec.z, vec.w) + s(vec.x - h, vec.y, vec.z, vec.w)) / (h * h),
3505
- d2sdy2 = (s(vec.x, vec.y + h, vec.z, vec.w) - 2 * s(vec.x, vec.y, vec.z, vec.w) + s(vec.x, vec.y - h, vec.z, vec.w)) / (h * h),
3506
- d2sdz2 = (s(vec.x, vec.y, vec.z + h, vec.w) - 2 * s(vec.x, vec.y, vec.z, vec.w) + s(vec.x, vec.y, vec.z - h, vec.w)) / (h * h),
3507
- d2sdw2 = (s(vec.x, vec.y, vec.z, vec.w + h) - 2 * s(vec.x, vec.y, vec.z, vec.w) + s(vec.x, vec.y, vec.z, vec.w - h)) / (h * h);
3508
- return Chalkboard.matr.new([d2pdx2, d2pdy2, d2pdz2, d2pdw2],
3509
- [d2qdx2, d2qdy2, d2qdz2, d2qdw2],
3510
- [d2rdx2, d2rdy2, d2rdz2, d2rdw2],
3511
- [d2sdx2, d2sdy2, d2sdz2, d2sdw2]);
3512
- } else {
3513
- return "TypeError: Parameter \"funcORvecfield\" must be of type \"surf\", \"mult\", \"vec2field\", \"vec3field\", or \"vec4field\".";
3514
- }
3515
- },
3516
- div: function(vecfield, vec) {
3517
- if(vecfield.type === "vec2field" || vecfield.type === "vec3field" || vecfield.type === "vec4field") {
3518
- return Chalkboard.matr.trace(Chalkboard.calc.grad(vecfield, vec));
3519
- } else {
3520
- return "TypeError: Parameter \"vecfield\" must be of type \"vec2field\", \"vec3field\", or \"vec4field\".";
3521
- }
3522
- },
3523
- curl: function(vecfield, vec) {
3524
- var h = 0.000000001;
3525
- if(vecfield.type === "vec2field") {
3526
- var p = Chalkboard.real.parse("(x, y) => " + vecfield.p),
3527
- q = Chalkboard.real.parse("(x, y) => " + vecfield.q);
3528
- var dpdy = (p(vec.x, vec.y + h) - p(vec.x, vec.y)) / h,
3529
- dqdx = (q(vec.x + h, vec.y) - q(vec.x, vec.y)) / h;
3530
- return Chalkboard.vec3.new(0, 0, dqdx - dpdy);
3531
- } else if(vecfield.type === "vec3field") {
3532
- var p = Chalkboard.real.parse("(x, y, z) => " + vecfield.p),
3533
- q = Chalkboard.real.parse("(x, y, z) => " + vecfield.q),
3534
- r = Chalkboard.real.parse("(x, y, z) => " + vecfield.r);
3535
- var dpdy = (p(vec.x, vec.y + h, vec.z) - p(vec.x, vec.y, vec.z)) / h,
3536
- dpdz = (p(vec.x, vec.y, vec.z + h) - p(vec.x, vec.y, vec.z)) / h,
3537
- dqdx = (q(vec.x + h, vec.y, vec.z) - q(vec.x, vec.y, vec.z)) / h,
3538
- dqdz = (q(vec.x, vec.y, vec.z + h) - q(vec.x, vec.y, vec.z)) / h,
3539
- drdx = (r(vec.x + h, vec.y, vec.z) - r(vec.x, vec.y, vec.z)) / h,
3540
- drdy = (r(vec.x, vec.y + h, vec.z) - r(vec.x, vec.y, vec.z)) / h;
3541
- return Chalkboard.vec3.new(drdy - dqdz, dpdz - drdx, dqdx - dpdy);
3542
- } else {
3543
- return "TypeError: Parameter \"vecfield\" must be of type \"vec2field\" or \"vec3field\".";
3544
- }
3545
- },
3546
- dfdz: function(func, comp) {
3547
- var h = 0.000000001;
3548
- if(func.type === "comp") {
3549
- var u = Chalkboard.comp.parse("(a, b) => " + func.definition[0]),
3550
- v = Chalkboard.comp.parse("(a, b) => " + func.definition[1]);
3551
- var duda = (u(comp.a + h, comp.b) - u(comp.a, comp.b)) / h,
3552
- dudb = (u(comp.a, comp.b + h) - u(comp.a, comp.b)) / h,
3553
- dvda = (v(comp.a + h, comp.b) - v(comp.a, comp.b)) / h,
3554
- dvdb = (v(comp.a, comp.b + h) - v(comp.a, comp.b)) / h;
3555
- return {a: Chalkboard.comp.new(duda, dvda), b: Chalkboard.comp.new(dudb, dvdb)};
3556
- } else {
3557
- return "TypeError: Parameter \"func\" must be of type \"comp\".";
3558
- }
3559
- },
3560
- d2fdz2: function(func, comp) {
3561
- var h = 0.00001;
3562
- if(func.type === "comp") {
3563
- var u = Chalkboard.comp.parse("(a, b) => " + func.definition[0]),
3564
- v = Chalkboard.comp.parse("(a, b) => " + func.definition[1]);
3565
- var d2uda2 = (u(comp.a + h, comp.b) - 2 * u(comp.a, comp.b) + u(comp.a - h, comp.b)) / (h * h),
3566
- d2udb2 = (u(comp.a, comp.b + h) - 2 * u(comp.a, comp.b) + u(comp.a, comp.b - h)) / (h * h),
3567
- d2vda2 = (v(comp.a + h, comp.b) - 2 * v(comp.a, comp.b) + v(comp.a - h, comp.b)) / (h * h),
3568
- d2vdb2 = (v(comp.a, comp.b + h) - 2 * v(comp.a, comp.b) + v(comp.a, comp.b - h)) / (h * h);
3569
- return {a: Chalkboard.comp.new(d2uda2, d2vda2), b: Chalkboard.comp.new(d2udb2, d2vdb2)};
3570
- } else {
3571
- return "TypeError: Parameter \"func\" must be of type \"comp\".";
3572
- }
3573
- },
3574
- fxdx: function(func, a, b) {
3575
- if(func.type === "expl" || func.type === "inve" || func.type === "pola") {
3576
- var f;
3577
- if(func.type === "expl") {
3578
- f = Chalkboard.real.parse("x => " + func.definition);
3579
- } else if(func.type === "inve") {
3580
- f = Chalkboard.real.parse("y => " + func.definition);
3581
- } else if(func.type === "pola") {
3582
- f = Chalkboard.real.parse("O => " + "((" + func.definition + ") * (" + func.definition + ")) / 2");
3583
- }
3584
- var fx = f(a) + f(b);
3585
- var dx = (b - a) / 1000000;
3586
- for(var i = 1; i < 1000000; i++) {
3587
- fx += i % 2 === 0 ? 2 * f(a + i * dx) : 4 * f(a + i * dx);
3588
- }
3589
- return (fx * dx) / 3;
3590
- } else if(func.type === "curv") {
3591
- if(func.definition.length === 2) {
3592
- var x = Chalkboard.real.parse("t => " + func.definition[0]),
3593
- y = Chalkboard.real.parse("t => " + func.definition[1]);
3594
- var xt = x(a) + x(b),
3595
- yt = y(a) + y(b);
3596
- var dt = (b - a) / 1000000;
3597
- for(var i = 1; i < 1000000; i++) {
3598
- xt += i % 2 === 0 ? 2 * x(a + i * dt) : 4 * x(a + i * dt);
3599
- yt += i % 2 === 0 ? 2 * y(a + i * dt) : 4 * y(a + i * dt);
3600
- }
3601
- return Chalkboard.vec2.new((xt * dt) / 3, (yt * dt) / 3);
3602
- } else if(func.definition.length === 3) {
3603
- var x = Chalkboard.real.parse("t => " + func.definition[0]),
3604
- y = Chalkboard.real.parse("t => " + func.definition[1]),
3605
- z = Chalkboard.real.parse("t => " + func.definition[2]);
3606
- var xt = x(a) + x(b),
3607
- yt = y(a) + y(b),
3608
- zt = z(a) + z(b);
3609
- var dt = (b - a) / 1000000;
3610
- for(var i = 1; i < 1000000; i++) {
3611
- xt += i % 2 === 0 ? 2 * x(a + i * dt) : 4 * x(a + i * dt);
3612
- yt += i % 2 === 0 ? 2 * y(a + i * dt) : 4 * y(a + i * dt);
3613
- zt += i % 2 === 0 ? 2 * z(a + i * dt) : 4 * z(a + i * dt);
3614
- }
3615
- return Chalkboard.vec3.new((xt * dt) / 3, (yt * dt) / 3, (zt * dt) / 3);
3616
- }
3617
- } else {
3618
- return "TypeError: Parameter \"func\" must be of type \"expl\", \"inve\", \"pola\", or \"curv\".";
3619
- }
3620
- },
3621
- fxydxdy: function(func, a, b, c, d) {
3622
- if(func.type === "mult") {
3623
- var f = Chalkboard.real.parse("(x, y) => " + func.definition);
3624
- var result = 0;
3625
- var dx = (b - a) / 10000,
3626
- dy = (d - c) / 10000;
3627
- for(var x = a; x <= b; x += dx) {
3628
- for(var y = c; y <= d; y += dy) {
3629
- result += f(x, y);
3630
- }
3631
- }
3632
- return result * dx * dy;
3633
- } else {
3634
- return "TypeError: Parameter \"func\" must be of type \"mult\".";
3635
- }
3636
- },
3637
- fds: function(func, a, b, c, d) {
3638
- var result = 0;
3639
- var drdt, drds;
3640
- if(func.type === "curv") {
3641
- var dt = (b - a) / 10000;
3642
- if(func.definition.length === 2) {
3643
- for(var t = a; t <= b; t += dt) {
3644
- drdt = Chalkboard.calc.dfdx(func, t);
3645
- result += Chalkboard.vec2.mag(drdt);
3646
- }
3647
- return result * dt;
3648
- } else if(func.definition.length === 3) {
3649
- for(var t = a; t <= b; t += dt) {
3650
- drdt = Chalkboard.calc.dfdx(func, t);
3651
- result += Chalkboard.vec3.mag(drdt);
3652
- }
3653
- return result * dt;
3654
- }
3655
- } else if(func.type === "surf") {
3656
- var dt = (b - a) / 100,
3657
- ds = (d - c) / 100;
3658
- for(var s = c; s <= d; s += ds) {
3659
- for(var t = a; t <= b; t += dt) {
3660
- drds = Chalkboard.matr.toVector(Chalkboard.calc.grad(func, Chalkboard.vec2.new(s, t)), "vec3", "col", 1);
3661
- drdt = Chalkboard.matr.toVector(Chalkboard.calc.grad(func, Chalkboard.vec2.new(s, t)), "vec3", "col", 2);
3662
- result += Chalkboard.vec3.mag(Chalkboard.vec3.cross(drds, drdt));
3663
- }
3664
- }
3665
- return result * ds * dt;
3666
- } else {
3667
- return "TypeError: Parameter \"func\" must be of type \"curv\" or \"surf\".";
3668
- }
3669
- },
3670
- frds: function(funcORvecfield, func, a, b) {
3671
- if(func.type === "curv") {
3672
- var result = 0;
3673
- var dt = (b - a) / 10000;
3674
- if(funcORvecfield.type === "mult") {
3675
- for(var t = a; t <= b; t += dt) {
3676
- result += Chalkboard.real.val(funcORvecfield, Chalkboard.vec2.toArray(Chalkboard.real.val(func, t))) * Chalkboard.vec2.mag(Chalkboard.calc.dfdx(func, t));
3677
- }
3678
- return result * dt;
3679
- } else if(funcORvecfield.type === "vec2field") {
3680
- for(var t = a; t <= b; t += dt) {
3681
- result += Chalkboard.vec2.dot(Chalkboard.vec2.fromField(funcORvecfield, Chalkboard.real.val(func, t)), Chalkboard.calc.dfdx(func, t));
3682
- }
3683
- return result * dt;
3684
- } else if(funcORvecfield.type === "vec3field") {
3685
- for(var t = a; t <= b; t += dt) {
3686
- result += Chalkboard.vec3.dot(Chalkboard.vec3.fromField(funcORvecfield, Chalkboard.real.val(func, t)), Chalkboard.calc.dfdx(func, t));
3687
- }
3688
- return result * dt;
3689
- } else {
3690
- return "TypeError: Parameter \"funcORvecfield\" must be of type \"mult\", \"vec2field\", or \"vec3field\".";
3691
- }
3692
- } else {
3693
- return "TypeError: Parameter \"func\" must be of type \"curv\".";
3694
- }
3695
- },
3696
- fnds: function(vecfield, func, a, b, c, d) {
3697
- var result = 0;
3698
- var drdt, drds;
3699
- if(func.type === "curv") {
3700
- var dt = (b - a) / 10000;
3701
- if(func.definition.length === 2) {
3702
- for(var t = a; t <= b; t += dt) {
3703
- drdt = Chalkboard.calc.dfdx(func, t);
3704
- result += Chalkboard.vec2.dot(Chalkboard.vec2.fromField(vecfield, Chalkboard.real.val(func, t)), Chalkboard.vec2.new(-drdt.y, drdt.x)) * Chalkboard.vec2.mag(drdt);
3705
- }
3706
- return result * dt;
3707
- } else if(func.definition.length === 3) {
3708
- for(var t = a; t <= b; t += dt) {
3709
- drdt = Chalkboard.calc.dfdx(func, t);
3710
- result += Chalkboard.vec3.dot(Chalkboard.vec3.fromField(vecfield, Chalkboard.real.val(func, t)), Chalkboard.calc.normal(func, t)) * Chalkboard.vec3.mag(drdt);
3711
- }
3712
- return result * dt;
3713
- }
3714
- } else if(func.type === "surf") {
3715
- var dt = (b - a) / 100,
3716
- ds = (d - c) / 100;
3717
- for(var s = c; s <= d; s += ds) {
3718
- for(var t = a; t <= b; t += dt) {
3719
- drds = Chalkboard.matr.toVector(Chalkboard.calc.grad(func, Chalkboard.vec2.new(s, t)), "vec3", "col", 1);
3720
- drdt = Chalkboard.matr.toVector(Chalkboard.calc.grad(func, Chalkboard.vec2.new(s, t)), "vec3", "col", 2);
3721
- result += Chalkboard.vec3.scalarTriple(Chalkboard.vec3.fromField(vecfield, Chalkboard.real.val(func, Chalkboard.vec2.new(s, t))), drds, drdt);
3722
- }
3723
- }
3724
- return result * ds * dt;
3725
- } else {
3726
- return "TypeError: Parameter \"func\" must be of type \"curv\" or \"surf\".";
3727
- }
3728
- },
3729
- fzdz: function(func_1, func_2, a, b) {
3730
- if(func_1.type === "comp") {
3731
- if(func_2.type === "curv") {
3732
- var result = Chalkboard.comp.new(0, 0);
3733
- var dt = (b - a) / 10000;
3734
- for(var t = a; t <= b; t += dt) {
3735
- var fz = Chalkboard.comp.val(func_1, Chalkboard.vec2.toComplex(Chalkboard.real.val(func_2, t)));
3736
- var rt = Chalkboard.calc.dfdx(func_2, t);
3737
- result = Chalkboard.comp.add(result, Chalkboard.comp.new((fz.a * rt.x) - (fz.b * rt.y), (fz.b * rt.x) + (fz.a * rt.y)));
3738
- }
3739
- return Chalkboard.comp.scl(result, dt);
3740
- } else {
3741
- return "TypeError: Parameter \"func_2\" must be of type \"curv\".";
3742
- }
3743
- } else {
3744
- return "TypeError: Parameter \"func_1\" must be of type \"comp\".";
3745
- }
3746
- },
3747
- extrema: function(func, domain) {
3748
- var result = [];
3749
- for(var i = domain[0]; i <= domain[1]; i++) {
3750
- if(Math.round(Chalkboard.calc.dfdx(func, i)) === 0) {
3751
- result.push(i);
3752
- }
3753
- }
3754
- return result;
3755
- },
3756
- mean: function(func, a, b) {
3757
- return (Chalkboard.calc.fxdx(func, a, b)) / (b - a);
3758
- },
3759
- curvature: function(func, val) {
3760
- if(func.type === "curv") {
3761
- if(func.definition.length === 2) {
3762
- var dxdt = Chalkboard.calc.dfdx(func, val).x,
3763
- dydt = Chalkboard.calc.dfdx(func, val).y,
3764
- d2xdt2 = Chalkboard.calc.d2fdx2(func, val).x,
3765
- d2ydt2 = Chalkboard.calc.d2fdx2(func, val).y;
3766
- return Math.abs(dxdt * d2ydt2 - dydt * d2xdt2) / Math.sqrt((dxdt * dxdt + dydt * dydt) * (dxdt * dxdt + dydt * dydt) * (dxdt * dxdt + dydt * dydt));
3767
- } else if(func.definition.length === 3) {
3768
- return Chalkboard.vec3.mag(Chalkboard.calc.normal(func, val)) / Chalkboard.vec3.mag(Chalkboard.calc.dfdx(func, val));
3769
- }
3770
- } else {
3771
- return "TypeError: Parameter \"func\" must be of type \"curv\".";
3772
- }
3773
- },
3774
- convolution: function(func_1, func_2, val) {
3775
- return Chalkboard.calc.fxdx(Chalkboard.real.function("(" + func_1.definition + ") * (" + func_2.definition.replace(/x/g, "(" + val + " - x)") + ")"), -100, 100);
3776
- },
3777
- correlation: function(func_1, func_2, val) {
3778
- return Chalkboard.calc.fxdx(Chalkboard.real.function("(" + func_1.definition + ") * (" + func_2.definition.replace(/x/g, "(" + val + " + x)") + ")"), -100, 100);
3779
- },
3780
- autocorrelation: function(func, val) {
3781
- return Chalkboard.calc.correlation(func, func, val);
3782
- },
3783
- Taylor: function(func, val, n, a) {
3784
- if(func.type === "expl") {
3785
- if(n === 0) {
3786
- return Chalkboard.real.val(func, a);
3787
- } else if(n === 1) {
3788
- return Chalkboard.real.val(func, a) + Chalkboard.calc.dfdx(func, a) * (val - a);
3789
- } else if(n === 2) {
3790
- return Chalkboard.real.val(func, a) + Chalkboard.calc.dfdx(func, a) * (val - a) + (Chalkboard.calc.d2fdx2(func, a) * (val - a) * (val - a)) / 2;
3791
- }
3792
- } else {
3793
- return "TypeError: Parameter \"func\" must be of type \"expl\".";
3794
- }
3795
- },
3796
- Laplace: function(func, val) {
3797
- if(val > 0) {
3798
- return Chalkboard.calc.fxdx(Chalkboard.real.function("(" + func.definition + ") * Math.exp(-" + val + " * x)"), 0, 10);
3799
- } else {
3800
- return undefined;
3801
- }
3802
- },
3803
- Fourier: function(func, val) {
3804
- return (2 * Chalkboard.calc.fxdx(Chalkboard.real.function("(" + func.definition + ") * Math.cos(" + val + " * x)"), 0, 10)) / Chalkboard.PI();
3805
- },
3806
- Newton: function(func, domain) {
3807
- domain = domain || [-1, 1];
3808
- var x = Chalkboard.numb.random(domain[0], domain[1]);
3809
- for(var i = 0; i < 10; i++) {
3810
- x = x - Chalkboard.real.val(func, x) / Chalkboard.calc.dfdx(func, x);
3811
- }
3812
- return x;
3813
- }
3814
- }
3815
- };