Drawing and scripting
This is a demo of the libraries (lispkit draw)
and
(lisppad system macos)
. Function plot
draws a graph of a
function for a given range using a number of interpolation points. Function show-graph-plot
shows a
plotted drawing in a graphics window.
Usage:
(show-graph-plot sin -1 6.5 50 "sin(x)")
(show-graph-plot (lambda (x) (* (sin (* x 2)) (cos (/ x 4)))) -1 6.5 50 "sin+cos")
(import (lispkit base)
(lispkit draw)
(lisppad system macos))
;; Plots a function `f` over range `[xmin; xmax]` using `n` interpolation points
;; within rectangle `rect`. Prints `label` at the bottom of the graph. Returns the result
;; as a drawing object.
(define (plot f xmin xmax n rect)
(let* ((dx (/ (- xmax xmin) n))
(xs (tabulate (fx1+ n) (lambda (i) (+ xmin (* i dx)))))
(ys (map f xs))
(ymin (apply min ys))
(ymax (apply max ys))
(xfac (/ (rect-width rect) (- xmax xmin)))
(yfac (/ (rect-height rect) (- ymax ymin)))
(ps (map (lambda (x y) (point (* xfac (- x xmin)) (* yfac (- y ymin)))) xs ys))
(graph (flip-shape (interpolate ps))))
(drawing
; Draw a bounding box
(draw (rectangle (rect-point rect) (rect-size rect)) 1.0)
; Move rest of drawing into the bounding box
(transform (translate (rect-x rect) (rect-y rect))
; Draw the coordinate axis
(set-color (color 0.3 0.3 0.3))
(if (and (<= xmin 0.0) (>= xmax 0.0))
(draw (line (point (* xfac (- xmin)) 0)
(point (* xfac (- xmin)) (rect-height rect))) 0.5))
(if (and (<= ymin 0.0) (>= ymax 0.0))
(draw (line (point 0 (+ (rect-height rect) (* yfac ymin)))
(point (rect-width rect) (+ (rect-height rect) (* yfac ymin)))) 0.5))
; Draw flipped interpolation shape
(set-color blue)
(draw graph 1.5)
; Draw interpolation points
(set-fill-color white)
(for-each (lambda (p)
(let ((s (flip-shape (circle p 2.5) (shape-bounds graph))))
(fill s) (draw s 1.0))) ps)))))
;; Creates a demo page consisting of a header and four graphs
(define (show-graph-plot f xmin xmax n title)
(let* ((graph (drawing
(draw-text "Demo of libraries (lispkit draw) and (lisppad system macos)"
(point 110 16)
(font "Times-Bold" 16)
black)
(draw-drawing (plot f xmin xmax n (rect 20 50 510 330)))))
(window (use-graphics-window graph (size 550 400) title #f (size 550 445))))
(set-graphics-window-label! window "© 2018 Matthias Zenger")
window))