R/lcd.R

Defines functions lcd

Documented in lcd

#' Liquid crystal diagrams (LCDs)
#'
#' A function for producing schematic liquid crystal diagrams that can be useful
#' for demonstrating directod alignment through the depth of an LC cell
#'
#' @param theta1 Tilt angle (in degrees) of LC molecules at y = 0 (measured from x, anti-clockwise)
#' @param theta2 Tilt angle (in degrees) of LC molecules at y = 1 (measured from x, anti-clockwise)
#' @param phi1 Twist angle (in degrees) of LC molecules at y = 0 (measured from x, anti-clockwise)
#' @param phi2 Twist angle (in degrees) of LC molecules at y = 1 (measured from x, anti-clockwise)
#' @param mol Molecule type. One of "el" for elipse (default) or "rect" for rectangles
#' @param n Number of molecules in diagram
#' @param l Length of molecule
#' @param lc_asp Aspect ratio of LC molecule (defaults to 1/4, length is 4 times width)
#' @param theta_n Nose added symetrically to theta (random noise between -theta_n and theta_n is added to theta)
#' @param bg_col Colour of diagram background (between molecules)
#' @param bg_border Colour of border of diagram
#' @param lc_col Colour of the LC molecules
#' @param lc_border Colour of LC molecule borders
#' @param right Right dimension (defaults to 1) Increase to make diagram wider
#' @param top Top dimension (defaults to 1)
#' @param strate1 Thickness of the substrate
#' @param strate2 Thickness of the superstrate
#' @param seed Seed for reproducable diagrams
#' @param strate1_col Substrate fill colour
#' @param strate1_border Substrate border coloure
#' @param strate2_col Superstrate fill colour
#' @param strate2_border SUperstrate border colour
#'
#' @return A base R plot in the graphics device
#' @export
#'
#' @examples
#' lcd(-45, 45)

lcd <- function(theta1, theta2,
                phi1 = 0, phi2 = 0,
                mol = "el",
                n = 500,
                l = 0.08,
                lc_asp = 1/3,
                theta_n = 0,
                phi_n = 0,
                bg_col = "white",
                bg_border = "black",
                lc_col = "grey90",
                lc_border = "black",
                right = 1,
                top = 1,
                strate1 = 0,
                strate2 = 0,
                strate1_col = "black",
                strate1_border = "black",
                strate2_col = "black",
                strate2_border = "black",
                seed = NULL){

  # Set seed if present
  if(!is.null(seed)) set.seed(seed)

  # Compute molecule width from provided length and LC aspect
  w <- lc_asp * l

  # Set the xy coordinates (overlap 0 and 1 with buffer so the plot
  # the plot is full with molecules overlapping the edges (stylistic choice))
  x <- runif(n=n, min = 0,  max = right)
  y <- runif(n=n, min = 0 + strate1, max = top - strate2)

  # Order y ascending
  y <- y[order(y)]

  # Generate the sequence of tilt (theta) angles and add theta noise symetrically
  theta <- seq((theta1/180)*pi, (theta2/180)*pi, l=n) + runif(n, (theta_n/180)*pi*-1, (theta_n/180)*pi)

  # Generate the sequence of twist (phi) angles and add phi noise symetrically
  phi <- seq((phi1/180)*pi, (phi2/180)*pi, l=n) + runif(n, (phi_n/180)*pi*-1, (phi_n/180)*pi)
  
  # The molecule length (projection) on the diagram is a function of the twist (phi) angle
  l <- Mod(cos(phi))*l
  
  # Once the length goes below the width - limit it to a minimum of width
  l[l < w] <- w
  
  ## Make diagram
  # Set parameters (these are purely a stylistic choice)
  par(xaxs="i", yaxs="i", mar=c(0.8,0.8,0.8,0.8), bg="white")

  # Initialise an empty plot of the correct x and y dimensions
  plot(1,
       xlim = c(0, right),
       ylim = c(0, top),
       type = 'n',
       axes = FALSE,
       ann = FALSE,
       asp = 1
  )

  # Draw background rectangle and fill colour
  polygon(x = c(0, 0, right, right),
          y = c(0, top, top, 0),
          col = bg_col,
          border = NA)

  # Plot LC molecules
  if(mol == "rect"){
  # RECTANGLES
  # Generate rectangle corner coordinates
  rects <- rects(x=x, y=y, angle=theta, length=l, width=w)

  # Plot each rectangle
  for(i in 1:nrow(rects)){
    polygon(c(rects$p1x[i], rects$p2x[i], rects$p3x[i], rects$p4x[i]),
            c(rects$p1y[i], rects$p2y[i], rects$p3y[i], rects$p4y[i]),
            col = lc_col,
            border = lc_border)
  }
  }

  if(mol == "el"){
    # ELLIPSES
    # Generate ellipse perimeter coordinates
    for(i in 1:n){

    elipse <- elipses(x=x[i], y=y[i],
                       angle=theta[i],
                       major=l[i]/2,
                       minor=w/2,
                       res=50)

    polygon(x=elipse$x, y=elipse$y,
            col = lc_col,
            border = lc_border)
    }
  }


  # This is a little ineligant - but I draw a thin rectangle of height (or width l)
  # around the whole diagram - This stops the plotting of fractions of molecules outside
  # the border (covers them up)
  rect(xleft=0, xright=right, ybottom=top,  ytop=top+l,  col="white", border = NA) # top
  rect(xleft=0, xright=right, ybottom=0-l, ytop=0, col="white", border = NA) # bottom
  rect(xleft=0-l, xright=0, ybottom=0-l, ytop=top+l,  col="white", border = NA) # left
  rect(xleft=right,  xright=right+l, ybottom=0-l, ytop=top+l,  col="white", border = NA) # right

  # Add substrates
  rect(xleft=0, xright=right, ybottom=top-strate2,  ytop=top,  col=strate2_col, border = strate2_border) # top
  rect(xleft=0, xright=right, ybottom=0, ytop=0+strate1, col=strate1_col, border = strate1_border) # bottom

  # Draw border last so it is on top of everything
  polygon(x = c(0, 0, right, right),
          y = c(0, top, top, 0),
          col = NA,
          border = bg_border)
}
dickie-roper/lcdiagrammer documentation built on Nov. 4, 2019, 10:31 a.m.