Skip to content
Snippets Groups Projects
Commit ec281e35 authored by Finn Bear's avatar Finn Bear
Browse files

Improve fractal slide.

parent 4b6f553e
No related branches found
No related tags found
No related merge requests found
......@@ -9,7 +9,7 @@ use crate::color::set_alpha;
use crate::component::arrow::Arrow;
use crate::component::code::{pseudocode, Code};
use crate::component::grid::Grid;
use crate::egui::{Color32, Context, Frame, Ui};
use crate::egui::{Color32, Context, Frame, Pos2, Shape, Stroke, Ui};
use crate::fade_in::{fade_in_manual, fade_out_manual};
use crate::governor::Governor;
use crate::slide::s4_automata::randomize_grid;
......@@ -22,6 +22,8 @@ use crate::slide::s6_fractals::rectangle::rectangle;
use crate::slide::Slide;
use eframe::egui::style::Margin;
use eframe::egui::{Align2, Vec2};
use eframe::epaint::CircleShape;
use std::iter;
use std::ops::{Bound, RangeBounds};
/// Mandelbrot, etc.
......@@ -239,10 +241,7 @@ impl Slide for Fractals {
algo = Box::new(wrap_bool_algo(circle));
limit_pixels = Some(pixels);
}
FractalsState::Mandelbrot {
pixels,
traversal: _,
} => {
FractalsState::Mandelbrot { pixels, .. } => {
self.code.code = pseudocode(include_str!("s6_fractals/mandelbrot.rs"));
algo = Box::new(wrap_bool_algo(mandelbrot));
limit_pixels = Some(pixels);
......@@ -315,38 +314,87 @@ impl Slide for Fractals {
self.code.show(ui.ctx());
self.grid.show_with_overlays(ui.ctx(), |ui, to_screen| {
if let &FractalsState::Axes { fade_start } = &self.state {
fade_in_manual(ui, fade_start, |ui, alpha| {
let color = set_alpha(Color32::BLACK, alpha);
let middle = self.grid.size_cells / 2;
Arrow {
origin: to_screen * self.grid.center(middle, middle),
tip: to_screen * self.grid.center(self.grid.size_cells - 1, middle),
stroke: color,
label: "x".into(),
label_at_tip: true,
label_align: Some(Align2::CENTER_CENTER),
label_offset: Vec2::new(-20.0, 10.0),
stroke_width: 4.0,
font_size: 25.0,
..Arrow::default()
}
.show(ui);
Arrow {
origin: to_screen * self.grid.center(middle, middle),
tip: to_screen * self.grid.center(middle, 0),
stroke: color,
label: "y".into(),
label_at_tip: true,
label_align: Some(Align2::CENTER_CENTER),
label_offset: Vec2::new(-10.0, 20.0),
stroke_width: 4.0,
font_size: 25.0,
..Arrow::default()
match &self.state {
&FractalsState::Axes { fade_start } => {
fade_in_manual(ui, fade_start, |ui, alpha| {
let color = set_alpha(Color32::BLACK, alpha);
let middle = self.grid.size_cells / 2;
Arrow {
origin: to_screen * self.grid.center(middle, middle),
tip: to_screen * self.grid.center(self.grid.size_cells - 1, middle),
stroke: color,
label: "x".into(),
label_at_tip: true,
label_align: Some(Align2::CENTER_CENTER),
label_offset: Vec2::new(-20.0, 10.0),
stroke_width: 4.0,
font_size: 25.0,
..Arrow::default()
}
.show(ui);
Arrow {
origin: to_screen * self.grid.center(middle, middle),
tip: to_screen * self.grid.center(middle, 0),
stroke: color,
label: "y".into(),
label_at_tip: true,
label_align: Some(Align2::CENTER_CENTER),
label_offset: Vec2::new(-10.0, 20.0),
stroke_width: 4.0,
font_size: 25.0,
..Arrow::default()
}
.show(ui);
});
}
&FractalsState::Mandelbrot { traversal, .. } if traversal => {
//const TIME_SCALE: f64 = 0.4;
let mouse_position = ui.ctx().input().pointer.hover_pos();
if let Some(mouse_position) = mouse_position {
//let mut last_pos = Pos2::new(0.5 * (ui.ctx().input().time * TIME_SCALE).cos() as f32 - 1.0, 0.5 * (ui.ctx().input().time * TIME_SCALE).sin() as f32);
let mut last_pos = ((to_screen.inverse() * mouse_position).to_vec2() * 4.0
- Vec2::splat(2.0))
.to_pos2();
ui.painter().add(Shape::Circle(CircleShape {
center: to_screen
* ((last_pos.to_vec2() + Vec2::splat(2f32)) * 0.25).to_pos2(),
radius: 10.0,
fill: Color32::RED,
stroke: Stroke::default(),
}));
for pos in mandelbrot_iter(last_pos).take(5) {
Arrow {
origin: to_screen
* ((last_pos.to_vec2() + Vec2::splat(2f32)) * 0.25).to_pos2(),
tip: to_screen
* ((pos.to_vec2() + Vec2::splat(2f32)) * 0.25).to_pos2(),
stroke: Color32::LIGHT_BLUE,
stroke_width: 4.0,
..Arrow::default()
}
.show(ui);
last_pos = pos;
}
}
.show(ui);
});
}
_ => {}
}
});
}
}
/// Iterates points in a traversal of the mandelbrot set.
///
/// Never terminates, so caller is responsible for setting limits.
pub fn mandelbrot_iter(Pos2 { x, y }: Pos2) -> impl Iterator<Item = Pos2> + 'static {
let mut x1 = 0.0;
let mut y1 = 0.0;
// Rust iterator magic ;)
iter::repeat(()).map(move |_| {
let x_tmp = x1 * x1 - y1 * y1 + x;
y1 = 2.0 * x1 * y1 + y;
x1 = x_tmp;
Pos2::new(x1, y1)
})
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment