
(require :asdf)
(require :vecto)

(defparameter *r* 0.35)
(defparameter *a* 1.0)
(defparameter *b* 1.35)
(defparameter *steps* 50)

(defun draw-axises ()
  (vecto:set-rgba-stroke 0 0 1 0.5)
  (vecto:set-line-cap :round)
  (vecto:set-line-width 0.01)
  (vecto:move-to -1  0)
  (vecto:line-to  1  0)
  (vecto:move-to  0 -1)
  (vecto:line-to  0  1)
  (vecto:stroke)
  (vecto:set-rgba-fill 0 0 1 0.5)
  (vecto:draw-string 0.90 0.02 "x")
  (vecto:draw-string 0.02 0.90 "y")
  (vecto:set-rgba-stroke 0 1 0 1.0)
  (vecto:set-line-width 0.015)
  (vecto:move-to (- *r*) 0)
  (vecto:line-to 0 0)
  (vecto:stroke)
  (vecto:set-rgba-fill 0 1 0 0.75)
  (vecto:draw-string (* *r* -2/3) 0.02 "r"))

(defun draw-diagonal ()
  ;; draw line
  (vecto:set-rgba-stroke 1 0 0 0.25)
  (vecto:set-line-cap :round)
  (vecto:set-line-width 0.01)
  (vecto:set-dash-pattern #(0.08 0.02) 0)
  (vecto:move-to (- *a*) (- *b*))
  (vecto:line-to *a* *b*)
  (vecto:stroke)

  (vecto:move-to (- *a*) *b*)
  (vecto:line-to *a* (- *b*))
  (vecto:stroke)

  ;; label line
  (vecto:set-rgba-fill 1 0 0 0.5)
  (vecto:draw-string (+ (* *a* -0.6) 0.05) (* *b* -0.6) "y=bx/a")

  ;; draw phi arc
  (vecto:set-rgba-stroke 0.5 0.25 0.25 0.75)
  (vecto:set-line-width 0.005)
  (vecto:set-dash-pattern #() 0)
  (vecto:arc 0 0 0.4 (atan *b* *a*) (/ pi 2))
  (vecto:stroke)

  ;; draw phi
  (vecto:set-rgba-fill 0.5 0.25 0.25 0.75)
  (vecto:draw-string 0.1 0.4 "Φ")

  ;; draw theta arc
  (vecto:arc 0 0 0.3 0 (atan *b* *a*))
  (vecto:stroke)

  ;; draw phi
  (vecto:set-rgba-fill 0.5 0.25 0.25 0.75)
  (vecto:draw-string 0.28 0.15 "θ"))


(defun draw-hyperbola (side)
  (let* ((a-squared (* *a* *a*))
	 (a-r-squared (* *r* *r*))
	 (a/b-squared (/ a-squared *b* *b*)))
    (flet ((f (y)
	     (* side (sqrt (+ a-r-squared (* a/b-squared y y))))))
      (vecto:set-rgba-stroke 0 0 0 1)
      (vecto:set-line-cap :round)
      (vecto:set-line-join :round)
      (vecto:set-line-width 0.01)
      (vecto:set-dash-pattern #() 0)
      (vecto:move-to (f -1) -1)
      (loop :for ss :from 1 :to *steps*
	 :do (let ((yy (+ -1 (* ss (/ 2 *steps*)))))
	       (vecto:line-to (f yy) yy)))
      (vecto:stroke)))
  #+not
  (vecto:with-graphics-state
    (vecto:scale 0.5 0.5)
    (vecto:set-rgba-fill 0 0 0 0.7)
    (vecto:draw-string -1.8 0.1 "(x/a)^2 - (y/b)^2 = r^2")))

(vecto:with-canvas (:width 512 :height 512)
  (vecto:translate 256 256)
  (vecto:scale 256 256)
  (let ((font (vecto:get-font "font.ttf")))
    (vecto:set-font font 0.1)
    (draw-axises)
    (draw-diagonal)
    (draw-hyperbola +1)
    (draw-hyperbola -1))
  (vecto:save-png "hyperbola.png"))

#+sbcl (sb-ext:quit)
