-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathengine.js
133 lines (119 loc) · 3.08 KB
/
engine.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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Get the drawing panel
var ctx = $("#viewport")[0].getContext("2d");
// Gets input and does some parsing
function getVal(id) {
var num = $(id).val().replace(/[^\d-\.]/g, ""); // Crude way to fix non-numeric inputs
if (num == "") { // ex, the user entered __x which should be interpreted as x = 1x
return 1;
} else if (num == '-') { //ex, the user entered -x which should be interpreted as -x = -1x
return -1;
} else {
return num;
}
}
// Draws a line from (0,0) to (x,y)
function drawFunc(x, y) {
ctx.beginPath();
ctx.moveTo(0,0);
ctx.lineTo(300*x, -300*y);
ctx.stroke();
}
// Called on load and on button press. Updates canvas.
function update() {
// Get all the values
var i = getVal("#i"),
j = getVal("#j"),
k = getVal("#k"),
x = getVal("#x"),
y = getVal("#y"),
z = getVal("#z"),
c = getVal("#c");
// Get their lengths
var lijk = Math.sqrt(i*i + j*j + k*k),
lxyz = Math.sqrt(x*x + y*y + z*z)*Math.sign(c); // sign(c) is for flipping
// Convert to unit vectors
i /= lijk;
j /= lijk;
k /= lijk;
x /= lxyz;
y /= lxyz;
z /= lxyz;
// Clean the canvas by drawing over it
ctx.fillStyle = "#eeeeee";
ctx.fillRect(-300,-300, 600,600);
// Draw axes
if ( x==0 && y==0 ) { // If vertical, draw xy-plane
ctx.strokeStyle = "#ee1111";
drawFunc(1,0);
ctx.strokeStyle = "#11ee11";
drawFunc(0,1);
ctx.strokeStyle = "#111111";
drawFunc(i,j);
} else {
// s is used repeatedly, so calculate it once and store it to save some time
var s = Math.sqrt(1-z*z);
// Draw axes
ctx.strokeStyle = "#ee1111";
drawFunc( -y/s, -x*z/s ); // Magic
ctx.strokeStyle = "#11ee11";
drawFunc( x/s, -y*z/s ); // Magic
ctx.strokeStyle = "#1111ee";
drawFunc( 0, s ); // Magic
// Draw vector
ctx.strokeStyle = "#111111";
drawFunc( (x*j-y*i)/s, (-i*x*z-j*y*z)/s + k*s ); // Magic
/* Notes on "Magic":
Find comp_a u and comp_b u
where u is the vector given by projecting vector w onto (viewplane) subspace V
and the basis of V: { a , b }
a = <-xz, -yz, x^2+y^2>
b = <-y, x, 0>
comp_a u is the y-coord of V and comp_b u is the x-coord of V
*/
}
}
// Handle button click
$("#gobutton").click( update );
window.addEventListener("keydown", function (event) {
// Do nothing if the event was already processed
if (event.defaultPrevented) {
return;
}
switch (event.key) {
case "Enter":
update();
break;
case "w":
case "ArrowUp":
$("#z").val(getVal("#z")*1.02);
update();
break;
case "s":
case "ArrowDown":
$("#z").val(getVal("#z")*0.98);
update();
break;
case "a":
case "ArrowLeft":
$("#x").val(getVal("#x")*1.01);
$("#y").val(getVal("#y")*0.99);
update();
break;
case "d":
case "ArrowRight":
$("#y").val(getVal("#y")*1.01);
$("#x").val(getVal("#x")*0.99);
update();
break;
default:
return; // Quit when this doesn't handle the key event.
}
// Cancel the default action to avoid it being handled twice
event.preventDefault();
}, true); //Thanks, exd5cxd4
// Initialization of ctx and first draw
$( document ).ready( function() {
ctx.translate(300,300);
ctx.lineWidth = 1;
update();
});