I like sending New Year's cards. Each year I prepare the design, buy these blank cards, and print them at home. This year I thought I'd try quil, basically Processing in clojure, to draw some fancy patterns for it. Because I can't draw at all...
What kind of pattern is suitable for New Year's cards? In Japan (I'm a Japanese, by the way), things which we can wish each other's health and prosperity with have been popular --- pine trees, cranes, and turtles to name some. They are symbols of health & long lives because they live long (always green for pines). Another popular symbol is the ume 梅, Japanese apricot, because they bloom the earliest in spiring and celebrating the New Year is all about celebrating the coming spring.
Ume flowers are traditionally abstracted into design (for lack of my vocab) like this:
(Image taken from this site, which allows replication). Five circles with stamen nicely signifies the ume flowers. I like them and its simplicity will go well with quil.
I talked with Mom and she suggested a traditional design called 利休梅 (do check out the link which is google image search), where the flower is symbolised with 5+1 circles + lines connecting the centre and the petals.
The flowers are, she says, usually scattered to form a design. Maybe I can tile them to make a pattern?
Tessellation is always an interesting topic. For pentagons, I found the Cairo pentagonal tiling quite beautiful and symmetric (remember we'll be putting flowers to the pentagons)
So let's assign a flower to each of the pentagon there. From now on, I'll call the hexagon formed by 4 pentagons Hexa. Let the length of the squares and regular triangles r, which I set to 50px in the code.
Let's look at a Hexa and name some lengths. The structure is so elegant that every length I'll need can be calculated nicely. Here's a doodle I drew while coding, which shows how the lengths
r3 is defined.
After these simple math, coding itself is quite straightforward. To make things easier, a Hexa is drawn in an angle where it stands straight. I defined
draw-flower to draw a single flower;
draw-hex-pattern for a Hexa, in which 4
draw-flower is called with appropriate translation and rotation; then
draw-hex-at, which accepts the location in the form of
(structure hexa x y), where
y are the hexagonal coordinates. Full code (which is probably not ideal) follows..
; licensed under the MIT license (ns nen.core (:require [quil.core :as q] [quil.middleware :as m])) (defstruct hexa :x :y) (def r 50) (def r1 (/ r (Math/sqrt 3))) (def r2 (* r (+ 1 (/ 1 (Math/sqrt 3))))) (def r3 (/ (* r (+ 1 (Math/sqrt 3))) 2)) (def corolla-size 15) (def centre-size 12) (def str-w 3) (defn draw-corolla [x y] (q/ellipse x y corolla-size corolla-size)) (defn draw-corolla-r [x y] (let [dx (* 0.1 corolla-size (- (Math/random) 0.5)) dy (* 0.1 corolla-size (- (Math/random) 0.5)) ] (draw-corolla (+ x 0) (+ y 0)) ) ) (defn draw-flower  (q/fill 223 130 138) (doseq ; every corolla is located half-way for aesthetics [ [x y] [[0 0] [(/ r2 8) (/ r3 4)] [(/ r2 8) (- (/ r3 4))] [(/ (+ r1 r2) 4) (/ r1 4)] [(/ (+ r1 r2) 4) ( - (/ r1 4))] ]] (do (q/stroke 223 130 138) (q/stroke-weight str-w) (q/line (/ r1 2) 0 x y) (q/no-stroke) (draw-corolla-r x y))) (q/fill 248 181 0) (q/ellipse (/ r1 2) 0 centre-size centre-size) ) (defn draw-hex-pattern  (q/fill 223 130 138) (draw-flower) (q/with-translation [ (/ (+ r1 r2) 2) (- (/ r1 2)) ] (q/with-rotation [(/ Math/PI -2)] (draw-flower))) (q/with-translation [ (/ (+ r1 r2) 2) (/ r1 2) ] (q/with-rotation [(/ Math/PI 2)] (draw-flower))) (q/with-translation [ (+ r1 r2) 0 ] (q/with-rotation [Math/PI] (draw-flower))) ) (defn draw-hex-at [h] (q/with-translation [ (* (:x h) (+ r1 (/ r2 2)) ) (+ (* 2 r3 (:y h)) (if (even? (:x h)) 0 r3))] (draw-hex-pattern))) (defn setup  (q/frame-rate 30) (q/color-mode :rgb) (for [x (range 10) y (range 5)] (struct hexa x y))) (defn update-state [s] s) (defn draw-state [state] (q/background 255) (q/no-loop) (q/with-translation [50 100] (doseq [h state] (draw-hex-at h))) (q/save "out.png") ) (q/defsketch nen :title "super-omedetai" :size [800 800] ; setup function called only once, during sketch initialization. :setup setup ; update-state is called on each iteration before draw-state. :update update-state :draw draw-state :features [:keep-on-top] :middleware [m/fun-mode])
which results in something like this:
That looks beautiful. I love it.
After adding some texts and my hand-written messages (which is blurred in this post) and my name, here's my new year's card. I'd use the spaces in top-left to add some personal messages to each person.
I wish you all a happy new year, and hope that 2018 will be a wonderful year for all of us.