-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
205 lines (180 loc) · 10.3 KB
/
index.html
File metadata and controls
205 lines (180 loc) · 10.3 KB
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Complex Mappings</title>
<script src="https://cdn.jsdelivr.net/npm/p5@1.4.1/lib/p5.js"></script>
<!-- bootstrap stuff, can delete if not using-->
<!-- use this tutorial for popover: https://www.w3schools.com/bootstrap/bootstrap_popover.asp-->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<!-- Personal CSS-->
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id='text-exp'>
<h1 class>Complex Mappings</h1>
<p>Use this program to visualize mappings of functions with complex inputs and complex outputs, or symbolically, a function f: ℂ → ℂ. Note that for functions log(z) and sqrt(z), only the principal value is displayed. </p>
<ol>
<li>Enter the function you would like to map into the <strong>f(z)=</strong> text box. Use standard operators: <code>+</code>, <code>-</code>, <code>*</code>, <code>/</code>, and <code>^</code>. The following functions are allowed: <code>conj</code> (complex conjugate), <code>mod</code> (modulus), <code>log</code>, <code>sqrt</code>, and <code>arg</code>. Only lowercase function names are accepted.</li>
<li>Click <strong>Plot it!</strong> to apply the function you entered.</li>
<li>Drag your mouse across the left complex plane to create a set of inputted points for f(z). Watch as the outputs appear on the right. </li>
</ol>
You can delete all input points with the <strong>Clear Plot</strong> button. <br><br>
You can fit the output plot to show all of the outputted points with <strong>Fit to Points</strong>. <br><br>
If you want to see how your points are mapped under a different function, enter the new function into the <strong>f(z)=</strong> textbox and click <strong>Plot it!</strong> again. <br><br>
Change the color scheme to one of your liking with the <strong>Color scheme</strong> dropdown. <br><br>
Finally, if you would like to manually rescale one of the plots, do so using the rescale tables at the very bottom. Note that all four of the plot's text boxes must have valid numerical inputs in order to rescale the plot.
<!-- <p>This is an interactive program providing a visualization of mappings of complex functions, that is, functions with a complex input and a complex output.</p>
<p>To use the program, draw on the graph (input complex plane) on the left. As you draw, the points will be mapped using the function <em>f</em> and appear on the graph on the right.</p>
<p>Note that for some functions, like <em>f(z)=log(z)</em> and <em>f(z)=sqrt(z)</em>, there are multiple (or even infinite) values of <em>f(z)</em> that would be satisfactory. In these cases, we choose the value of <em>f(z)</em> belonging to the principle branch of <em>f</em>. To visualize all satisfactory values, you would need to work with Riemann Surfaces (and would need more than two dimensions).</p> -->
</div>
<div id='program'>
<div class='fzBox'>
<div class='fzOptions'>
<span id='colorSchemeText'>Color scheme: </span>
<select name='colorSchemes' id='colorSchemeSelector'>
<option value="standard">standard</option>
<option value="monochrome">monochrome</option>
<option value = "primary">primary</option>
<option value="rainbow">rainbow</option>
<option value="dark">dark mode</option>
<option value="dark primary">dark primary</option>
<option value="dark rainbow">dark rainbow</option>
</select>
<br>
<label for="f(z)">f(z)=</label>
<input type="text" id="functionInput" data-toggle="popover" title="Invalid equation" data-placement="top">
<button id='plotItButton'>Plot it!</button>
<br>
<button id='deleteButton' onclick='clearPts();'>Clear Plot</button>
<button id='fitToPtsButton' onclick='fitToPts();'>Fit to Points</button>
</div>
</div>
<div id='canvas'></div>
<div class='fzBox'>
<div class="float-container">
<div class='float-child'>
<table>
<th></th>
<th>Min</th>
<th>Max</th>
<tr>
<td>Real</td>
<td><input type="text" id="plotRealMin" class="plotBoundInput" data-toggle="popover" title="Invalid" data-placement='left'></td>
<td><input type="text" id="plotRealMax" class="plotBoundInput" data-toggle="popover" title="Invalid"></td>
</tr>
<tr>
<td>Im(i)</td>
<td><input type="text" id="plotImMin" class="plotBoundInput" data-toggle="popover" title="Invalid" data-placement='left'></td>
<td><input type="text" id="plotImMax" class="plotBoundInput" data-toggle="popover" title="Invalid"></td>
</tr>
</table>
<button id='rescaleInputPlotButton'>Rescale Input Plot</button>
</div>
<div class='float-child'>
<table>
<th></th>
<th>Min</th>
<th>Max</th>
<tr>
<td>Real</td>
<td><input type="text" id="MappedPlotRealMin" class="plotBoundInput" data-toggle="popover" title="Invalid" data-placement='left'></td>
<td><input type="text" id="MappedPlotRealMax" class="plotBoundInput" data-toggle="popover" title="Invalid"></td>
</tr>
<tr>
<td>Im(i)</td>
<td><input type="text" id="MappedPlotImMin" class="plotBoundInput" data-toggle="popover" title="Invalid" data-placement='left'></td>
<td><input type="text" id="MappedPlotImMax" class="plotBoundInput" data-toggle="popover" title="Invalid"></td>
</tr>
</table>
<button id='rescaleOutputPlotButton' onclick="rescaleOutput();">Rescale Output Plot</button>
</div>
</div>
</div>
</div>
<script src="complexNumber.js"></script>
<script src="script.js"></script>
<script src="complexPlanePlot.js"></script>
<script src="equationParser.js"></script>
<script>
let colorSchemeSelector = document.getElementById('colorSchemeSelector');
colorSchemeSelector.oninput = function () {
setColorScheme(this.value);
}
let plotItButton = document.getElementById('plotItButton');
let functionInput = document.getElementById('functionInput');
plotItButton.onclick = function() {
let error = setFPostfix(functionInput.value);
// add a popover and change styling if there's an error
if(error) {
$(functionInput).popover('show').off('click');
functionInput.setAttribute("style", "border-color:#ff0000; background-color:#ffdddd;");
}
else {
$(functionInput).popover('destroy');
functionInput.removeAttribute("style");
}
}
// TODO: make all of this a lot cleaner and less repetitive
let rescaleInputButton = document.getElementById('rescaleInputPlotButton');
let inputRealMin = document.getElementById('plotRealMin');
let inputRealMax = document.getElementById('plotRealMax');
let inputImMin = document.getElementById('plotImMin');
let inputImMax = document.getElementById('plotImMax');
rescaleInputButton.onclick = function() {
error = rescaleInputPlot(Number(inputRealMin.value), Number(inputRealMax.value), Number(inputImMin.value), Number(inputImMax.value));
if(error) {
$(inputRealMin).popover('show').off('click');
$(inputRealMax).popover('show').off('click');
$(inputImMin).popover('show').off('click');
$(inputImMax).popover('show').off('click');
inputRealMin.setAttribute("style", "border-color:#ff0000; background-color:#ffdddd;");
inputRealMax.setAttribute("style", "border-color:#ff0000; background-color:#ffdddd;");
inputImMin.setAttribute("style", "border-color:#ff0000; background-color:#ffdddd;");
inputImMax.setAttribute("style", "border-color:#ff0000; background-color:#ffdddd;");
}
else {
$(inputRealMin).popover('destroy');
$(inputRealMax).popover('destroy');
$(inputImMin).popover('destroy');
$(inputImMax).popover('destroy');
inputRealMin.removeAttribute("style");
inputRealMax.removeAttribute("style");
inputImMin.removeAttribute("style");
inputImMax.removeAttribute("style");
}
}
let rescaleOutputButton = document.getElementById('rescaleOutputPlotButton');
let outputRealMin = document.getElementById('MappedPlotRealMin');
let outputRealMax = document.getElementById('MappedPlotRealMax');
let outputImMin = document.getElementById('MappedPlotImMin');
let outputImMax = document.getElementById('MappedPlotImMax');
rescaleOutput = function() {
error = rescaleOutputPlot(Number(outputRealMin.value), Number(outputRealMax.value), Number(outputImMin.value), Number(outputImMax.value));
if(error) {
$(outputRealMin).popover('show').off('click');
$(outputRealMax).popover('show').off('click');
$(outputImMin).popover('show').off('click');
$(outputImMax).popover('show').off('click');
outputRealMin.setAttribute("style", "border-color:#ff0000; background-color:#ffdddd;");
outputRealMax.setAttribute("style", "border-color:#ff0000; background-color:#ffdddd;");
outputImMin.setAttribute("style", "border-color:#ff0000; background-color:#ffdddd;");
outputImMax.setAttribute("style", "border-color:#ff0000; background-color:#ffdddd;");
}
else {
$(outputRealMin).popover('destroy');
$(outputRealMax).popover('destroy');
$(outputImMin).popover('destroy');
$(outputImMax).popover('destroy');
outputRealMin.removeAttribute("style");
outputRealMax.removeAttribute("style");
outputImMin.removeAttribute("style");
outputImMax.removeAttribute("style");
}
}
</script>
</body>
</html>