fn draw_mandelbrot(canvas: &DrawingTarget, layer: LayerId, texture: TextureId, (min, max): (Complex<f64>, Complex<f64>), width: u32, height: u32, alpha: &BindRef<f32>, update_num: &BindRef<u64>) {
    // Create a vector for the pixels in the mandelbrot set
    let mut pixels  = vec![0u8; (width*height*4) as usize];
    let mut pos     = 0;
    let update      = update_num.get();

    let mut start_time = Instant::now();

    // Work out how many iterations to perform
    let scale_factor_x  = 3.5/(max.re - min.re).abs();
    let scale_factor_y  = 2.0/(max.im - min.im).abs();
    let scale_factor    = f64::max(scale_factor_x, scale_factor_y);
    let scale_factor    = scale_factor.round();

    let num_cycles = if scale_factor < 64.0 {
        256
    } else if scale_factor < 2048.0 {
        1024
    } else if scale_factor < 8192.0 {
        2048
    } else {
        4096
    };

    // Render each pixel in turn
    for y in 0..height {
        let y = y as f64;
        let y = y / (height as f64);
        let y = (max.im - min.im) * y + min.im;

        for x in 0..width {
            let x = x as f64;
            let x = x / (width as f64);
            let x = (max.re - min.re) * x + min.re;

            let c               = Complex::new(x, y);
            let cycles          = count_cycles(c, num_cycles);
            let (r, g, b, a)    = color_for_cycles(cycles);

            pixels[pos+0]       = r;
            pixels[pos+1]       = g;
            pixels[pos+2]       = b;
            pixels[pos+3]       = a;

            pos                 += 4;
        }

        // Stop if there's an update to the state we're rendering
        if update_num.get() != update {
            return;
        }

        // Draw the story so far every 50ms
        if Instant::now().duration_since(start_time) > Duration::from_millis(50) {
            let intermediate_pixels = Arc::new(pixels.clone());
            canvas.draw(move |gc| {
                gc.layer(layer);
                gc.clear_layer();
                gc.create_texture(texture, width, height, TextureFormat::Rgba);
                gc.set_texture_bytes(texture, 0, 0, width, height, intermediate_pixels);
                gc.set_texture_fill_alpha(texture, alpha.get());

                gc.canvas_height(height as _);
                gc.center_region(0.0, 0.0, width as _, height as _);

                gc.new_path();
                gc.rect(0.0, 0.0, width as _, height as _);
                gc.fill_texture(texture, 0.0, 0.0, width as _, height as _);
                gc.fill();
            });

            start_time = Instant::now();
        }
    }

    // Draw to the texture
    canvas.draw(move |gc| {
        gc.create_texture(texture, width, height, TextureFormat::Rgba);
        gc.set_texture_bytes(texture, 0, 0, width, height, Arc::new(pixels));

        gc.layer(layer);
        gc.clear_layer();
        gc.set_texture_fill_alpha(texture, alpha.get());

        gc.canvas_height(height as _);
        gc.center_region(0.0, 0.0, width as _, height as _);

        gc.new_path();
        gc.rect(0.0, 0.0, width as _, height as _);
        gc.fill_texture(texture, 0.0, 0.0, width as _, height as _);
        gc.fill();
    });
}
///
/// Draws the mandelbrot set within a specified set of bounds
///
Draws the mandelbrot set within a specified set of bounds
Draws the mandelbrot set within a specified set of bounds
fn draw_mandelbrot(canvas: &DrawingTarget, layer: LayerId, texture: TextureId, (min, max): (Complex<f64>, Complex<f64>), width: u32, height: u32, alpha: &BindRef<f32>, update_num: &BindRef<u64>) {
    // Create a vector for the pixels in the mandelbrot set
    let mut pixels  = vec![0u8; (width*height*4) as usize];
    let mut pos     = 0;
    let update      = update_num.get();
    let mut start_time = Instant::now();
    // Work out how many iterations to perform
    let scale_factor_x  = 3.5/(max.re - min.re).abs();
    let scale_factor_y  = 2.0/(max.im - min.im).abs();
    let scale_factor    = f64::max(scale_factor_x, scale_factor_y);
    let scale_factor    = scale_factor.round();
    let num_cycles = if scale_factor < 64.0 {
        256
    } else if scale_factor < 2048.0 {
        1024
    } else if scale_factor < 8192.0 {
        2048
    } else {
        4096
    };
    // Render each pixel in turn
    for y in 0..height {
        let y = y as f64;
        let y = y / (height as f64);
        let y = (max.im - min.im) * y + min.im;
        for x in 0..width {
            let x = x as f64;
            let x = x / (width as f64);
            let x = (max.re - min.re) * x + min.re;
            let c               = Complex::new(x, y);
            let cycles          = count_cycles(c, num_cycles);
            let (r, g, b, a)    = color_for_cycles(cycles);
            pixels[pos+0]       = r;
            pixels[pos+1]       = g;
            pixels[pos+2]       = b;
            pixels[pos+3]       = a;
            pos                 += 4;
        }
        // Stop if there's an update to the state we're rendering
        if update_num.get() != update {
            return;
        }
        // Draw the story so far every 50ms
        if Instant::now().duration_since(start_time) > Duration::from_millis(50) {
            let intermediate_pixels = Arc::new(pixels.clone());
            canvas.draw(move |gc| {
                gc.layer(layer);
                gc.clear_layer();
                gc.create_texture(texture, width, height, TextureFormat::Rgba);
                gc.set_texture_bytes(texture, 0, 0, width, height, intermediate_pixels);
                gc.set_texture_fill_alpha(texture, alpha.get());
                gc.canvas_height(height as _);
                gc.center_region(0.0, 0.0, width as _, height as _);
                gc.new_path();
                gc.rect(0.0, 0.0, width as _, height as _);
                gc.fill_texture(texture, 0.0, 0.0, width as _, height as _);
                gc.fill();
            });
            start_time = Instant::now();
        }
    }
    // Draw to the texture
    canvas.draw(move |gc| {
        gc.create_texture(texture, width, height, TextureFormat::Rgba);
        gc.set_texture_bytes(texture, 0, 0, width, height, Arc::new(pixels));
        gc.layer(layer);
        gc.clear_layer();
        gc.set_texture_fill_alpha(texture, alpha.get());
        gc.canvas_height(height as _);
        gc.center_region(0.0, 0.0, width as _, height as _);
        gc.new_path();
        gc.rect(0.0, 0.0, width as _, height as _);
        gc.fill_texture(texture, 0.0, 0.0, width as _, height as _);
        gc.fill();
    });
}
fn draw_mandelbrot ( canvas : & DrawingTarget , layer : LayerId , texture : TextureId , ( min , max ) : ( Complex < f64 > , Complex < f64 > ) , width : u32 , height : u32 , alpha : & BindRef < f32 > , update_num : & BindRef < u64 > ) { // Create a vector for the pixels in the mandelbrot set let mut pixels = vec ! [ 0u8 ( width height 4 ) as usize ] ; let mut pos = 0 ; let update = update_num . get ( ) ; let mut start_time = Instant :: now ( ) ; // Work out how many iterations to perform let scale_factor_x = 3.5 / ( max . re - min . re ) . abs ( ) ; let scale_factor_y = 2.0 / ( max . im - min . im ) . abs ( ) ; let scale_factor = f64 :: max ( scale_factor_x , scale_factor_y ) ; let scale_factor = scale_factor . round ( ) ; let num_cycles = if scale_factor < 64.0 { 256 } else if scale_factor < 2048.0 { 1024 } else if scale_factor < 8192.0 { 2048 } else { 4096 } ; // Render each pixel in turn for y in 0 .. height { let y = y as f64 ; let y = y / ( height as f64 ) ; let y = ( max . im - min . im ) * y + min . im ; for x in 0 .. width { let x = x as f64 ; let x = x / ( width as f64 ) ; let x = ( max . re - min . re ) * x + min . re ; let c = Complex :: new ( x , y ) ; let cycles = count_cycles ( c , num_cycles ) ; let ( r , g , b , a ) = color_for_cycles ( cycles ) ; pixels [ pos + 0 ] = r ; pixels [ pos + 1 ] = g ; pixels [ pos + 2 ] = b ; pixels [ pos + 3 ] = a ; pos += 4 ; } // Stop if there's an update to the state we're rendering if update_num . get ( ) != update { return ; } // Draw the story so far every 50ms if Instant :: now ( ) . duration_since ( start_time ) > Duration :: from_millis ( 50 ) { let intermediate_pixels = Arc :: new ( pixels . clone ( ) ) ; canvas . draw ( move | gc | { gc . layer ( layer ) ; gc . clear_layer ( ) ; gc . create_texture ( texture , width , height , TextureFormat :: Rgba ) ; gc . set_texture_bytes ( texture , 0 , 0 , width , height , intermediate_pixels ) ; gc . set_texture_fill_alpha ( texture , alpha . get ( ) ) ; gc . canvas_height ( height as _ ) ; gc . center_region ( 0.0 , 0.0 , width as _ , height as _ ) ; gc . new_path ( ) ; gc . rect ( 0.0 , 0.0 , width as _ , height as _ ) ; gc . fill_texture ( texture , 0.0 , 0.0 , width as _ , height as _ ) ; gc . fill ( ) ; } ) ; start_time = Instant :: now ( ) ; } } // Draw to the texture canvas . draw ( move | gc | { gc . create_texture ( texture , width , height , TextureFormat :: Rgba ) ; gc . set_texture_bytes ( texture , 0 , 0 , width , height , Arc :: new ( pixels ) ) ; gc . layer ( layer ) ; gc . clear_layer ( ) ; gc . set_texture_fill_alpha ( texture , alpha . get ( ) ) ; gc . canvas_height ( height as _ ) ; gc . center_region ( 0.0 , 0.0 , width as _ , height as _ ) ; gc . new_path ( ) ; gc . rect ( 0.0 , 0.0 , width as _ , height as _ ) ; gc . fill_texture ( texture , 0.0 , 0.0 , width as _ , height as _ ) ; gc . fill ( ) ; } ) ; }
Draws the mandelbrot set within a specified set of bounds
Draws the mandelbrot set within a specified set of bounds
canvas
&DrawingTarget
layer
LayerId
texture
(Complex<f64>, Complex<f64>)
width
u32
height
u32
alpha
&BindRef<f32>
update_num
&BindRef<u64>