@@ -139,33 +139,179 @@ def construct(self):
139139
140140class Testing (ThreeDSlide ):
141141 def construct (self ):
142- axes = Axes (
143- x_range = [0.7 , 4 , 0.2 ],
144- y_range = [0 , 1 , 0.2 ],
145- axis_config = {"color" : BLUE },
146- )
147142
148- labels = axes .get_axis_labels (x_label = "r" , y_label = "x" )
149143
150- self .play (Create (axes ), Write (labels ))
144+ title = Tex (r"1. Objetivos" ).to_edge (UP + LEFT )
145+
146+
147+ axes_top = Axes (
148+ x_range = [0 , 4 , 1 ],
149+ y_range = [0 , 1 , 0.2 ],
150+ x_length = 5 ,
151+ y_length = 2.5 ,
152+ axis_config = {"color" : BLUE }
153+ )
154+ # Etiquetas
155+ labels_top = axes_top .get_axis_labels (x_label = "r" , y_label = "x" )
156+
157+ # Colocamos este grupo arriba en la pantalla
158+ bif_axes_group = VGroup (axes_top , labels_top ).to_edge (UP , buff = 1.5 )
151159
160+ # 2.2) Función logística
152161 def logistic_map (r , x ):
153162 return r * x * (1 - x )
154163
155- def bifurcation_diagram (r_values , iterations , last ):
156- x = np .random .rand (len (r_values ))
164+ # 2.3) Generador de puntos para el diagrama
165+ def bifurcation_diagram (r_values , iterations = 1000 , last = 100 ):
166+ """
167+ Devuelve (r, x) tras descartar transitorios.
168+ r_values: array de valores de 'r'
169+ iterations: número total de iteraciones
170+ last: cuántas iteraciones finales graficar
171+ """
172+ x = np .random .rand (len (r_values )) # condiciones iniciales aleatorias
157173 for i in range (iterations ):
158174 x = logistic_map (r_values , x )
159- if i >= (iterations - last ):
160- yield r_values , x
175+ # Sólo generamos puntos en las últimas 'last' iteraciones
176+ if i >= (iterations - last ):
177+ yield r_values , x
178+
179+ # 2.4) Creamos los puntos del diagrama
180+ r_values = np .linspace (0 , 4.0 , 1000 )
181+ bif_points = VGroup ()
182+ """ for r, x in bifurcation_diagram(r_values, iterations=1000, last=100):
183+ for i in range(len(r)):
184+ dot = Dot(
185+ axes_top.coords_to_point(r[i], x[i]),
186+ radius=0.008,
187+ color=WHITE
188+ )
189+ #bif_points.add(dot)
190+
191+ """
192+ # ------------------------------------------------
193+ # 3) Conjunto de Mandelbrot (abajo e invertido)
194+ # ------------------------------------------------
195+ # 3.1) Parámetros para el Mandelbrot
196+ RES = 50 # resolución
197+ MAX_ITER = 50 # iteraciones máximas
198+ XMIN , XMAX = - 2 , 1
199+ YMIN , YMAX = - 1.5 , 1.5
200+
201+ # Para dibujar "abajo", crearemos un VGroup y luego lo moveremos
202+ mandelbrot_group = VGroup ()
203+
204+ # 3.2) Generamos el fractal píxel a píxel
205+ # Definimos un ancho y alto en coordenadas Manim
206+ # (para luego ubicarlo centrado bajo el diagrama).
207+ fractal_width = 7
208+ fractal_height = 7
209+
210+ # Función para mapear (x, y) real a coordenadas de Manim
211+ # centradas, con el mismo ancho que "fractal_width" y alto "fractal_height".
212+ def mandelbrot_to_manim (px , py ):
213+ """
214+ px, py están en [XMIN, XMAX], [YMIN, YMAX].
215+ Devolvemos (X, Y) en la escena, centrados en (0,0) por debajo.
216+ """
217+ # Proporciones
218+ # 1) normalizamos px a [0,1] respecto a [XMIN, XMAX]
219+ nx = (px - XMIN ) / (XMAX - XMIN )
220+ ny = (py - YMIN ) / (YMAX - YMIN )
221+ # 2) escalamos al tamaño en la escena
222+ X = fractal_width * (nx - 0.5 ) # -0.5 para centrar en 0
223+ Y = fractal_height * (ny - 0.5 ) # -0.5 para centrar en 0
224+ return np .array ([X , Y , 0 ])
225+
226+ for i in range (RES ):
227+ for j in range (RES ):
228+ # Convertir (i, j) en coordenadas complejas c = x + i y
229+ x = XMIN + (XMAX - XMIN ) * i / (RES - 1 )
230+ y = YMIN + (YMAX - YMIN ) * j / (RES - 1 )
231+ c = complex (x , y )
232+
233+ # Iteramos z_{n+1} = z_n^2 + c
234+ z = 0
235+ iteration = 0
236+ while abs (z ) <= 2 and iteration < MAX_ITER :
237+ z = z * z + c
238+ iteration += 1
239+
240+ # Color según número de iteraciones (negro->blanco simple)
241+ color = interpolate_color (BLACK , WHITE , iteration / MAX_ITER )
242+
243+ # Representamos cada píxel con un cuadrado
244+ pixel = Square (
245+ side_length = (fractal_width / RES ),
246+ fill_opacity = 1 ,
247+ stroke_width = 0
248+ )
249+ pixel .set_fill (color )
250+ # Posicionarlo en la escena
251+ pixel .move_to (mandelbrot_to_manim (x , y ))
252+ mandelbrot_group .add (pixel )
253+
254+ # Invertimos verticalmente el mandelbrot
255+ # (flip en el eje UP equivaldría a "reflejar" sobre el eje horizontal)
256+ mandelbrot_group .flip (UP )
257+
258+ # Ahora lo desplazamos debajo del diagrama de bifurcación
259+ #mandelbrot_group.next_to(bif_axes_group, DOWN, buff=1.0)
260+
261+ # ------------------------------------------------
262+ # 4) Añadir líneas que conecten r (arriba) con c (abajo)
263+ # ------------------------------------------------
264+ # Supongamos un mapeo lineal: c(r) = -2 + 3r/4
265+ # => si r=0 -> c=-2, si r=4 -> c=1
266+ # Dibujamos líneas en r_line_values = [0,1,2,3,4], por ejemplo
267+ r_line_values = [1 , 3 , 3.45 , 3.85 ]
268+ lines_group = VGroup ()
269+
270+ for rv in r_line_values :
271+ # Coordenada X en el diagrama de bifurcación (arriba)
272+ top_x = axes_top .coords_to_point (rv , 1.0 ) # y=1 (para que baje desde "arriba")
273+ # Calculamos c
274+ c_val = - 2 + 3 * rv / 4.0
275+ # Lo llevamos al mandelbrot "invertido"
276+ # Tomamos y=0 (eje real) antes de la inversión
277+ # => (c_val, 0) en el plano del fractal
278+ # Convertimos a la posición en la escena con la misma función,
279+ # y luego aplicamos la inversión que ya hicimos con .flip(UP).
280+ # Para no complicarnos, simplemente localizamos el pixel en y=0:
281+ bottom_point_before_flip = mandelbrot_to_manim (c_val , 0 )
282+ # Como ya hemos hecho un flip vertical, la posición en la escena
283+ # es la misma. Solo necesitamos el SHIFT que le dimos a mandelbrot_group.
284+ # Extraemos la posición final sumando su center:
285+ bottom_x = bottom_point_before_flip + mandelbrot_group .get_center () - ORIGIN
286+
287+ # Creamos la línea
288+ line = DashedLine (
289+ start = top_x ,
290+ end = bottom_x ,
291+ dash_length = 0.05 ,
292+ color = YELLOW
293+ )
294+ lines_group .add (line )
161295
162- r_values = np .linspace (0.7 , 4.0 , 15000 )
163- points = VGroup ()
296+ # ------------------------------------------------
297+ # 5) Añadimos todo a la escena
298+ # ------------------------------------------------
299+ self .play (FadeIn (title ))
300+ self .wait (0.5 )
164301
165- for r , x in bifurcation_diagram (r_values , 1000 , 100 ):
166- for i in range (len (r )):
167- points .add (Dot (axes .coords_to_point (r [i ], x [i ]), radius = 0.01 , color = WHITE ))
302+ # Diagrama de bifurcación
303+ # self.play(FadeIn(bif_axes_group))
304+ # self.play(FadeIn(bif_points, lag_ratio=0.01), run_time=2)
305+ # self.wait(0.5)
168306
169- self .play (FadeIn (points , lag_ratio = 0.01 ), run_time = 2 )
170- self .wait ()
307+ mandelbrot_group .next_to (title , DOWN ).set_x (0 )
308+
309+ # Mandelbrot (invertido)
310+ self .play (FadeIn (mandelbrot_group , lag_ratio = 0.01 ), run_time = 2 )
311+ self .wait (0.5 )
312+
313+ # Líneas de conexión
314+ # self.play(Create(lines_group))
315+ # self.wait(2)
316+
171317
0 commit comments