Moiré Patterns

Moiré pattern with two overlaid triangle tilings with a slight rotation offset

An interesting thing to play around with is Moiré patterns, which are new patterns you get when you overlay two identical patterns but with some slight displacement. The above and below images are using two triangle tilings. My code displays the tilings and allows rotational and translation adjustment using some keyboard keys. The pattern for the overlaid triangle tilings seems to be generally some number of hexagons at various sizes.

Pattern with less hexagons.

This was the most interesting, however, was this dodecagon-like shape when around a 30 degree rotation offset or so.

Pattern with dodecagon-like shapes.
;; Copyright 2021 Christopher Howard

;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License.
;; You may obtain a copy of the License at

;;     http://www.apache.org/licenses/LICENSE-2.0

;; Unless required by applicable law or agreed to in writing, software
;; distributed under the License is distributed on an "AS IS" BASIS,
;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
;; See the License for the specific language governing permissions and
;; limitations under the License.

(use-modules (sdl2)
             (sdl2 video)
             (sdl2 rect)
             (sdl2 surface)
             (sdl2 render)
             (sdl2 input keyboard)
             (sdl2 events))

(define (cex coord) (list (inexact->exact (round (car coord)))
                          (inexact->exact (round (cadr coord)))))

(define (rot rad coords)
  (let* ((x (car coords))
         (y (cadr coords))
         (cpx (make-rectangular x y))
         (fact (exp (* rad 0+i)))
         (ncpx (* cpx fact)))
    (list (real-part ncpx) (imag-part ncpx))))

(define* (draw-tri-block r orig-x orig-y base-l
                         #:key (rotr 0))
  (let* ((base-hl (* 0.5 base-l))
         (base-h (* (* base-l (sqrt 3)) 0.5))
         (lrot (if (zero? rotr) (lambda (x) x)
                   (lambda (c) (rot rotr c))))
         (ccomp (lambda (c) (cex (lrot c)))))
    (render-draw-lines
     r
     (map ccomp (list (list (+ orig-x base-l) orig-y)
                      (list (+ orig-x base-hl)
                            (+ orig-y base-h))
                      (list (+ orig-x base-hl base-l)
                            (+ orig-y base-h))
                      (list (+ orig-x base-l) (ex orig-y)))))))

(define* (draw-tri-pattern r offset-x offset-y #:key (rotr 0))
  (let* ((base-l 20)
         (base-h (* (* base-l (sqrt 3)) 0.5))
         (base-hl (* 0.5 base-l)))
    (do ((j 0 (1+ j)))
        ((> j 40))
        (do ((i 0 (1+ i)))
            ((> i 40))
          (draw-tri-block
           r
           (+ (* i base-l)
              (if (zero? (floor-remainder j 2)) 0 base-hl)
              offset-x)
           (+ (* j base-h) offset-y)
           base-l
           #:rotr rotr)))))

(define rot-radius 0)

(define rot-inc (/ 3.1415 5096))

(define trans-x 0)

(define trans-y 0)

(define trans-inc 1)

(define (main)
  (sdl-init)
  (let* ((mywindow (make-window
                  #:title "Super Awesome Window"
                  #:opengl? #t
                  #:size '(1024 768)))
         (glc (make-gl-context mywindow))
         (myrect (make-rect 100 100 200 100))
         (mysurface (make-rgb-surface 300 300 32))
         (myrenderer (make-renderer mywindow)))
    (set-gl-swap-interval! 'vsync)
    (while (not (key-pressed? 'q))
      (usleep 100)
      (poll-event)
      (if (key-pressed? 'r)
          (set! rot-radius (+ rot-inc rot-radius)))
      (if (key-pressed? 't)
          (set! rot-radius (- rot-radius rot-inc)))
      (if (key-pressed? 'j)
          (set! trans-x (- trans-x trans-inc)))
      (if (key-pressed? 'k)
          (set! trans-x (+ trans-x trans-inc)))
      (if (key-pressed? 'i)
          (set! trans-y (- trans-y trans-inc)))
      (if (key-pressed? 'm)
          (set! trans-y (+ trans-y trans-inc)))
      (set-render-draw-color myrenderer 0 0 0 255)
      (clear-renderer myrenderer)
      (set-render-draw-color myrenderer 0 255 255 255)
      (draw-tri-pattern myrenderer 0 0)
      (draw-tri-pattern myrenderer trans-x trans-y #:rotr rot-radius)
      (present-renderer myrenderer))
    (close-window! mywindow)
  (sdl-quit)))

1 thought on “Moiré Patterns”

Leave a Reply to AlaskaLinuxUser Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s