/clj
Created
November 29, 2017 11:40
squircle
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; Wed Nov 29 10:09:47 2017 | |
;; Draw a square using trig | |
;; Instructions | |
;; cider-jack-in | |
;; cider-refresh | |
;; User interactions | |
(ns my-sketch.core | |
(:require [quil.core :as q] | |
[quil.middleware :as m])) | |
(def num-points 720) | |
(defn h | |
([] (h 1.0)) | |
([value] (* (q/height) value))) | |
(defn w | |
([] (w 1.0)) | |
([value] (* (q/width) value))) | |
(defn setup [] | |
(q/no-loop) | |
(q/stroke-weight 0.5)) | |
(defn key-pressed [state event] | |
(let [key-p (:key event) | |
new-state (case key-p | |
:s (do | |
(q/save (str (java.util.Date.))) | |
state) | |
(do | |
state | |
))] | |
new-state)) | |
(defn update-state [state] | |
state) | |
(defmacro doseq-indexed [index-sym [item-sym coll] & body] | |
`(doseq [[~index-sym ~item-sym] (map list (range) ~coll)] | |
~@body)) | |
(defn sign [x] | |
(cond | |
(< x 0) -1 | |
(> x 0) 1 | |
:else 0)) | |
(defn squircle-x [theta width] | |
(* width | |
(sign (q/cos theta)) | |
(q/sqrt (Math/abs (q/cos theta))))) | |
(defn squircle-y [theta width] | |
(* width | |
(sign (q/sin theta)) | |
(q/sqrt (Math/abs (q/sin theta))))) | |
(defn draw-squircle [radius] | |
(let [thetas (range 0 (* 2 Math/PI) (/ Math/PI num-points)) | |
xs (map (fn[theta] (squircle-x theta radius)) | |
thetas) | |
ys (map (fn[theta] (squircle-y theta radius)) | |
thetas)] | |
(doseq-indexed i [x xs] | |
(let [y (nth ys i)] | |
(q/point x y))))) | |
(defn circle-x [theta width] | |
(* width (q/cos theta))) | |
(defn circle-y [theta width] | |
(* width (q/sin theta))) | |
(defn draw-circle [radius] | |
(let [thetas (range 0 (* 2 Math/PI) (/ Math/PI num-points)) | |
xs (map (fn[theta] (circle-x theta radius)) | |
thetas) | |
ys (map (fn[theta] (circle-y theta radius)) | |
thetas)] | |
(doseq-indexed i [x xs] | |
(let [y (nth ys i)] | |
(q/point x y))))) | |
(defn square-x [theta width] | |
(cond | |
(< theta (* Math/PI 0.25)) width | |
(< theta (* Math/PI 0.75)) (* width (/ 1 (q/tan theta))) | |
(< theta (* Math/PI 1.25)) (- width) | |
(< theta (* Math/PI 1.75)) (* -1 width (/ 1 (q/tan theta))) | |
:else width)) | |
(defn square-y [theta width] | |
(cond | |
(< theta (* Math/PI 0.25)) (* width (q/tan theta)) | |
(< theta (* Math/PI 0.75)) width | |
(< theta (* Math/PI 1.25)) (* -1 width (q/tan theta)) | |
(< theta (* Math/PI 1.75)) (- width) | |
:else (* (q/tan theta) width))) | |
(defn draw-square[width] | |
(let [thetas (range 0 (* 2 Math/PI) (/ Math/PI num-points)) | |
xs (map (fn[theta] (square-x theta width)) | |
thetas) | |
ys (map (fn[theta] (square-y theta width)) | |
thetas)] | |
(doseq-indexed i [x xs] | |
(let [y (nth ys i)] | |
(q/point x y))))) | |
(defn half-circle-half-squircle [width lerp-amount] | |
(let [thetas (range 0 (* 2 Math/PI) (/ Math/PI num-points)) | |
xs-circle (map (fn[theta] (circle-x theta width)) | |
thetas) | |
ys-circle (map (fn[theta] (circle-y theta width)) | |
thetas) | |
xs-squircle (map (fn[theta] (squircle-x theta width)) | |
thetas) | |
ys-squircle (map (fn[theta] (squircle-y theta width)) | |
thetas) | |
xs (map-indexed (fn [i x] | |
(q/lerp x (nth xs-squircle i) lerp-amount)) | |
xs-circle) | |
ys (map-indexed (fn [i y] | |
(q/lerp y (nth ys-squircle i) lerp-amount)) | |
ys-circle)] | |
(doseq-indexed i [x xs] | |
(let [y (nth ys i)] | |
(q/point x y))))) | |
(defn half-square-half-squircle [width lerp-amount] | |
(let [thetas (range 0 (* 2 Math/PI) (/ Math/PI num-points)) | |
xs-square (map (fn[theta] (square-x theta width)) | |
thetas) | |
ys-square (map (fn[theta] (square-y theta width)) | |
thetas) | |
xs-squircle (map (fn[theta] (squircle-x theta width)) | |
thetas) | |
ys-squircle (map (fn[theta] (squircle-y theta width)) | |
thetas) | |
xs (map-indexed (fn [i x] | |
(q/lerp x (nth xs-squircle i) lerp-amount)) | |
xs-square) | |
ys (map-indexed (fn [i y] | |
(q/lerp y (nth ys-squircle i) lerp-amount)) | |
ys-square)] | |
(doseq-indexed i [x xs] | |
(let [y (nth ys i)] | |
(q/point x y))))) | |
(defn half-square-half-circle [width lerp-amount] | |
(let [thetas (range 0 (* 2 Math/PI) (/ Math/PI num-points)) | |
xs-square (map (fn[theta] (square-x theta width)) | |
thetas) | |
ys-square (map (fn[theta] (square-y theta width)) | |
thetas) | |
xs-circle (map (fn[theta] (circle-x theta width)) | |
thetas) | |
ys-circle (map (fn[theta] (circle-y theta width)) | |
thetas) | |
xs (map-indexed (fn [i x] | |
(q/lerp x (nth xs-circle i) lerp-amount)) | |
xs-square) | |
ys (map-indexed (fn [i y] | |
(q/lerp y (nth ys-circle i) lerp-amount)) | |
ys-square)] | |
(doseq-indexed i [x xs] | |
(let [y (nth ys i)] | |
(q/point x y))) | |
)) | |
(defn mix-shapes [shape-1 shape-2 width lerp-amt] | |
(let [thetas (range 0 (* 2 Math/PI) (/ Math/PI num-points)) | |
x-fn-1 (case shape-1 | |
"squircle" squircle-x | |
"square" square-x | |
"circle" circle-x) | |
y-fn-1 (case shape-1 | |
"squircle" squircle-y | |
"square" square-y | |
"circle" circle-y) | |
x-fn-2 (case shape-2 | |
"squircle" squircle-x | |
"square" square-x | |
"circle" circle-x) | |
y-fn-2 (case shape-2 | |
"squircle" squircle-y | |
"square" square-y | |
"circle" circle-y) | |
xs-1 (map (fn[theta] (x-fn-1 theta width)) | |
thetas) | |
ys-1 (map (fn[theta] (y-fn-1 theta width)) | |
thetas) | |
xs-2 (map (fn[theta] (x-fn-2 theta width)) | |
thetas) | |
ys-2 (map (fn[theta] (y-fn-2 theta width)) | |
thetas) | |
xs (map-indexed (fn [i x] | |
(q/lerp x (nth xs-2 i) lerp-amt)) | |
xs-1) | |
ys (map-indexed (fn [i y] | |
(q/lerp y (nth ys-2 i) lerp-amt)) | |
ys-1)] | |
(doseq-indexed i [x xs] | |
(let [y (nth ys i)] | |
(q/point x y))) | |
)) | |
(defn draw [state] | |
(q/translate (w 0.5) (h 0.5)) | |
;; (draw-circle 100) | |
;; (draw-square 100) | |
;; (half-square-half-circle 100 0.5) | |
;; (half-circle-half-squircle 100 0.5) | |
;; (half-square-half-squircle 100 0.5) | |
;; (mix-shapes "square" "circle" 100 0.5) | |
(doseq [lerp-amt (vec (range -10 1 0.1))] | |
(mix-shapes "squircle" "circle" 100 lerp-amt) | |
) | |
;; (draw-squircle 100) | |
(q/save (str (java.util.Date.)))) | |
(q/defsketch my-sketch | |
:title "Square with theta" | |
:size [500 500] | |
:setup setup | |
:update update-state | |
:key-pressed key-pressed | |
:draw draw | |
:features [:keep-on-top] | |
:middleware [m/fun-mode]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment