---
title: "Blitting"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{Blitting}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---
```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>"
)
set.seed(1)
```
```{r setup, echo = FALSE}
library(nara)
```
[Blitting](https://en.wikipedia.org/wiki/Bit_blit) is a term used in computer
graphics to describe the copying of whole or part of one image into another.
This copying is optinised for speed and forms a significant part of the
underlying mechanics for 2D games and interactive applications. For example:
* putting a players character on the scrolling background in a game
* Assembling a background image from a small library of tiled images
* Placing pre-rendered pieces on a game board
`{nara}` includes two blitting functions:
* `nr_blit()`
* Blit a single source image at one (or multiple) locations in the destination
image.
* `nr_blit_multi()`
* Define a complex sequence of blitting operations using a data.frame
# `nr_blit()`
Use `nr_blit()` when you want to use a single source image only
### Blit a single image
```{r}
library(nara)
# Create a canvas to draw on
w <- 300
h <- 300
nr <- nr_new(w, h, 'grey90')
# Place a deer on the canvas
nr_blit(nr, deer[[1]], w/2, h/2)
plot(nr)
```
### Blit a single image to multiple locations
```{r}
# Create a canvas to draw on
nr <- nr_new(w, h, 'grey90')
# Place a deer on the canvas at many locations
xs <- runif(20, 0, w)
ys <- runif(20, 0, h)
nr_blit(nr, deer[[1]], xs, ys)
plot(nr)
```
### Blit a single image to multiple locations with varying angles and scales
```{r}
# Create a canvas to draw on
nr <- nr_new(w, h, 'grey90')
# Place a deer on the canvas at many locations
xs <- runif(20, 0, w)
ys <- runif(20, 0, h)
angles <- runif(20, 0, 2*pi)
scales <- runif(20, 0.5, 2)
nr_blit(nr, deer[[1]], xs, ys, angle = angles, scale = scales)
plot(nr)
```
# `nr_blit_multi()`
If you have multiple source images to blit, there are two possible approaches:
* Loop over the images and blit them one-at-a-time with `nr_blit()`
* Set-up a configuration data.frame and blit them all-at-once with `nr_blit_multi()`
For most simple tasks, `nr_blit()` should be sufficient.
For larger structures, it may be useful to store blitting parameters in a data.frame
for organisation purposes.
The `{nara}` packages includes a `tileset` (a list of nativerasters which
can *tile* together to form an image) and a `tileset_config` giving one
possible arrangement of tiles.
Combining `tileset` with `tileset_config` in `nr_blit_multi()` creates a
complex image with a single function call.
```{r}
head(tileset_config)
w <- 70 * 11
h <- 70 * 8
nr <- nr_new(w, h, fill = 'lightblue')
nr_blit_multi(nr, tileset, config = tileset_config)
plot(nr)
```
### Blit with a mask
`{nara}` supports masked rendering of most drawing operations.
`blit_mask_begin()` and `blit_mask_end()` are used to delineate the use
of a mask on an image.
```{r}
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Setup a drawing canvas and an image to use as a mask
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
w <- 300
h <- 300
canvas <- nr_new(w, h, fill = 'lightblue')
mask <- nr_new(w, h, fill = 'transparent')
# Set the top-left area of the mask to be the active area by making it
# not transparent
nr_rect(mask, x=0, y=0, w=w/2, h=h/2)
plot(mask)
# Attach the mask to the canvas
nr_mask_begin(canvas, mask)
{
# Draw random deer on the image -
xs <- runif(50, 0, w)
ys <- runif(50, 0, h)
nr_blit(canvas, deer[[1]], xs, ys)
}
nr_mask_end(canvas) # Finalise the masked operation
plot(canvas)
```