tikz/tikz.rkt
#lang racket

(require "../base/coord.rkt"
         "../base/bounding-box.rkt")

(provide point circle ellipse arc line closed-line rectangle text)

(define tikz display)
(define tikzln displayln)

(define (tikz-end)
  (tikzln ";"))

(define (tikz-e arg)
  (tikz arg)
  (tikz-end))

(define (tikz-draw)
  (tikz "\\draw "))

(define (tikz-number x)
  (if (integer? x)
      (tikz x)
      (tikz (real->decimal-string x))))

(define (tikz-cm x)
  (tikz-number x)
  (tikz "cm"))

(define (tikz-coord c)
  (display "(")
  (tikz-number (cx c))
  (display ",")
  (tikz-number (cy c))
  (unless (= (cz c) 0)
    (display ",")
    (tikz-number (cz c)))
  (display ")"))

(define (tikz-pgfpoint c)
  (unless (= 0 (cz c))
    (error "Can't handle 3D coords"))
  (tikz "\\pgfpoint{")
  (tikz-cm (cx c))
  (tikz "}{")
  (tikz-cm (cy c))
  (tikz "}"))

(define (point c)
  (circle c 0.01))

(define (circle c r)
  (tikz-draw)
  (tikz-coord c)
  (tikz "circle(")
  (tikz-cm r)
  (tikz-e ")"))

(define (ellipse c r0 r1 fi)
  (tikz-draw)
  (tikz "[shift={")
  (tikz-coord c)
  (tikz "}]")
  (tikz "[rotate=")
  (tikz-number (radians->degrees fi))
  (tikz "]")
  (tikz "(0,0)")
  (tikz "ellipse(")
  (tikz-cm r0)
  (tikz " and ")
  (tikz-cm r1)
  (tikz-e ")"))

(define (arc c r ai af)
  (tikz-draw)
  (tikz-coord (+pol c r ai))
  (tikz "arc(")
  (tikz-number (radians->degrees ai))
  (tikz ":")
  (tikz-number
   (radians->degrees
    (if (> ai af)
      (+ af (* 2 pi))
      af)))
  (tikz ":")
  (tikz-cm r)
  (tikz-e ")"))

(define (line pts)
  (tikz-draw)
  (tikz-coord (car pts))
  (for ([pt (in-list (cdr pts))])
    (tikz "--")
    (tikz-coord pt))
  (tikz-end))

(define (closed-line pts)
  (tikz-draw)
  (for ([pt (in-list pts)])
    (tikz-coord pt)
    (tikz "--"))
  (tikz-e "cycle"))

(define (rectangle p w h)
  (tikz-draw)
  (tikz-coord p)
  (tikz "rectangle")
  (tikz-coord (+xy p w h))
  (tikz-end))

;;Assuming default Arial font for AutoCAD
#;
(define (text txt p0 p1 h rot x-scale incl horiz-just vert-just)
  (let ((scale-x (* 3.7 h (if x-scale x-scale 1)))
	(scale-y (* 3.7 h)))
    (tikz-draw)
    (tikz "[anchor=base west]")
    (tikz-coord p0)
    ;; (tikz "node[font=\\fontfamily{phv}\\selectfont,outer sep=0pt,inner sep=0pt,rotate=")
    (tikz "node[font=\\fontfamily{phv}\\selectfont,outer sep=0pt,inner sep=0pt")
    (unless (and (= horiz-just 0) (= vert-just 0))
      (tikz ",minimum width=")
      (tikz-cm (abs (/ (- (cx p1) (cx p0)) scale-x)))
      (tikz ",minimum height=")
      (tikz-cm (abs (/ (- (cy p1) (cy p0)) scale-y))))
    (unless (= rot 0)
      (tikz ",rotate=")
      (tikz-number (radians->degrees rot)))
    (unless (= incl 0)
      (tikz ",xslant=")
      (tikz-number (sin incl)))
    (tikz ",xscale=")
    (tikz-number scale-x)
    (tikz ",yscale=")
    (tikz-number scale-y)
    (tikz "]{")
    (tikz txt)
    (tikz-e "}")))

(define (text txt p h)
  (let ((scale-x (* 3.7 h))
	(scale-y (* 3.7 h)))
    (tikz-draw)
    (tikz "[anchor=base west]")
    (tikz-coord p)
    (tikz "node[font=\\fontfamily{phv}\\selectfont,outer sep=0pt,inner sep=0pt")
    (tikz ",xscale=")
    (tikz-number scale-x)
    (tikz ",yscale=")
    (tikz-number scale-y)
    (tikz "]{")
    (tikz txt)
    (tikz-e "}")))