-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdonut.js
100 lines (77 loc) · 3.3 KB
/
donut.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import { create, all } from 'mathjs'
const math = create(all, {})
// TODO: Adjust this based on the flexbox sizing
let thetaSteps = 0.05;
let rotationAngleYSteps = 0.05;
let rotationAngleXZSteps = 0.1;
let screenWidth = 20;
let screenHeight = 20;
let output;
let K2 = 5; // Scale factor of view from object
let R = 0.5;
let X = 2;
let Y = 0;
let K1 = screenWidth*K2*3/(8*(X+R)); // Scale factor of view from screen
render_frames();
function render_frame(rotationAngleX, rotationAngleZ) {
output = new Array(screenHeight).fill(' ').map(() => new Array(screenWidth).fill(' '));
// Rotations
let sinX = math.sin(rotationAngleX);
let cosX = math.cos(rotationAngleX);
let sinZ = math.sin(rotationAngleZ);
let cosZ = math.cos(rotationAngleZ);
let rotationMatrixX = math.matrix([[1, 0, 0],[0, cosX, -sinX], [0, sinX, cosX]]);
let rotationMatrixZ = math.matrix([[cosZ, -sinZ, 0],[sinZ, cosZ, 0], [0, 0, 1]]);
// Rotating circle
for(let theta=0; theta<2*math.pi; theta+=thetaSteps) {
for(let rotationAngleY = 0; rotationAngleY<2*math.pi; rotationAngleY+=rotationAngleYSteps) {
// Generate 2-D Circle
let circleThirdDim = math.matrix([X+R*math.cos(theta), Y+R*math.sin(theta), 0]);
// Rotate 2-D Circle to create 3-D circle (donut)
let sinRotationY = math.sin(rotationAngleY);
let cosRotationY = math.cos(rotationAngleY);
let rotationMatrixY = math.matrix([[cosRotationY, 0, sinRotationY], [0, 1, 0], [-sinRotationY, 0, cosRotationY]]);
let circleThirdDimRotateY = math.multiply(rotationMatrixY, circleThirdDim);
// Rotate about X and Z to create 3-D effect
let circleThirdDimRotateYX = math.multiply(rotationMatrixX, circleThirdDimRotateY);
let circleThirdDimRotateYXZ = math.multiply(rotationMatrixZ, circleThirdDimRotateYX);
let x2 = circleThirdDimRotateYXZ.subset(math.index(0));
let y2 = circleThirdDimRotateYXZ.subset(math.index(1));
let z2 = circleThirdDimRotateYXZ.subset(math.index(2));
// 3-D circle projected to 2-D
let circleSecondDim = [K1*x2/(K2+z2),
K1*y2/(K2+z2)]
let xPrime2 = math.round(screenWidth/2 + circleSecondDim[0]);
let yPrime2 = math.round(screenHeight/2 + circleSecondDim[1]);
output[xPrime2][yPrime2] = 'H';
}
/* console.log(math.size(circleThirdDimRotateY))
circleThirdDimRotateY.forEach(function(value, index, matrix) {
console.log('value: ', value, "index: ", index);
}) */
}
}
async function render_frames() {
for(let rotationAngleXZ=0; rotationAngleXZ<2*math.pi; rotationAngleXZ += rotationAngleXZSteps) {
render_frame(rotationAngleXZ, rotationAngleXZ);
await sleep(100);
print_frame();
}
/*
render_frame(0, 0);
print_frame();
*/
}
function print_frame() {
for(let i=0; i<screenHeight; i++) {
for(let j=0; j<screenWidth; j++) {
process.stdout.write(output[i][j]);
}
console.log();
}
}
function sleep(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}