So I'm making a little LOGO system again, this time in elisp.
Ideally you could even have source code that spits out diagrams for more visual parts of a program by embedding small elisp snippets.
Or perhaps you could use it to create elisp games that need a more visual presentation. (I know there is a way to have it read SVG files after exporting them )
http://pastebin.com/KgjugVnF
I just think it is kind of an *ah ha!* moment to have source code that generates some pictorial documentation when you run a program.
This is useful when you are working with things easily described with pictures.
I've still got to write a function to export .SVG but I've worked with the format before and it is simple to write a small subset.
Please feel free to hack and help if anyone wants.
eLOGO plugin ...
-
- Posts: 43
- Joined: Mon Aug 26, 2013 9:24 pm
Re: eLOGO plugin ...
Did some more work on this...
Screenshot:
http://i.imgur.com/jdmxb6L.png
Screenshot:
http://i.imgur.com/jdmxb6L.png
Code: Select all
;;;; Author: Ryan Burnside
;;;; Date: 2014-03-06
;;;; Released under GPL v4
;;; This is the beginning of a LOGO like module to draw vector shapes
;;; Historically the cursor is called a "turtle"
;;; It has a small set of commands to draw primative line graphics
;;; Global variables for turtle maintenance
(defvar *canvas-width* 500)
(defvar *canvas-height* 500)
(defvar *x-pos* (/ *canvas-width* 2.0))
(defvar *y-pos* (/ *canvas-height* 2.0))
(defvar *previous-x-pos* *x-pos*)
(defvar *previous-y-pos* *y-pos*)
(defvar *direction* 0)
(defvar *step* 0)
(defvar *is-drawing* t)
(defvar *color* '(0 0 0))
(defvar *line-list* '()) ; Elements are (x y x2 y2 '(R G B))
;;; Turtle manipulation commands
(defun move ()
"Move at the current angle and step size, save line to list if *is-drawing*"
(if *is-drawing*
(setf *line-list*
(cons (list *previous-x-pos* *previous-y-pos* *x-pos* *y-pos* *color*)
*line-list*)))
(setf *previous-x-pos* *x-pos*)
(setf *previous-y-pos* *y-pos*))
(defun rt (dir)
"Turn the turtle right in degrees"
(incf *direction* dir))
(defun lt (dir)
"Turn the turtle left in degrees"
(decf *direction* dir))
(defun fd (length)
"Move forward in pixels at current heading"
(setf *step* length)
(setf *x-pos* (+ *x-pos* (* (cos (degrees-to-radians *direction*)) *step*)))
(setf *y-pos* (+ *y-pos* (* (sin (degrees-to-radians *direction*)) *step*)))
(move))
(defun bk (length)
"Turn 180 degrees and move backward from current heading"
(setf *step* length)
(incf *direction* 180)
(setf *x-pos* (+ *x-pos* (* (cos (degrees-to-radians *direction*)) *step*)))
(setf *y-pos* (+ *y-pos* (* (sin (degrees-to-radians *direction*)) *step*)))
(move))
(defun jump (x y)
"Make the turtle jump to a new position"
(setf *x-pos* x)
(setf *y-pos* y)
(move))
(defun lk (direction)
"Make the turtle look in a direction"
(setf *direction* direction))
(defun set-pen-color (red green blue)
"Set the RGB triplet for the turtle's line color"
(setf *color* (list red green blue)))
(defun tail-up ()
"Don't draw following step commands"
(setf *is-drawing* nil))
(defun tail-down ()
"Start drawing following step commands"
(setf *is-drawing* t))
(defun clear-drawing ()
"Reset the global line list"
(setf *line-list* '())
(setf *x-pos* (/ *canvas-width* 2.0))
(setf *y-pos* (/ *canvas-height* 2.0))
(setf *previous-x-pos* *x-pos*)
(setf *previous-y-pos* *y-pos*)
(setf *direction* 0)
(setf *step* 0)
(setf *is-drawing* t)
(setf *color* '(0 0 0)))
;;; We'll need to impliment a very small subset of SVG file writing below
(defun SVG-string-line (list-line)
"This converts our line from a list to the SVG syntax analog"
(let ((x1 (car list-line))
(y1 (cadr list-line))
(x2 (nth 2 list-line))
(y2 (nth 3 list-line))
(r (number-to-string (floor (car (nth 4 list-line)))))
(g (number-to-string (floor (cadr (nth 4 list-line)))))
(b (number-to-string (floor (nth 2 (nth 4 list-line))))))
(format
"<line x1=\"%3f\" y1=\"%3f\" x2=\"%3f\" y2=\"%3f\" style=\"stroke:rgb(%s,%s,%s)\"/>"
x1 y1 x2 y2 r g b)))
(defun write-SVG_buffer ()
"This writes the complete SVG file to a buffer you can save it on your own"
(switch-to-buffer (get-buffer-create "*SVG-out*"))
(set-buffer "*SVG-out*")
(erase-buffer)
(insert-string "<svg height=\"500\" width=\"500\">")
(dotimes (i (length *line-list*))
(insert-string (SVG-string-line (nth i *line-list*))))
(insert-string "</svg>"))
;; Test here little housey
(progn
(clear-drawing)
(progn ;; roof
(set-pen-color 255 0 0)
(dotimes (i 3)
(fd 100)
(lt 120))
(lk 90)
(progn ;; base
(set-pen-color 255 255 255)
(dotimes (i 3)
(fd 100)
(lt 90)))
(write-SVG_buffer)))