R6 Interface To Chipmunk2d Physics Library • Chipmunkbasic

chipmunkbasic

chipmunkbasic is a wrapper around the Chipmunk2d rigid body physics simulation library.

chipmunkbasic is just the simulator. To actually render the positions of bodies in the simulation you’ll need to use ggplot2, cairocore or something else

Read the online documentation here

Chipmunk2d

  • Chipmunk2d is a C library for simulating rigid body physics
  • chipmunkcore is a very low-level wrapper around the C library, providing 1-to-1 mapping between R functions and the core C library
  • chipmunkbasic provides a nicer wrapper around chipmunkcore

Pre-requisites

You’ll need to install the Chipmunk2d library on your system. See the README for chipmunkcore for more information

Installation

Install this package from GitHub with:

# install.package('remotes') remotes::install_github('coolbutuseless/chipmunkcore') remotes::install_github('coolbutuseless/chipmunkbasic')

Vignettes

  • Basic Circles shows how circles can be added to a scene
  • Basic Boxes shows how boxes can be added to a scene and rendered in ggplot
  • Galton board
  • Plop shows a large bowling ball being projected into a bucket of elastic circles
  • Plop (polygon) shows a large triangle (with initial angular velocity) being projected into a bucket of elastic circles
  • Inevitable Destruction shows a bowling ball destroying a tower of blocks
  • Inevitable Destruction 2 more gratuitous destruction

ToDo

  • Add constraints and joints

Galton Board

For full code, see the vignette

Thanks to Esteban Moro for fine-tuning this simulation, and contributing his changes.

A simple simulation

# library(chipmunkcore) library(chipmunkbasic) library(ggplot2) set.seed(1) #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Initialize a simulation space #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cm <- Chipmunk$new() #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Add fixed segments #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cm$add_static_segment(-20, 10, -5, 0) cm$add_static_segment( 20, 10, 5, 0) #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Fetch all the segments. Use for plotting #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ segments_df <- cm$get_static_segments() #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Add some circles #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (i in 1:10) { cm$add_circle( x = runif(1, -20, 20), y = runif(1, 10, 50), vx = 10 * rnorm(1), vy = 10 * rnorm(1) ) } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Get the current positions of the circles as a data.frame #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ circles <- cm$get_circles() circles #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Prepare the directory for output images #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ root_dir <- here::here("man/figures/") png_dir <- file.path(root_dir, "png") unlink(list.files(png_dir, pattern = "*.png", full.names = TRUE)) for (frame in 1:45) { #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Advance the simulation #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cm$advance(5) #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Get the circles in their new locations #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ circles <- cm$get_circles() #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Plot everything #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ p <- ggplot(circles) + geom_point(aes(x, y, colour = as.factor(idx)), size = 4, na.rm=TRUE) + geom_segment(data = segments_df, aes(x = x1, y = y1, xend = x2, yend = y2)) + coord_fixed() + # theme_void() + theme_minimal() + xlim(-20, 20) + ylim(-10, 50) + theme(legend.position = 'none') ggsave(sprintf("man/figures/png/%04i.png", frame), p, width = 6, height = 6) } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ffmpeg/gifsicle to create animations # - create mp4 from PNG files (use in vignettes) # - create gif from mp4 (use in github readme) # - simplify gif with gifsicle #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ root_name <- "simple" mp4_name <- paste0(root_dir, "/", root_name, ".mp4") tmp_name <- tempfile(fileext = ".gif") gif_name <- paste0(root_dir, "/", root_name, ".gif") system(glue::glue("ffmpeg -y -framerate 10 -pattern_type glob -i 'man/figures/png/*.png' -c:v libx264 -pix_fmt yuv420p -s 800x800 '{mp4_name}'")) system(glue::glue("ffmpeg -y -i '{mp4_name}' -filter_complex 'fps=30,scale=800:-1:flags=lanczos,split [o1] [o2];[o1] palettegen [p]; [o2] fifo [o3];[o3] [p] paletteuse' '{tmp_name}'")) system(glue::glue("gifsicle -O99 -o '{gif_name}' -k 128 '{tmp_name}'")) unlink(mp4_name)

Acknowledgements

  • R Core for developing and maintaining the language.
  • CRAN maintainers, for patiently shepherding packages onto CRAN and maintaining the repository

Links

  • Browse source code

License

  • MIT + file LICENSE

Citation

  • Citing chipmunkbasic

Developers

  • mikefc Maintainer

Dev status

  • Lifecycle: experimental

Từ khóa » Chipmunk2d