;;;See if clx works even a little (require 'asdf) (eval-when (:compile-toplevel :load-toplevel :execute) (asdf:oos 'asdf:load-op :clx) ) (defpackage :xapp (:use :common-lisp :xlib) (:export :main)) (in-package :xapp) (defun |x,f(x)| (points x-min x-max f) "Call f repeatly to build an array tabulating f from x-min to x-max inclusive. Uses CLX representation so array is twice as long as the number of points evaluated" (let ((a (make-array (* 2 points)))) (dotimes (index points) (let ((x (+ x-min (/ (* (- x-max x-min) index) (- points 1))))) (setf (aref a (* 2 index)) x (aref a (+ (* 2 index ) 1)) (funcall f x)))) a)) (defun |x(t),y(t)| (points t-min t-max x y) (let ((a (make-array (* 2 points)))) (dotimes (index points) (let ((tau (+ t-min (/ (* (- t-max t-min) index) (- points 1))))) (setf (aref a (* 2 index)) (funcall x tau) (aref a (+ (* 2 index ) 1)) (funcall y tau)))) a)) (defun |z(t)| (points t-min t-max z) (let ((a (make-array (* 2 points)))) (dotimes (index points) (let ((z (funcall z (+ t-min (/ (* (- t-max t-min) index) (- points 1)))))) (setf (aref a (* 2 index)) (realpart z) (aref a (+ (* 2 index) 1)) (imagpart z)))) a)) (defun cycloid(loop1 size1 loop2 size2) #'(lambda(x)(+ (* size1 (exp (* (complex 0f0 loop1) x))) (* size2 (exp (* (complex 0f0 loop2) x)))))) (defun bound-xy-vec(xys) (do ((index 0 (+ index 2)) (x-min (aref xys 0) (min x-min (aref xys index))) (x-max (aref xys 0) (max x-max (aref xys index))) (y-min (aref xys 1) (min y-min (aref xys (+ index 1)))) (y-max (aref xys 1) (max y-max (aref xys (+ index 1))))) ((>= index (length xys)) (values x-min x-max y-min y-max)))) (defun fit-xy-to-window (xy-vec width height) (let ((a (make-array (length xy-vec)))) (multiple-value-bind (x-min x-max y-min y-max) (bound-xy-vec xy-vec) (loop for i from 0 below (length xy-vec) do (setf (aref a i) (if (evenp i) (round (* width (- (aref xy-vec i) x-min)) (- x-max x-min)) (round (* height (- y-max (aref xy-vec i))) (- y-max y-min))))) a))) (defun normalised-graph(points width height) (single-graph (fit-xy-to-window points width height) width height)) (defun single-graph (points width height &optional (host "")) (let* ((display (xlib:open-display host)) (screen (first (xlib:display-roots display))) (black (xlib:screen-black-pixel screen)) (white (xlib:screen-white-pixel screen)) (root-window (xlib:screen-root screen)) (grackon (xlib:create-gcontext :drawable root-window :foreground white :background black)) (my-window (xlib:create-window :parent root-window :x 0 :y 0 :width width :height height :background black :event-mask (xlib:make-event-mask :exposure :button-press)))) (describe grackon) (xlib:map-window my-window) (xlib:event-case (display :force-output-p t :discard-p t) (:exposure () (xlib:draw-lines my-window grackon points) nil) (:button-press () t)) (xlib:destroy-window my-window) (xlib:close-display display))) (defun main () (progn (single-graph #(0 0 100 100 200 300 300 0) 400 400) #| (normalised-graph #(0 0 100 100 200 300 300 0) 400 400) (normalised-graph (|x,f(x)| 100 (- pi) (* 3 pi) #'sin) 400 200) (normalised-graph (|x,f(x)| 100 -3 3 #'(lambda(x)(* x x))) 400 400) (normalised-graph (|x(t),y(t)| 100 0 (* 2 pi) #'cos #'sin) 400 400) (normalised-graph (|x(t),y(t)| 100 0 (* 2 pi) #'(lambda(x)(sin (* 2 x))) #'sin) 400 400) (normalised-graph (|z(t)| 100 0 (* 2 pi) #'(lambda(theta)(exp (* #c(0 1) theta)))) 400 400) (normalised-graph (|z(t)| 100 0 (* 3 pi) #'(lambda(theta) (+ theta (exp (* #c(0 1) (- (* 3/2 pi) theta)))))) 800 200) (normalised-graph (|z(t)| 1000 0 (* 2 pi) (cycloid 3 10 13 5)) 400 400) |# ) ;;End progn )