#lang racket (require racket/flonum) ;; Receive width & height as command-line arguments: (define-values (WIDTH HEIGHT) (command-line #:args (width height) (values (string->number width) (string->number height)))) ;; Instead of using fractions, we stick to integers ;; implicitly divided by FSCALE, just like the Jam2000 ;; version: (define FSCALE 1000) (define LIMIT-SQR (* 4 FSCALE)) (define ITERATIONS 50) ;; Per-pixel computation: (define (mandelbrot Cr Ci i Zr Zi) (cond [(> (quotient (+ (* Zr Zr) (* Zi Zi)) FSCALE) LIMIT-SQR) 0] [(= i ITERATIONS) 1] [else (define new-Zr (+ (quotient (- (* Zr Zr) (* Zi Zi)) FSCALE) Cr)) (define new-Zi (+ (* 2 (quotient (* Zr Zi) FSCALE)) Ci)) (mandelbrot Cr Ci (+ i 1) new-Zr new-Zi)])) ;; Make a vector of vectors to hold the image: (define vecs (for/vector ([y HEIGHT]) (for/vector ([x WIDTH]) 0))) ;; Fill in the image: (time (for ([y (in-range 0 HEIGHT)]) (define Ci (- (quotient (* 2 y FSCALE) HEIGHT) FSCALE)) (define vec (vector-ref vecs y)) (for ([x (in-range 0 WIDTH)]) (define Cr (- (quotient (* 2 x FSCALE) WIDTH) (* 3/2 FSCALE))) (define px (mandelbrot Cr Ci 0 0 0)) (vector-set! vec x px)))) ;; Write out the image as a PBM file: (define o (open-output-file "mb.pbm" #:exists 'truncate)) (fprintf o "P1\n~a ~a\n" WIDTH HEIGHT) (for ([y HEIGHT]) (define vec (vector-ref vecs y)) (for ([x WIDTH]) (display (vector-ref vec x) o) (display " " o)) (newline o))