library(minisvg)

The Carpet in the Overlook Hotel from The Shining

The carpet in the Overlook Hotel features prominently in the movie The Shining.

The carpet itself has articles written about it:

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# carpet colours
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
red    <- rgb(152, 31, 36, maxColorValue = 255)
orange <- rgb(223, 95, 24, maxColorValue = 255)

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Function to calculate points around a hexagon
# @param cx,cy centre of hexagon
# @param r radius of hexagon
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
create_hex_points <- function(cx, cy, r) {
  angles <- pi/180 * seq(0, 360, 60)
  list(
    xs = round(cx + r * sin(angles), 2),
    ys = round(cy + r * cos(angles), 2)
  )
}


#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Define the patterns fundamental sizes
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sw <- 20      # stroke width
h  <- sw*10   # height
w  <- sw*7    # wiedth


#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Initialise SVG document
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
doc <- svg_doc(width = 6*w, height = 3*h)
doc$rect(x=0, y=0, width="100%", height ="100%", fill =orange)


#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Initialise the pattern
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pat  <- doc$defs()$pattern(id = 'motif', width=w, height=h, patternUnits = 'userSpaceOnUse')
patg <- pat$g(stroke_width = sw, stroke='black')

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Centre spot
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
hex <- create_hex_points(w/2, h/2, sw*2)
patg$polygon(xs=hex$xs, ys=hex$ys, fill=red)

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Lower red hexes
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
hex <- create_hex_points(0, h-sw, sw*2); patg$polygon(xs=hex$xs, ys=hex$ys, fill=red)
hex <- create_hex_points(w, h-sw, sw*2); patg$polygon(xs=hex$xs, ys=hex$ys, fill=red)

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# upper red hexes
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
hex <- create_hex_points(0, -sw, sw*2); patg$polygon(xs=hex$xs, ys=hex$ys, fill=red)
hex <- create_hex_points(w, -sw, sw*2); patg$polygon(xs=hex$xs, ys=hex$ys, fill=red)

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Some of the black outline
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
hex <- create_hex_points(0, -sw, sw*4); patg$polygon(xs=hex$xs, ys=hex$ys, fill='none')
hex <- create_hex_points(w, -sw, sw*4); patg$polygon(xs=hex$xs, ys=hex$ys, fill='none')

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# The black descenders
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
patg$line(x1 = w/2, y1 = h-sw*3, x2=w/2, y2 = h, stroke_width=sw+2)
patg$line(x1 =   0, y1 = h-sw*7, x2=0  , y2 = h-sw*3)
patg$line(x1 =   w, y1 = h-sw*7, x2=w  , y2 = h-sw*3)

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Use the pattern to fill a rectangle taking up the entire document
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
doc$rect(x=0, y=0, width="100%", height="100%", fill=pat)

Show SVG text (click to open)

   <?xml version="1.0" encoding="UTF-8"?>
   <svg width="840" height="600" viewBox="0 0 840 600" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
     <rect fill="#DF5F18" x="0" y="0" width="100%" height="100%" />
     <defs>
       <pattern id="motif" width="140" height="200" patternUnits="userSpaceOnUse">
         <g stroke-width="20" stroke="black">
           <polygon points="70,140 104.64,120 104.64,80 70,60 35.36,80 35.36,120 70,140" fill="#981F24" />
           <polygon points="0,220 34.64,200 34.64,160 0,140 -34.64,160 -34.64,200 0,220" fill="#981F24" />
           <polygon points="140,220 174.64,200 174.64,160 140,140 105.36,160 105.36,200 140,220" fill="#981F24" />
           <polygon points="0,20 34.64,0 34.64,-40 0,-60 -34.64,-40 -34.64,0 0,20" fill="#981F24" />
           <polygon points="140,20 174.64,0 174.64,-40 140,-60 105.36,-40 105.36,0 140,20" fill="#981F24" />
           <polygon points="0,60 69.28,20 69.28,-60 0,-100 -69.28,-60 -69.28,20 0,60" fill="none" />
           <polygon points="140,60 209.28,20 209.28,-60 140,-100 70.72,-60 70.72,20 140,60" fill="none" />
           <line stroke-width="22" x1="70" y1="140" x2="70" y2="200" />
           <line x1="0" y1="60" x2="0" y2="140" />
           <line x1="140" y1="60" x2="140" y2="140" />
         </g>
       </pattern>
     </defs>
     <rect fill="url(#motif)" x="0" y="0" width="100%" height="100%" />
   </svg>


Animating the pattern

In order to animate the pattern, an animateTransform is applied to the patternTransform attribute.

pat$animateTransform(
  attributeName = 'patternTransform',
  type          = 'translate',
  from          = '0 0',
  to            = paste(0, h),
  dur           = 5,
  repeatCount   = 'indefinite'
)

Show SVG text (click to open)

   <?xml version="1.0" encoding="UTF-8"?>
   <svg width="840" height="600" viewBox="0 0 840 600" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
     <rect fill="#DF5F18" x="0" y="0" width="100%" height="100%" />
     <defs>
       <pattern id="motif" width="140" height="200" patternUnits="userSpaceOnUse">
         <g stroke-width="20" stroke="black">
           <polygon points="70,140 104.64,120 104.64,80 70,60 35.36,80 35.36,120 70,140" fill="#981F24" />
           <polygon points="0,220 34.64,200 34.64,160 0,140 -34.64,160 -34.64,200 0,220" fill="#981F24" />
           <polygon points="140,220 174.64,200 174.64,160 140,140 105.36,160 105.36,200 140,220" fill="#981F24" />
           <polygon points="0,20 34.64,0 34.64,-40 0,-60 -34.64,-40 -34.64,0 0,20" fill="#981F24" />
           <polygon points="140,20 174.64,0 174.64,-40 140,-60 105.36,-40 105.36,0 140,20" fill="#981F24" />
           <polygon points="0,60 69.28,20 69.28,-60 0,-100 -69.28,-60 -69.28,20 0,60" fill="none" />
           <polygon points="140,60 209.28,20 209.28,-60 140,-100 70.72,-60 70.72,20 140,60" fill="none" />
           <line stroke-width="22" x1="70" y1="140" x2="70" y2="200" />
           <line x1="0" y1="60" x2="0" y2="140" />
           <line x1="140" y1="60" x2="140" y2="140" />
         </g>
         <animateTransform attributeName="patternTransform" from="0 0" to="0 200" type="translate" dur="5" repeatCount="indefinite" />
       </pattern>
     </defs>
     <rect fill="url(#motif)" x="0" y="0" width="100%" height="100%" />
   </svg>