dragoncoder047’s blog

random thoughts about nonrandom things

Lisp Practice

← Previous: uLisp Thoughts Next: ParTcl
Posted
By dragoncoder047

Today I decided I would have a little fun with Lisp. I wanted to try and make a program that you can type in a function and get a graph of it.

I started off with a function that takes an xx-value and a list of coefficients, and evaluates the polynomial defined by those coefficients. Here’s the function:

(defun poly (x a)
    (let ((result 0) (n (length a)))
         (dotimes (k n)
             (setq result (+ (* (nth k a) (expt x (- n k 1))) result)))
         result))
Lisp

And here’s using it to evaluate the polynomial 2x3x2+5x102x^{3} - x^{2} + 5x - 10 at x=3x = 3:

(poly 3 '(2 -1 5 -10))
Lisp

Then I thought how to turn each of those points into an ASCII-art graph.

The polt function uses two nested dolist loops iterating over a list of x-values and y-values, and then at each point, it has to decide domehow whether to plot a point (by returning “#” insread of the background character). The simplest solution is to only plot it if y=f(x)y = f(x) and don’t otherwise, but this only works when lines cross exactly over the gridline.

After considering a number of other methods, I decided on the method that mattbatwings used in his Minecraft graphing calculator. This represents a function as 3D surface in xx and yy, and then plotting all the points where the surface crosses the xx-yy plane at z=0z=0.

This function makes that decision. It takes the function ff, the xx and yy coordinates, and dd which represents the distance between gird lines.

(defun zerocross (f x y d)
    (or
        (eq (< 0 (funcall f x y)) (> 0 (funcall f (- x d) y)))
        (eq (< 0 (funcall f x (- y d))) (> 0 (funcall f x y)))
        (eq (< 0 (funcall f x y)) (> 0 (funcall f (+ x d) y)))
        (eq (< 0 (funcall f x (+ y d))) (> 0 (funcall f x y)))))
Lisp

If there is a sign change in the function close to the point, it returns t, otherwise it returns nil.

Now all that’s left to do is iterate over the provided ranges and call zerocross at each x- and y-value, and if there is no zero crossing, return the “background” characters.

axis returns a line character if it is on the axis, and dots for a grid at increments of 2.

(defun axis (x y)
    (if (and (= 0 x) (= 0 y)) "+"
        (if (= 0 x) "|"
            (if (= 0 y) "-"
                (if (and (= 0 (mod x 2)) (= 0 (mod y 2))) "." " ")))))
Lisp

range is an emulation fo the Python range function, which returns a list of numbers from min up to max in increments of step.

(defun range (min max step)
    (let ((l nil) (c min))
         (loop
             (push c l)
             (setq c (+ c step))
             (when (>= c max) (return l)))))
Lisp

plot then iterates over the entire x-y plane within the given range, and plots the function:

(defun plot (fx tx fy ty s fun)
    (with-output-to-string (out)
        (dolist (y (range fy ty s))
            (dolist (x (range fx tx s))
                (princ (if (zerocross fun x y s) "#" (axis x y)) out))
            (terpri out))))
Lisp

If you’re interested in the whole code, here it is: plot.lisp

Here’s using it to plot the function y3+x210x70=0y^{3} + x^{2} - 10x - 70 = 0:

(princ
    (plot
        -20 20 ; x-values
        -20 20 ; y-values
        1 ; step in each direction
        (lambda (x y) (+ (poly x '(1 -10 0)) (poly y '(1 0 0 -70))))))
Lisp

This produces this neat graph:

                   |                    
 . . . . . . . . . | . . . . . . . . . .
                   |                    
 . . . . . . . . . | . . . . . . . . . .
                   |                    
 . . . . . . . . . | . . . . . . . . . .
                   |                    
 . . . . . . . . . | . . . . . . . . . .
                   |                    
 . . . . . . . . . | . . . . . . . . . .
                   |                    
 . . . . . . . . . | . . . . . . . . . .
                   |                    
 . . . . . . . . . | . . . . . . . . . .
         ###########                    
 . . .#################. . . . . . . . .
     ####          |####                
 . .## . . . . . . | . ##. . . . . . . .
    ##             |   ##               
----##-------------+---##---------------
    ##             |   ##               
 . ##. . . . . . . | . .## . . . . . . .
  ##               |     ##             
###. . . . . . . . | . . .###. . . . . .
##                 |       #####        
 . . . . . . . . . | . . . . ######. . .
                   |            ####### 
 . . . . . . . . . | . . . . . . . #####
                   |                   #
 . . . . . . . . . | . . . . . . . . . .
                   |                    
 . . . . . . . . . | . . . . . . . . . .
                   |                    
 . . . . . . . . . | . . . . . . . . . .
                   |                    
 . . . . . . . . . | . . . . . . . . . .
                   |                    
 . . . . . . . . . | . . . . . . . . . .
                   |                    
 . . . . . . . . . | . . . . . . . . . .
Plain text

Pretty neat! An easy self-introduction to a programming language I though I’d never learn. Maybe I’ll take some time to learn more.

And here’s a bigger example: xsin(0.2πx)y=0x\sin\left(0.2\pi x\right)-y=0:

(princ
    (plot
        -50 50 ; x-values
        -50 50 ; y-values
        1 ; step in each direction
        (lambda (x y) (- (* x (sin (* x pi 0.2))) y))))
Lisp
                                                 |                                                  
 . . . . . . . . . . . . . . . . . . . . . . . . | . . . . . . . . . . . . . . . . . . . . . . . . .
                                                 |                                                  
 . . . . . . . . . . . . . . . . . . . . . . . . | . . . . . . . . . . . . . . . . . . . . . . . . .
                                                 |                                                  
 . . . . . . . . . . . . . . . . . . . . . . . . | . . . . . . . . . . . . . . . . . . . . . . . . .
                                                 |                                                  
 . . . . . . . . . . . . . . . . . . . . . . . . | . . . . . . . . . . . . . . . . . . . . . . . . .
      #                                          |                                          #       
 . . ### . . . . . . . . . . . . . . . . . . . . | . . . . . . . . . . . . . . . . . . . . ### . . .
     ####                                        |                                        ####      
 . . ####. . . . . . . . . . . . . . . . . . . . | . . . . . . . . . . . . . . . . . . . .#### . . .
     ####                                        |                                        ####      
 . . ####. . . . . . . . . . . . . . . . . . . . | . . . . . . . . . . . . . . . . . . . .#### . . .
     ####                                        |                                        ####      
 . . ####. . . . . . . . . . . . . . . . . . . . | . . . . . . . . . . . . . . . . . . . .#### . . .
     ####                                        |                                        ####      
 . . ####. . . .#. . . . . . . . . . . . . . . . | . . . . . . . . . . . . . . . .#. . . .#### . . .
     ####      ###                               |                               ###      ####      
 . . ####. . . ####. . . . . . . . . . . . . . . | . . . . . . . . . . . . . . .#### . . .#### . . .
     ####      ####                              |                              ####      ####     #
 . . ####. . . ####. . . . . . . . . . . . . . . | . . . . . . . . . . . . . . .#### . . .#### . . #
     ####      ####                              |                              ####      ####     #
 . . ####. . . ####. . . . . . . . . . . . . . . | . . . . . . . . . . . . . . .#### . . .#### . . #
    ## ##      ####                              |                              ####      ## ##    #
 . .## .## . . ####. . . . . . . . . . . . . . . | . . . . . . . . . . . . . . .#### . . ##. ##. . #
    ##  ##     ####                              |                              ####     ##  ##    #
 . .## .## . . ####. . . .#. . . . . . . . . . . | . . . . . . . . . . .#. . . .#### . . ##. ##. . #
    ##  ##     ####      ###                     |                     ###      ####     ##  ##    #
 . .## .## . . ####. . . ####. . . . . . . . . . | . . . . . . . . . .#### . . .#### . . ##. ##. . #
    ##  ##    ## ##      ####                    |                    ####      ## ##    ##  ##    #
 . .## .## . .## .## . . ####. . . . . . . . . . | . . . . . . . . . .#### . . ##. ##. . ##. ##. . #
    ##  ##    ##  ##     ####                    |                    ####     ##  ##    ##  ##    #
 . .## .## . .## .## . . ####. . . . . . . . . . | . . . . . . . . . .#### . . ##. ##. . ##. ##. . #
    ##  ##    ##  ##     ####                    |                    ####     ##  ##    ##  ##    #
 . .## .## . .## .## . .## ##. . . . . . . . . . | . . . . . . . . . .## ##. . ##. ##. . ##. ##. . #
    ##  ##    ##  ##    ## ##       #            |            #       ## ##    ##  ##    ##  ##    #
 . .## .## . .## .## . .## .## . . ### . . . . . | . . . . . ### . . ##. ##. . ##. ##. . ##. ##. . #
    ##  ##    ##  ##    ##  ##     ####          |          ####     ##  ##    ##  ##    ##  ##    #
 . .## .## . .## .## . .## .## . . ####. . . . . | . . . . .#### . . ##. ##. . ##. ##. . ##. ##. . #
    ##  ##    ##  ##    ##  ##     ####          |          ####     ##  ##    ##  ##    ##  ##    #
 . .## .## . .## .## . .## .## . .## ##. . . . . | . . . . .## ##. . ##. ##. . ##. ##. . ##. ##. . #
    ##  ##    ##  ##    ##  ##    ## ##          |          ## ##    ##  ##    ##  ##    ##  ##    #
 . .## .## . .## .## . .## .## . .## .## . . . . | . . . . ##. ##. . ##. ##. . ##. ##. . ##. ##. . #
    ##  ##    ##  ##    ##  ##    ##  ##         |         ##  ##    ##  ##    ##  ##    ##  ##    #
 . .## .## . .## .## . .## .## . .## .## . . . . | . . . . ##. ##. . ##. ##. . ##. ##. . ##. ##. . #
    ##  ##    ##  ##    ##  ##    ##  ##     ##  |  ##     ##  ##    ##  ##    ##  ##    ##  ##    #
 . .## .## . .## .## . .## .## . .## .## . .#### | ####. . ##. ##. . ##. ##. . ##. ##. . ##. ##. . #
    ##  ##    ##  ##    ##  ##    ##  ##    ## ##|## ##    ##  ##    ##  ##    ##  ##    ##  ##    #
#---##---##--##----##---##---##---##---##---##--###--##---##---##---##---##---##----##--##---##---##
#  ##    ##  ##    ##  ##    ##  ##    ##  ##    #    ##  ##    ##  ##    ##  ##    ##  ##    ##  ##
#. ##. . ##. ##. . ##. ##. . ##. ##. . ##. ##. . | . .## .## . .## .## . .## .## . .## .## . .## .##
#  ##    ##  ##    ##  ##    ##  ##    ##  ##    |    ##  ##    ##  ##    ##  ##    ##  ##    ##  ##
#. ##. . ##. ##. . ##. ##. . ##. ##. . ##.## . . | . . ##.## . .## .## . .## .## . .## .## . .## .##
#  ##    ##  ##    ##  ##    ##  ##    ## ##     |     ## ##    ##  ##    ##  ##    ##  ##    ##  ##
#. ##. . ##. ##. . ##. ##. . ##. ##. . .#### . . | . . ####. . .## .## . .## .## . .## .## . .## .##
#  ##    ##  ##    ##  ##    ##  ##     ###      |      ###     ##  ##    ##  ##    ##  ##    ##  ##
#. ##. . ##. ##. . ##. ##. . ##. ##. . . # . . . | . . . # . . .## .## . .## .## . .## .## . .## .##
#  ##    ##  ##    ##  ##    ##  ##              |              ##  ##    ##  ##    ##  ##    ##  ##
#. ##. . ##. ##. . ##. ##. . ##.## . . . . . . . | . . . . . . . ##.## . .## .## . .## .## . .## .##
#  ##    ##  ##    ##  ##    ## ##               |               ## ##    ##  ##    ##  ##    ##  ##
#. ##. . ##. ##. . ##. ##. . .#### . . . . . . . | . . . . . . . ####. . .## .## . .## .## . .## .##
#  ##    ##  ##    ##  ##     ####               |               ####     ##  ##    ##  ##    ##  ##
#. ##. . ##. ##. . ##. ##. . .#### . . . . . . . | . . . . . . . ####. . .## .## . .## .## . .## .##
#  ##    ##  ##    ##  ##     ####               |               ####     ##  ##    ##  ##    ##  ##
#. ##. . ##. ##. . ##.## . . .#### . . . . . . . | . . . . . . . ####. . . ##.## . .## .## . .## .##
#  ##    ##  ##    ## ##      ###                |                ###      ## ##    ##  ##    ##  ##
#. ##. . ##. ##. . .#### . . . # . . . . . . . . | . . . . . . . . # . . . ####. . .## .## . .## .##
#  ##    ##  ##     ####                         |                         ####     ##  ##    ##  ##
#. ##. . ##. ##. . .#### . . . . . . . . . . . . | . . . . . . . . . . . . ####. . .## .## . .## .##
#  ##    ##  ##     ####                         |                         ####     ##  ##    ##  ##
#. ##. . ##.## . . .#### . . . . . . . . . . . . | . . . . . . . . . . . . ####. . . ##.## . .## .##
#  ##     ####      ####                         |                         ####      ####     ##  ##
#. ##. . .#### . . .#### . . . . . . . . . . . . | . . . . . . . . . . . . ####. . . ####. . .## .##
#  ##     ####      ####                         |                         ####      ####     ##  ##
#. ##. . .#### . . .###. . . . . . . . . . . . . | . . . . . . . . . . . . .###. . . ####. . .## .##
#  ##     ####       #                           |                           #       ####     ##  ##
#.## . . .#### . . . . . . . . . . . . . . . . . | . . . . . . . . . . . . . . . . . ####. . . ##.##
####      ####                                   |                                   ####      #### 
#### . . .#### . . . . . . . . . . . . . . . . . | . . . . . . . . . . . . . . . . . ####. . . ####.
####      ####                                   |                                   ####      #### 
#### . . .#### . . . . . . . . . . . . . . . . . | . . . . . . . . . . . . . . . . . ####. . . ####.
####      ####                                   |                                   ####      #### 
#### . . .#### . . . . . . . . . . . . . . . . . | . . . . . . . . . . . . . . . . . ####. . . ####.
####      ####                                   |                                   ####      #### 
#### . . .###. . . . . . . . . . . . . . . . . . | . . . . . . . . . . . . . . . . . .###. . . ####.
####       #                                     |                                     #       #### 
#### . . . . . . . . . . . . . . . . . . . . . . | . . . . . . . . . . . . . . . . . . . . . . ####.
####                                             |                                             #### 
#### . . . . . . . . . . . . . . . . . . . . . . | . . . . . . . . . . . . . . . . . . . . . . ####.
####                                             |                                             #### 
#### . . . . . . . . . . . . . . . . . . . . . . | . . . . . . . . . . . . . . . . . . . . . . ####.
####                                             |                                             #### 
#### . . . . . . . . . . . . . . . . . . . . . . | . . . . . . . . . . . . . . . . . . . . . . ####.
###                                              |                                              ### 
 # . . . . . . . . . . . . . . . . . . . . . . . | . . . . . . . . . . . . . . . . . . . . . . . # .
                                                 |                                                  
 . . . . . . . . . . . . . . . . . . . . . . . . | . . . . . . . . . . . . . . . . . . . . . . . . .
                                                 |                                                  
 . . . . . . . . . . . . . . . . . . . . . . . . | . . . . . . . . . . . . . . . . . . . . . . . . .
Plain text

Related Posts