jigsawR / quarto /tutorials /basic-usage.qmd
pjt222's picture
Upload folder using huggingface_hub
bfccb56 verified
---
title: "Basic Usage Tutorial"
subtitle: "Step-by-step guide to creating your first puzzles"
---
```{r}
#| label: setup
#| include: false
# Flexible path: works from project root (Quarto) or quarto/tutorials/ (RStudio interactive)
setup_path <- if (file.exists("quarto/_setup.R")) "quarto/_setup.R" else "../_setup.R"
source(setup_path)
```
## Introduction
This tutorial walks you through creating puzzles with jigsawR, from simple examples to more complex configurations.
## Step 1: Installation
```{r}
#| label: installation
#| eval: false
# Install from GitHub
devtools::install_github("pjt222/jigsawR")
# Load the package
library(jigsawR)
```
## Step 2: Your First Puzzle
Let's create a simple rectangular puzzle. Choose your approach:
::: {.panel-tabset}
## ggpuzzle
The ggpuzzle approach integrates with ggplot2 for quick visualization:
```{r}
#| label: first-puzzle-ggpuzzle
#| fig-align: center
library(ggplot2)
library(viridis)
ggplot() +
geom_puzzle_rect(
aes(fill = after_stat(piece_id)),
cols = 4, rows = 3,
width = 400, height = 300,
seed = 42
) +
scale_fill_viridis_c(name = "Piece ID") +
coord_fixed() +
theme_minimal() +
labs(title = "My First Puzzle")
```
::: {.callout-tip}
`geom_puzzle_rect()` computes piece geometry and provides `piece_id`, `row`, `col` for mapping.
:::
## API
The API approach gives you full control and access to the SVG data:
```{r}
#| label: first-puzzle-api
# Generate a 3x4 rectangular puzzle
result <- generate_puzzle(
type = "rectangular",
grid = c(3, 4), # 3 rows, 4 columns
size = c(300, 400), # height=300mm, width=400mm
seed = 42, # For reproducibility
fill_palette = "viridis"
)
# What did we get?
n_pieces <- length(result$pieces)
canvas_w <- result$canvas_size[1]
canvas_h <- result$canvas_size[2]
cli::cli_alert_info("Number of pieces: {n_pieces}")
cli::cli_alert_info("Canvas size: {canvas_w} x {canvas_h} mm")
# Visualize
render_puzzle_preview(result)
```
::: {.callout-tip}
The API returns a list with `$svg_content`, `$pieces`, `$canvas_size`, and `$files`.
:::
:::
## Step 3: Save Your Puzzle
::: {.panel-tabset}
## ggpuzzle
```{r}
#| label: save-puzzle-ggpuzzle
#| fig-align: center
# Save ggplot as PNG
p <- ggplot() +
geom_puzzle_rect(
aes(fill = after_stat(piece_id)),
cols = 4, rows = 3,
seed = 42
) +
scale_fill_viridis_c(guide = "none") +
coord_fixed() +
theme_puzzle()
print(p)
# ggsave("my_puzzle.png", p, width = 8, height = 6, dpi = 300)
```
## API
```{r}
#| label: save-puzzle-api
#| eval: false
# Save as SVG (from API result)
writeLines(result$svg_content, "my_puzzle.svg")
```
:::
::: {.callout-note}
API generates SVG files, while ggpuzzle uses ggplot2's `ggsave()` for PNG/PDF export.
:::
## Step 4: Try Different Puzzle Types
### Hexagonal
::: {.panel-tabset}
## ggpuzzle
```{r}
#| label: type-hexagonal-ggpuzzle
#| fig-align: center
ggplot() +
geom_puzzle_hex(
aes(fill = after_stat(piece_id)),
rings = 3,
seed = 42
) +
scale_fill_viridis_c(option = "plasma", guide = "none") +
coord_fixed() +
theme_puzzle() +
labs(title = "Hexagonal Puzzle")
```
## API
```{r}
#| label: type-hexagonal-api
hex_result <- generate_puzzle(
type = "hexagonal",
grid = c(3), # 3 rings
size = c(200), # 200mm diameter
seed = 42,
fill_palette = "plasma"
)
render_puzzle_preview(hex_result)
```
:::
### Concentric
::: {.panel-tabset}
## ggpuzzle
```{r}
#| label: type-concentric-ggpuzzle
#| fig-align: center
ggplot() +
geom_puzzle_conc(
aes(fill = after_stat(ring)),
rings = 3,
seed = 42
) +
scale_fill_viridis_c(option = "cividis", name = "Ring") +
coord_fixed() +
theme_puzzle() +
labs(title = "Concentric Puzzle")
```
## API
```{r}
#| label: type-concentric-api
conc_result <- generate_puzzle(
type = "concentric",
grid = c(3), # 3 rings
size = c(200), # 200mm diameter
seed = 42,
fill_palette = "cividis"
)
render_puzzle_preview(conc_result)
```
:::
### Voronoi
::: {.panel-tabset}
## ggpuzzle
```{r}
#| label: type-voronoi-ggpuzzle
#| fig-align: center
ggplot() +
geom_puzzle_voronoi(
aes(fill = after_stat(piece_id)),
n_cells = 20,
width = 250, height = 200,
seed = 42
) +
scale_fill_viridis_c(option = "turbo", guide = "none") +
coord_fixed() +
theme_puzzle() +
labs(title = "Voronoi Puzzle")
```
## API
```{r}
#| label: type-voronoi-api
vor_result <- generate_puzzle(
type = "voronoi",
grid = c(20), # 20 cells
size = c(200, 250), # height=200mm, width=250mm
seed = 42,
fill_palette = "turbo"
)
render_puzzle_preview(vor_result)
```
:::
## Step 5: Customize Parameters
### Change Separation
::: {.panel-tabset}
## ggpuzzle
```{r}
#| label: separation-modes-ggpuzzle
#| fig-align: center
make_offset_plot <- function(off) {
ggplot() +
geom_puzzle_rect(
aes(fill = after_stat(piece_id)),
cols = 3, rows = 2,
offset = off,
seed = 42
) +
scale_fill_viridis_c(guide = "none") +
coord_fixed() +
theme_puzzle() +
labs(title = paste0("offset = ", off))
}
print(make_offset_plot(0) + make_offset_plot(10) + make_offset_plot(20))
```
## API
```{r}
#| label: separation-modes-api
#| layout-ncol: 3
#| fig-cap:
#| - "Complete puzzle (offset = 0)"
#| - "Slightly separated (offset = 10)"
#| - "More separated (offset = 20)"
# Generate with different offset values
r0 <- generate_puzzle(type = "rectangular", grid = c(2, 3), size = c(200, 300), offset = 0, seed = 42, fill_palette = "viridis")
r10 <- generate_puzzle(type = "rectangular", grid = c(2, 3), size = c(200, 300), offset = 10, seed = 42, fill_palette = "viridis")
r20 <- generate_puzzle(type = "rectangular", grid = c(2, 3), size = c(200, 300), offset = 20, seed = 42, fill_palette = "viridis")
render_puzzle_preview(r0)
render_puzzle_preview(r10)
render_puzzle_preview(r20)
```
:::
### Change Colors
The ggpuzzle approach makes it easy to apply different color schemes using ggplot2's scale functions.
```{r}
#| label: color-palettes-ggpuzzle
#| layout-ncol: 2
#| fig-cap:
#| - "Plasma palette"
#| - "Magma palette"
print(ggplot() +
geom_puzzle_hex(
aes(fill = after_stat(piece_id)),
rings = 2, diameter = 150, seed = 42
) +
scale_fill_viridis_c(option = "plasma", guide = "none") +
coord_fixed() +
theme_puzzle() +
labs(title = "Plasma"))
print(ggplot() +
geom_puzzle_hex(
aes(fill = after_stat(piece_id)),
rings = 2, diameter = 150, seed = 42
) +
scale_fill_viridis_c(option = "magma", guide = "none") +
coord_fixed() +
theme_puzzle() +
labs(title = "Magma"))
```
::: {.callout-note}
For the API approach, colors are controlled through SVG styling. See the [Customization Tutorial](customization.qmd) for advanced coloring techniques.
:::
## Step 6: Reproducibility
The `seed` parameter ensures you get the same puzzle every time:
::: {.panel-tabset}
## ggpuzzle
```{r}
#| label: reproducibility-ggpuzzle
#| layout-ncol: 2
#| fig-cap:
#| - "seed = 42"
#| - "seed = 123"
# Same seed produces identical geometry
plot_with_seed <- function(s) {
ggplot() +
geom_puzzle_hex(
aes(fill = after_stat(piece_id)),
rings = 2,
seed = s
) +
scale_fill_viridis_c(guide = "none") +
coord_fixed() +
theme_puzzle() +
labs(title = paste("seed =", s))
}
print(plot_with_seed(42))
print(plot_with_seed(123))
```
## API
```{r}
#| label: reproducibility-api
# Same seed = same puzzle
p1 <- generate_puzzle(type = "hexagonal", grid = c(2), size = c(100), seed = 42)
p2 <- generate_puzzle(type = "hexagonal", grid = c(2), size = c(100), seed = 42)
identical(p1$svg_content, p2$svg_content) # TRUE
# Different seed = different puzzle
p3 <- generate_puzzle(type = "hexagonal", grid = c(2), size = c(100), seed = 123)
identical(p1$svg_content, p3$svg_content) # FALSE
```
:::
::: {.callout-tip}
Both approaches use the same deterministic RNG, so `seed = 42` generates identical piece shapes whether you use the API or ggpuzzle.
:::
## Summary
You've learned to:
1. Install and load jigsawR
2. Generate puzzles using both **API** and **ggpuzzle** approaches
3. Save puzzles as SVG (API) or PNG (ggpuzzle)
4. Create different puzzle types (rectangular, hexagonal, concentric, voronoi, random, snic)
5. Customize offset and colors
6. Use seeds for reproducibility
**Choosing an approach:**
- **API** (`generate_puzzle()`): Best for SVG export, programmatic manipulation, and custom rendering
- **ggpuzzle** (`geom_puzzle_*()`): Best for quick visualization, ggplot2 integration, and color customization
## Next Steps
- [Customization Tutorial](customization.qmd) - Colors, themes, and advanced styling
- [Fusion Groups Tutorial](fusion-groups.qmd) - Merge pieces with PILES notation
- [API Reference](../api/generate-puzzle.qmd) - Complete parameter documentation