Neural Outlet Mandelbrot SETL

Created by Neural Outlet
#!/usr/bin/sbcl --script

;; start Quicklisp
(let ((quicklisp-init (merge-pathnames "quicklisp/setup.lisp"
                                       (user-homedir-pathname))))
	(when (probe-file quicklisp-init)
		(load quicklisp-init)))

;; Load Common Qt
(ql:quickload 'qt)

;; Define package
(defpackage :mandelbrot
	(:use :cl :qt)
	(:export #:main))
(in-package :mandelbrot)
(named-readtables:in-readtable :qt)

(defclass mwindow ()
	((mandel :accessor mandel)
	 (mylab :accessor mylab))
	(:metaclass qt-class)
	(:qt-superclass "QWidget")
	(:override ("keyPressEvent" key-press-event)))

(defmethod initialize-instance :after ((instance mwindow) &key)
	(new instance)
	(let ((lay (#_new QGridLayout)) col)
		(setf (mylab instance) (#_new QLabel))
		(setf (mandel instance) (#_new QImage 500 500 (#_QImage::Format_ARGB32)))
		(setf col (#_QColor::fromRgb 0 255 0))
		(#_fill (mandel instance) (#_rgb col))
		(loop for x from 0 below 100
			do (#_setPixel (mandel instance) x 10 (#_rgb col)))

		(#_setPixmap (mylab instance) (#_QPixmap::fromImage (mandel instance)))

		(#_addWidget lay (mylab instance) 0 0 1 1)
		(#_setLayout instance lay)))

(defmethod draw-mandel ((instance mwindow) pixels)
	(let ((col (#_rgb (#_QColor::fromRgb 0 0 0))))
		(loop for (x y) in pixels
			do (#_setPixel (mandel instance) x y col))
		(#_setPixmap (mylab instance) (#_QPixmap::fromImage (mandel instance)))))

(defun strapp (str1 str2)
	(concatenate 'string str1 str2))

(defun parse-line (str)
	(let ((outstr ""))
		(loop for c across str
			do (cond
				((equal c #\[) (setf outstr (strapp outstr "(")))
				((equal c #\{) (setf outstr (strapp outstr "(")))
				((equal c #\]) (setf outstr (strapp outstr ")")))
				((equal c #\}) (setf outstr (strapp outstr ")")))
				(t (setf outstr (strapp outstr (string c))))))
		outstr))

;; The overloaded keyPressEvent
(defmethod key-press-event ((instance mwindow) event)
	(let (in-set)
		(if (equal (#_key event) (enum-value (#_Qt::Key_X)))
			(progn (setf in-set (read-from-string (parse-line
				(uiop:run-program "setl mandelbrot.setl -- -250 -250 250 8" :output :string))))

				(draw-mandel instance in-set)))))

;;; Main program
(let* ((app (make-qapplication))
       (window (make-instance 'mwindow)))

	(#_show window)

	(unwind-protect
		(#_exec app)
	(#_hide window)))
-----------------------------------------------------------------
-- Generating a list of co-ordinates inside the Mandelbrot Set --
-----------------------------------------------------------------

-- Get values from cmdline (for interaction with Lisp)
offset := [val(command_line(1)), val(command_line(2))];
scale := val(command_line(3));
iterations := val(command_line(4));

-- get a list of image co-ordinates inside the bound
-- box of -2 to 2 on both axis
image := [];
for x in [offset(1)..(offset(1)+500)] loop;
	for y in [offset(2)..(offset(2)+500)] loop;
		image +:= [[x/scale, y/scale]];
	end loop;
end loop;

-- Mandelbrot Set
M := {[(c(1)*scale)-offset(1),(c(2)*scale)-offset(2)] : c in image | forall num in {0..iterations} | cabs(pofc(c, num)) <= 2};
print(M);

---------------------------
--      Procedures       --
---------------------------

-- P(C) := z^2 + C
-- N iterations of P(C)
proc pofc(C, N);
	z := [0, 0];
	for x in [0..N] loop;
		z := ctimes(z, z);
		z(1) +:= C(1);
		z(2) +:= C(2);
	end loop;
	return z;
end proc;

-- Complex Operator: Multiplication
proc ctimes(compa, compb);
	outa := (compa(1) * compb(1)) - (compa(2) * compb(2));
	outb := (compa(2) * compb(1)) + (compa(1) * compb(2));
	return [outa, outb];
end proc;

-- Complex Operator: Absolute Value
proc cabs(comp);
	return sqrt((comp(1) ** 2) + (comp(2) ** 2));
end proc;

Comments (0)