-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy path2D-fractals.html
274 lines (255 loc) · 18.4 KB
/
2D-fractals.html
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
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
<!DOCTYPE html>
<html lang="es">
<head>
<title>Fractales 2D</title>
<!-- Código para la visualización de fractales -->
<script type="module" src="static/js/fractals-2D.js"></script>
<!-- jQuery -->
<script type="text/javascript" src="static/js/jquery-3.6.0.min.js"></script>
<!-- Bootstrap -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-pprn3073KE6tl6bjs2QrFaJGz5/SUsLqktiwsUTF55Jfv3qYSDhgCecCxMW52nD2" crossorigin="anonymous"></script>
<!-- Botones para RRSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<!-- MathJax para las expresiones matemáticas -->
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
<!-- CSS propio -->
<link rel="stylesheet" href="static/css/hover-style.css">
<!-- Meta -->
<meta charset="UTF-8">
<meta name="application-name" content="Visualización de fractales">
<meta name="author" content="Juan Antonio Villegas Recio">
<meta name="description" content="Visualización de fractales en 2 dimensiones">
<link rel="icon" href="static/img/logo.png">
</head>
<body>
<!--
-- ─── CABECERA ────────────────────────────────────────────────────
-->
<header class="row d-flex flex-wrap justify-content-around py-3 mb-4 border-bottom w-100 p-3">
<a href="index.html" class="d-flex align-items-center justify-content-center mb-3 mb-md-0 me-md-auto text-dark text-decoration-none col-xl-6">
<img src="static/img/logo.png" id="logo">
<span class="fs-4"><h1>Visualización de Fractales 2D</h1></span>
</a>
<ul class="nav nav-pills col-xl-6 justify-content-center">
<li class="nav-item"><a href="./index.html"><button class="btn-change">Home</button></a></li>
<li class="nav-item"><a href="./2D-fractals.html"><button class="btn-change">Fractales 2D</button></a></li>
<li class="nav-item"><a href="./3D-fractals.html"><button class="btn-change">Fractales 3D</button></a></li>
</ul>
</header>
<!--
-- ─── CONTENIDO ───────────────────────────────────────────────────
-->
<main class="container-xl">
<section class="row">
<!-- WEBGL CANVAS -->
<div class="col-lg-8" id="canvas-wapper">
<canvas class="container-fluid" id="glCanvas" width="1280" height="720"></canvas>
<div class="row justify-content-center">
<button type="button" class="btn-change col-4" id="botonReset">Reset</button>
</div>
</div>
<!-- PANEL DE CONTROL -->
<aside class="col-lg-4">
<div class="accordion" id="accordionPanelsStayOpenExample">
<div class="accordion-item">
<h2 class="accordion-header" id="headingOne">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
<span class="fs-5 text">Parámetros del fractal</span>
</button>
</h2>
<div id="collapseOne" class="accordion-collapse collapse show" aria-labelledby="headingOne" data-bs-parent="#accordionExample">
<div class="accordion-body">
<div class="row">
<b class="col-6">¿Qué fractal quieres ver?</b>
<div class="col-6">
<select class="form-select form-select-sm mb-3" aria-label=".form-select-lg example" id="fractales">
<option value="0">Mandelbrot</option>
<option value="1">Julia</option>
</select>
</div>
</div>
<div id="constanteJulia">
<b>Constante del Conjunto de Julia</b> \(c = x + i\cdot y\)
<div class="container" id="deslizadorJuliaX">
<div class="row align-items-center justify-content-between">
<b class="col-2">x:</b>
<input class="col-5" id="juliaX" type="range" min="-2" max="2" step="0.01">
<input type="number" class="col-3" id="valorJuliaX" min="-2" max="2" step="0.01"></input>
</div>
</div>
<div class="container" id="deslizadorJuliaY">
<div class="row align-items-center justify-content-between">
<b class="col-2">y:</b>
<input class="col-5" id="juliaY" type="range" min="-2" max="2" step="0.01">
<input type="number" class="col-3" id="valorJuliaY" min="-2" max="2" step="0.01"></input>
</div>
</div>
</div>
<br>
<b>Exponente \(m\) de la función</b> \(P_{c,m}(z) = z^m + c\)
<div class="container" id="deslizadorExponente">
<div class="row align-items-center justify-content-between">
<b class="col-2">m:</b>
<input class="col-5" id="exponente" type="range" min="1" max="10" step="1">
<input type="number" class="col-3" id="valorExponente" min="1" max="10" step="1"></input>
</div>
</div>
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header" id="panelsStayOpen-headingTwo">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#panelsStayOpen-collapseTwo" aria-expanded="false" aria-controls="panelsStayOpen-collapseTwo">
<span class="fs-5 text">Algoritmo de visualización</span>
</button>
</h2>
<div id="panelsStayOpen-collapseTwo" class="accordion-collapse collapse" aria-labelledby="panelsStayOpen-headingTwo">
<div class="accordion-body">
<h5>Región del plano visualizada</h5>
<b>Esquina inferior izquierda:</b>
<div class="row justify-content-around align-items-center">
<input class="col-3" id="LLCX" type="number" min="-10" max="10" step="0.1">
<input class="col-3" id="LLCY" type="number" min="-10" max="10" step="0.1">
<div class="col-4">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="LLCFixed">
<label class="form-check-label" for="LLCFixed">Fijo</label>
</div>
</div>
</div>
<br>
<b>Esquina superior derecha:</b>
<div class="row justify-content-around align-items-center">
<input class="col-3" id="URCX" type="number" min="-10" max="10" step="0.1">
<input class="col-3" id="URCY" type="number" min="-10" max="10" step="0.1">
<div class="col-4">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="URCFixed">
<label class="form-check-label" for="URCFixed">Fijo</label>
</div>
</div>
</div><br>
<h5>Máximo de iteraciones \(M\)</h5>
<div class="container" id="numIteraciones">
<div class="row align-items-center justify-content-between">
<b class="col-5">Número de iteraciones:</b>
<input class="col-4" id="nIteraciones" type="range" min="10" max="1000" step="5">
<input type="number" class="col-3" id="valorNIteraciones" min="10" max="1000" step="5"></input>
</div>
</div>
<h5>Supersampling Antialiasing</h5>
<div class="form-check form-switch" style="padding-left: 5.5em;">
<input class="form-check-input" type="checkbox" id="antialiasing">
<label class="form-check-label" for="antialiasing">Activar/desactivar</label>
</div>
<div class="container" id="deslizadorNSamples">
<div class="row align-items-center justify-content-between">
<b class="col-6">Muestras por píxel:</b>
<input class="col-4" id="nSamples" type="range" min="1" max="4" step="1">
<div class="col-2" id="valorNSamples"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</aside>
</section>
<!-- AYUDA -->
<section class="container">
<h2>Controles:</h2>
<ul>
<li>Teclas +/-: Ampliar o reducir el zoom</li>
<li>Flechas: Desplazarse por el plano</li>
</ul>
<h2 id="ayuda2D">Ayuda</h2>
<p>
En los siguientes párrafos se explica de forma intuitiva el significado y el efecto provocado por cada uno de los parámetros modificables. Previamente, introducimos unas pequeñas nociones sobre cómo se grafican los conjuntos de Julia y Mandelbrot.
</p>
<p>
Partimos de la familia de funciones complejas \(P_{c,m}(z)=z^m + c\), siendo \(c\in\mathbb C\) un número complejo. A su vez, identificamos la pantalla con una región del plano complejo, asociando cada píxel de la pantalla a un número complejo. Para visualizar un conjunto de Julia, fijamos un número complejo \(c\in\mathbb C\), de forma que hay tantos conjuntos de Julia como números complejos, aunque los más interesantes son aquellos asociados a constantes \(c\) con módulo pequeño. Denotamos \(\mathcal J_{c,m}\) al conjunto de Julia asociado al complejo \(c\).
</p>
<p>
Así, para cada punto \(z_0\in\mathbb C\) (es decir, para cada píxel) calculamos la sucesión de iteradas \(z_0, P_{c,m}(z_0), P_{c,m}(P_{c,m}(z_0)),\dots\) Es decir, la sucesión \(z_0, z_0^m + c, (z_0^m + c)^m +c, \dots\) Si esta sucesión no diverge después de un número máximo de iteraciones que llamamos \(M\), se colorea el píxel asociado a \(z_0\) de negro. Si después de \(M\) iteraciones la sucesión diverge (un término de la sucesión es grande), se colorea de algún color.
</p>
<p>
De forma similar, para graficar el conjunto de Mandelbrot, \(\mathcal M_m\), tomamos \(z_0=0\) como primer término y para cada complejo \(c\in\mathbb C\) (es decir, para cada píxel) se calculan las iteradas \(0, P_{c,m}(0), P_{c,m}(P_{c,m}(0)),\dots\), es decir, \(0, c, c^m +c,\dots\) Si esta sucesión no diverge después de un número máximo de iteraciones que llamamos \(M\), se colorea el píxel asociado a \(c\) de negro. Si después de \(M\) iteraciones la sucesión diverge (un término de la sucesión es grande), se colorea de algún color.
</p>
<p>
Tras esta introducción, presentamos el significado de cada parámetro:
</p>
<h3>Botón 'Reset'</h3>
<p>
Al pulsarlo se restablecen los parámetros a los iniciales, es decir, los que había al cargar la página por primera vez.
</p>
<h3 id="ayuda-fractal">Parámetros del fractal</h3>
<p>
Estos parámetros definen qué conjunto de Julia o Mandelbrot se visualiza. Podemos elegir entre qué conjuntos ver, si Julia o Mandelbrot, y en el caso de elegir que deseamos ver conjuntos de Julia, elegir qué constante \(c=x+i\cdot y\) fijar, pudiendo elegir la coordenada \(x\) y la coordenada \(y\). Ambos valores se permite que estén en el intervalo \([-2,2]\) por que fuera de esta región los conjuntos de Julia carecen de interés. También se puede elegir qué exponente \(m\) se fija en la función \(P_{c_m}(z)=z^{\mathbf m}+c\)
</p>
<p>
Se recomienda variar los exponentes y visualizar el conjunto de Mandelbrot estándar \(\mathcal M\) correspondiente a \(m=2\) y sus generalizaciones a órdenes superiores \(\mathcal M_m\), o seleccionar conjuntos de Julia y variar los deslizadores de \(x\) e \(y\) e ir viendo cómo cambian los conjuntos de Julia al variar la constante \(c\)
</p>
<h3>Algoritmo de visualización</h3>
<p>
En esta sección se pueden variar los parámetros relacionados no tanto con el fractal que estemos visualizando sino con el algoritmo utilizado para graficarlo y la calidad de la imagen. Está subdividida a su vez en varios subapartados.
</p>
<h4 id="ayuda-region-plano">Región del plano visualizada</h4>
<p>
Definimos dos números complejos a los cuales llamaremos \(\mathrm{LLC}\) (Lower Left Corner) y \(\mathrm{URC}\) (Upper Right Corner) como los números complejos que se identifican con los puntos situados en la esquina inferior izquierda y la esquina superior derecha de la región del plano que se visualiza en la pantalla. Estos valores son modificables, de forma que nos permiten movernos libremente por el plano complejo y fijar una de las dos y cambiar la otra, pudiendo así mostrar la región del plano que deseemos (siempre que se mantengan la proporción 16:9). Estos parámetros representan una alternativa al uso de las flechas y las teclas '+/-' para movernos por la región del plano.
</p>
<h4>Máximo número de iteraciones \(M\)</h4>
<p>
Valor de \(M\), es decir, el número máximo de iteraciones que se dan antes de decidir si las sucesiones convergen o divergen. A mayor número, mayor coste computacional pero mayor precisión en la representación.
</p>
<p>
Se recomienda ampliar alguna región del plano (con la tecla '+' y las flechas o con los parámetros de la <a href="#ayuda-region-plano" class="text-primary">región del plano visualizada</a>) y aumentar este parámetro para observar cómo mejora la resolución.
</p>
<p>
<strong>CUIDADO:</strong> Un número alto de iteraciones por píxel aumenta considerablemente el coste computacional, por lo que no recomendamos abusar de la interactividad si no se dispone de una gráfica suficientemente buena.
</p>
<h4>Supersampling Antialiasing</h4>
<p>
Anteriormente hemos mencionado que se identifica cada píxel con un único punto del plano, pero esto suele provocar calidades bajas y bordes bruscos. Con este parámetro se permite identificar cada píxel con \(n^2\) puntos, calcular el color asociado a cada punto y finalmente asignar al píxel el color promedio. De esta forma se visualizan los bordes más suavizados y se obtienen imágenes de mayor calidad. Esta técnica se conoce como Supersampling Antialiasing (SSAA).
</p>
<p>
Recomendamos ampliar una región del plano, aumentar el número de iteraciones \(M\) y posteriormente activar el antialiasing y aumentar el número de puntos por píxel. En esta situación, puede activar y desactivar el parámetro y observar cómo cambia la imagen.
</p>
<p>
<strong>CUIDADO:</strong> Esta operación es considerablemente más costosa que el visualizado estándar, por lo que recomendamos no abusar de la interactividad con un número alto de puntos por píxel si no se dispone de una gráfica suficientemente buena.
</p>
<div class="row align-items-center">
<img class="col-3" style="width: 70px;" src="static/img/warning.png">
<h2 class="col-9">ADVERTENCIA</h2>
</div>
<p>
Como se ha mencionado anteriormente, es posible que su dispositivo no soporte interactividad de forma fluida con un número alto de iteraciones y aplicando SSAA con un número elevado de muestras por píxel. Recomendamos por ello que si se utilizan valores altos, se desplace por el plano con pequeños incrementos, evitando mantener las teclas pulsadas.
</p>
<p>
En caso de que la web se sobrecargue, es posible que se ponga en blanco la pantalla. En este caso debe ser suficiente una simple recarga de la página para solucionarlo, aunque en ciertos casos puede ser necesario reiniciar el navegador.
</p>
</section>
</main>
<!--
-- ─── PIE DE PAGINA ───────────────────────────────────────────────
-->
<footer class="d-flex flex-wrap justify-content-between align-items-center py-3 my-4 border-top">
<div class="col-md-4 d-flex align-items-center">
<a href="index.html" class="mb-3 me-2 mb-md-0 text-muted text-decoration-none lh-1">
<img src="static/img/logo.png" id="logo">
</a>
</div>
<div class="col-md-4 d-flex align-items-center justify-content-center">
<span class="mb-3 mb-md-0 text-muted">© 2022, Juan Antonio Villegas Recio</span>
</div>
<ul class="nav col-md-4 justify-content-end list-unstyled d-flex">
<li class="ms-3"><a href="https://github.com/JAntonioVR" class="fa fa-github"></a></li>
<li class="ms-3"><a href="https://www.linkedin.com/in/juan-antonio-villegas-recio/" class="fa fa-linkedin"></a></li>
<li class="ms-3"><a href="https://www.instagram.com/juanantonio_79/" class="fa fa-instagram"></a></li>
<li class="ms-3"><a href="https://www.facebook.com/profile.php?id=100010525867626" class="fa fa-facebook"></a></li>
<li class="ms-3"><a href="mailto:juanantoniovr98@gmail.com" class="fa fa-google"></a></li>
</ul>
</footer>
</body>
</html>