#lang scheme
(define (fformat . args)
(display (apply format args)))
(require "../../common/main.ss")
(provide (all-from-out "../../common/main.ss")
(rename-out [draw-top-level draw]))
(require "../../utils.ss")
(define tag list)
(define tagged-object first)
(define c 0)
(define (next-c!)
(let ((cc c))
(set! c (add1 c))
(format "o~a" c)))
(define (draw-top-level o)
(fformat "object { ~a }~n"
(draw* o)))
(define (draw* object)
(case* object
[primitive? => draw-primitive]
[operation? => apply-operation]
[union? => apply-union]
[else (error 'draw
"Don't know how to draw objects of type ~a: ~a [~a]"
(vector-ref (struct->vector object) 0)
object (struct->vector object))]))
(define (draw-primitive primitive)
(assert (primitive? primitive))
(case* primitive
[box? => draw-box]
[cylinder? => draw-cylinder]
[else (error "Don't know how to draw primitives of type "
(vector-ref (struct->vector primitive) 0))]))
(define-syntax define-prim-bridge
(syntax-rules ()
[(_ name prim arg prop ...)
(define (name arg)
(tag (prim (prop arg)
...)
arg))]))
(define (draw-box box)
(let ((cccc (next-c!)))
(define (a n) (/ n 2))
(define b box)
(define c (box-center b))(define l box-length)(define w box-width)(define h box-height)
(fformat "#declare ~a = box { < ~a, ~a, ~a>, <~a, ~a, ~a> }~n" cccc
(- (cx c) (a (l box)))
(- (cy c) (a (w box)))
(- (cz c) (a (h box)))
(+ (cx c) (a (l box)))
(+ (cy c) (a (w box)))
(+ (cz c) (a (h box))))
cccc))
(define (draw-cylinder cylinder)
(let ((cccc (next-c!)))
(define c cylinder-center)(define h cylinder-height)(define r cylinder-radius)
(define p1 (+z (c cylinder) (- (h cylinder) 2)))
(define p2 (+z (c cylinder) (+ (h cylinder) 2)))
(fformat "#declare ~a = cylinder { <~a,~a,~a>, <~a,~a,~a>, ~a }~n" cccc
(cx p1)(cy p1)(cz p1)
(cx p2)(cy p2)(cz p2)
(r cylinder))
cccc))
(define (apply-operation operation)
(assert (operation? operation))
(case* operation
[rotation? => apply-rotation]
[translation? => apply-translation]
[else (error "Operation ("
(vector-ref (struct->vector operation) 0)
") not implemented")]))
(define (apply-translation t)
(let ((cccc (next-c!)))
(fformat "#declare ~a = object { ~a translate ~a*~a }~n" cccc
(draw* (translation-object t))
(translation-magnitude t) (translation-coordinate t))
cccc))
(define (apply-rotation t)
(let ((cccc (next-c!)))
(fformat "#declare ~a = object { ~a translate ~a*~a }~n" cccc
(draw* (rotation-object t))
(rotation-angle t) (rotation-coordinate t))
cccc))
(define (apply-union u)
(let ((cccc (next-c!)))
(fformat "#declare ~a = union {~n~a~n}~n" cccc
(apply string-append (map (lambda (x)
(format "object { ~a }~n" (draw* x)))
(union-objects u))))
cccc))