9ad941538426

Episode 27: Easing and Tweening
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Sun, 29 May 2016 11:47:47 +0000
parents 281946a21897
children 0e40a0899f0f
branches/tags (none)
files package.lisp src/2d/demo.lisp src/3d/demo.lisp src/utils.lisp

Changes

--- a/package.lisp	Thu May 19 21:38:29 2016 +0000
+++ b/package.lisp	Sun May 29 11:47:47 2016 +0000
@@ -15,7 +15,9 @@
     #:ensure-car
     #:ensure-cadr
     #:with-place
-    ))
+    #:draw-axes
+    #:juxt
+    #:graph-function))
 
 (defpackage #:coding-math.math
   (:use
--- a/src/2d/demo.lisp	Thu May 19 21:38:29 2016 +0000
+++ b/src/2d/demo.lisp	Sun May 29 11:47:47 2016 +0000
@@ -7,6 +7,11 @@
 (defparameter *center-x* (/ *width* 2))
 (defparameter *center-y* (/ *height* 2))
 
+(defvar *shift* nil)
+(defvar *control* nil)
+(defvar *command* nil)
+(defvar *option* nil)
+
 
 ;;;; Utils
 (defmacro with-setup (&body body)
@@ -43,31 +48,29 @@
 
 
 (defsketch cm
-    ((width *width*) (height *height*) (y-axis :down) (title "Coding Math 2D")
-     (mouse (cons 0 0))
+    ((width *width*) (height *height*) (y-axis :up) (title "Coding Math 2D")
+     (mouse (make-vec 0 0))
      ;; Data
-     (o (make-particle 0 0 :radius 5))
-     (p (make-particle 150.0 40.0 :radius 10))
-     (delta -0.05)
+     (p (make-particle 0.0 (random height) :radius 10))
+     (target (make-vec width (random height)))
+     (ease 0.1)
      ;; Pens
      (particle-pen (make-pen :fill (gray 0.9) :stroke (gray 0.4)))
-     (line-pen (make-pen :stroke (gray 0.7)))
+     (line-pen (make-pen :curve-steps 100
+                         :stroke (gray 0.7)))
      )
   (with-setup
     ;;
     (in-context
-      (translate (/ *width* 2) (/ *height* 2))
-      (with-pen particle-pen
-        (draw-particle o)
-        (draw-particle p))
-      (let ((sin (sin delta))
-            (cos (cos delta)))
-        (psetf (particle-x p)
-               (- (* (particle-x p) cos)
-                  (* (particle-y p) sin))
-               (particle-y p)
-               (+ (* (particle-y p) cos)
-                  (* (particle-x p) sin)))))
+      (draw-axes *width* *height*)
+      (let* ((distance (vec-sub target (particle-pos p)))
+             (velocity (vec-mul distance ease)))
+        (setf (particle-vel p) velocity)
+        (particle-update! p)
+        (with-pen particle-pen
+          (draw-particle p)))
+
+      )
     ;;
     )
   )
@@ -75,10 +78,10 @@
 
 ;;;; Mouse
 (defun mousemove (instance x y)
-  (with-slots (dragging mouse) instance
-    (setf (car mouse) x)
-    (setf (cdr mouse) y)
+  (with-slots (target mouse) instance
+    (setf mouse (make-vec x (- *height* y)))
     ;;
+    (setf target mouse)
     ;;
     )
   )
@@ -123,13 +126,23 @@
 (defun keydown (instance scancode)
   (declare (ignorable instance))
   (scancode-case scancode
-    (:scancode-space (sketch::prepare instance))))
+    (:scancode-space (sketch::prepare instance))
+    (:scancode-lshift (setf *shift* t))
+    (:scancode-lctrl (setf *control* t))
+    (:scancode-lgui (setf *command* t))
+    (:scancode-lalt (setf *option* t))
+    ;;
+    ;;
+    ))
 
 (defun keyup (instance scancode)
   (declare (ignorable instance))
   (scancode-case scancode
-    (:scancode-space
-     nil)))
+    (:scancode-lshift (setf *shift* nil))
+    (:scancode-lctrl (setf *control* nil))
+    (:scancode-lgui (setf *command* nil))
+    (:scancode-lalt (setf *option* nil))
+    (:scancode-space nil)))
 
 
 (defmethod kit.sdl2:keyboard-event ((instance cm) state timestamp repeatp keysym)
--- a/src/3d/demo.lisp	Thu May 19 21:38:29 2016 +0000
+++ b/src/3d/demo.lisp	Sun May 29 11:47:47 2016 +0000
@@ -10,6 +10,11 @@
 (defparameter *center-y* (/ *height* 2))
 
 
+(defvar *shift* nil)
+(defvar *control* nil)
+(defvar *command* nil)
+(defvar *option* nil)
+
 ;;;; Utils
 (defmacro with-centered-coords (&body body)
   `(in-context
@@ -177,12 +182,6 @@
 
 
 ;;;; Keyboard
-(defvar *shift* nil)
-(defvar *control* nil)
-(defvar *command* nil)
-(defvar *option* nil)
-
-
 (defun keydown (instance scancode)
   (declare (ignorable instance))
   (scancode-case scancode
--- a/src/utils.lisp	Thu May 19 21:38:29 2016 +0000
+++ b/src/utils.lisp	Sun May 29 11:47:47 2016 +0000
@@ -61,6 +61,48 @@
               :append (list slot val)))))
 
 
+(defun juxt (&rest fns)
+  (lambda (&rest args)
+    (mapcar (rcurry #'apply args) fns)))
+
+
+;;;; Handy drawing functions
+(defparameter axis-pen (make-pen :stroke (gray 0.7)))
+
+(defun draw-axes (width height)
+  (with-pen axis-pen
+    (line (- width) 0 width 0)
+    (line 0 (- height) 0 height)))
+
+
+(defun graph-function
+    (fn &key
+     (fn-start 0.0) (fn-end 1.0)
+     (fn-min 0.0) (fn-max 1.0)
+     (graph-start 0.0) (graph-end 1.0)
+     (graph-min 0.0) (graph-max 1.0))
+  (let ((steps (sketch::pen-curve-steps (sketch::env-pen sketch::*env*))))
+    (labels
+        ((norm (min max val)
+           (/ (- val min)
+              (- max min)))
+         (lerp (from to n)
+           (+ from (* n (- to from))))
+         (map-range (source-from source-to dest-from dest-to source-val)
+           (lerp dest-from dest-to
+                 (norm source-from source-to source-val))))
+      (apply #'polyline
+             (mapcan (juxt
+                       (lambda (x)
+                         (map-range fn-start fn-end graph-start graph-end x))
+                       (lambda (x)
+                         (map-range fn-min fn-max graph-min graph-max
+                                    (funcall fn x))))
+                     (iota (1+ steps)
+                           :start fn-start
+                           :step (/ (- fn-end fn-start) steps)))))))
+
+
 ;; snagged from squirl
 (eval-when (:compile-toplevel :load-toplevel :execute)
   (defun symbolicate (&rest things)