--- 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