Title: | Generates Polygon Straight Skeletons and 3D Bevels |
---|---|
Description: | Generates polygon straight skeletons and 3D models. Provides functions to create and visualize interior polygon offsets, 3D beveled polygons, and 3D roof models. |
Authors: | Tyler Morgan-Wall [aut, cph, cre] |
Maintainer: | Tyler Morgan-Wall <[email protected]> |
License: | GPL-3 |
Version: | 0.1.3 |
Built: | 2024-11-07 05:33:21 UTC |
Source: | https://github.com/tylermorganwall/raybevel |
This function generates a beveled 3D polygon model from the modified straight skeleton with pre-existing polygons generated from the 'generate_beveled_polygon' function when 'return_skeleton_polygons = TRUE'.
change_polygon_bevel( skeleton_polygons, bevel_offsets = NULL, bevel_heights = NULL, set_max_height = FALSE, max_height = 1, vertical_offset = 0, base = TRUE, base_height = NA, raw_offsets = FALSE, raw_heights = FALSE, swap_yz = TRUE, progress = TRUE, sides = FALSE, double_sided = FALSE, scale_all_max = FALSE, material = material_list(), bevel_material = NA, verbose = FALSE )
change_polygon_bevel( skeleton_polygons, bevel_offsets = NULL, bevel_heights = NULL, set_max_height = FALSE, max_height = 1, vertical_offset = 0, base = TRUE, base_height = NA, raw_offsets = FALSE, raw_heights = FALSE, swap_yz = TRUE, progress = TRUE, sides = FALSE, double_sided = FALSE, scale_all_max = FALSE, material = material_list(), bevel_material = NA, verbose = FALSE )
skeleton_polygons |
Default 'NULL'. A straight skeleton generated from the 'generate_beveled_polygon' function when 'return_skeleton_polygons = TRUE'. |
bevel_offsets |
Default 'NULL'. The offset(s) of the bevel. |
bevel_heights |
Default is set to 'bevel_offsets'. Numeric vector specifying the heights of the bevels. Must be of the same length as 'bevel_offsets'. |
set_max_height |
Default 'FALSE'. A logical flag that controls whether to set the max height of the polygon based on the 'max_height' argument. |
max_height |
Default '1'. The maximum height of the polygon. |
vertical_offset |
Default '0'. The vertical offset of the polygon. |
base |
Default 'TRUE'. A logical flag that controls whether to generate the bottom of the polygon. |
base_height |
Default 'NA'. Height of the base, defaulting to the 'min(bevel_heights) + vertical_offset' . |
raw_offsets |
Default 'FALSE'. A logical flag indicating whether the 'bevel_offsets' are already in raw format and do not need to be multiplied by the maximum time of the skeleton. |
raw_heights |
Default 'FALSE'. A logical flag indicating whether the 'bevel_heights' are already in raw format and do not need to be multiplied by the maximum time of the skeleton. |
swap_yz |
Default 'TRUE'. A logical flag that controls whether to swap the y and z coordinates in the resulting mesh. If 'TRUE', the y and z coordinates will be swapped. |
progress |
Default 'TRUE'. Whether to display a progress bar. |
sides |
Default 'FALSE'. A logical flag on whether to draw the sides. This will automatically be set to 'TRUE' if 'base = TRUE' and the 'base_height' is less than 'vertical_offset'. |
double_sided |
Default 'FALSE'. A logical flag that controls whether the polygon should be double-sided. |
scale_all_max |
Default 'FALSE'. If passing in a list of multiple skeletons with polygons, whether to scale each polygon to the overall max height, or whether to scale each max height to the maximum internal distance in the polygon. |
material |
Default 'material_list()'. Interface to set the color/appearance/material options for the resulting 'ray_mesh' mesh. |
bevel_material |
Default 'NA', uses the material specified in 'material'. Interface to set the color/appearance/material options for the resulting 'ray_mesh' bevel mesh. |
verbose |
Default 'FALSE'. A logical flag to control whether additional timing information should be displayed. |
A 3D mesh of the beveled polygon model.
# Skeletonize a complex {sf} object and set return_skeleton_polygons = TRUE in # generate_beveled_polygon(). This returns skeleton object with polygons included, which # allows for quickly generating 3D models with different bevels. if(run_documentation()) { library(rayrender) library(rayvertex) us_states = spData::us_states cali = us_states[us_states$NAME == "California",] cali_skeleton = skeletonize(cali) plot_skeleton(cali_skeleton) # We add manual offsets to ensure that the polygon can be morphed all along its interior bevel = generate_bevel(manual_offsets = seq(0,1,by=0.01), max_height=0.5) bevel_model_cali = generate_beveled_polygon(cali_skeleton, bevel_offsets = bevel, return_skeleton_polygons = TRUE) bevel_new = change_polygon_bevel(bevel_model_cali, bevel_offsets = generate_bevel(max_height=0.5, bevel_end=0.5)) |> center_mesh() scene_base = xz_rect(xwidth=100,zwidth=100, material=diffuse(color="grey20", checkercolor="white")) |> add_object(sphere(y=8,z=10,x=-3,material=light(intensity=100))) |> add_object(sphere(y=800,z=10,x=-3,radius=100,material=light(intensity=5))) raymesh_model(bevel_new, y=0.5, override_material = TRUE, material = diffuse(color="purple")) |> add_object(scene_base) |> render_scene(lookfrom=c(0,30,-10), sample_method = "sobol_blue",clamp_value = 10, width=800,height=800,fov=0,ortho_dimensions=c(12,12)) } # Change to a smooth bevel if(run_documentation()) { new_bevel = generate_bevel("circular", bevel_start = 0, bevel_end=1) bevel_new = change_polygon_bevel(bevel_model_cali, bevel_offsets = new_bevel, solid ) |> center_mesh() raymesh_model(bevel_new, override_material = TRUE, y=1,material = diffuse(color="purple")) |> add_object(scene_base) |> render_scene(lookfrom=c(0,30,-10), sample_method = "sobol_blue",clamp_value = 10, width=800,height=800,fov=0,ortho_dimensions=c(12,12)) } # Make a complex bevel if(run_documentation()) { complex_coords = generate_complex_bevel( bevel_type = c("angled","flat", "angled", "flat"), bevel_start = head(seq(0,1,by=0.05),-1), bevel_end = tail(seq(0,1,by=0.05),-1), overall_height = 1, angle = c(45,45,15,15), reverse = c(FALSE, FALSE,TRUE,TRUE), plot_bevel = TRUE ) bevel_new = change_polygon_bevel(bevel_model_cali, bevel_offsets = complex_coords) |> center_mesh() raymesh_model(bevel_new, override_material = TRUE, y=1,material = diffuse(color="purple")) |> add_object(scene_base) |> render_scene(lookfrom=c(0,30,-20), sample_method = "sobol_blue",clamp_value = 10, width=800,height=800,fov=0,ortho_dimensions=c(12,12)) } # Quickly generate new bevels to inflate California like a balloon using the arctan function. if(run_documentation()) { inflate_california = function(magnitudes) { for(val in magnitudes) { bevel_new = change_polygon_bevel(bevel_model_cali, bevel_heights = 1/2*atan(seq(0,val,length.out=100)), bevel_offsets = seq(0,1, length.out=100), base = TRUE) |> translate_mesh(c(-120.49,0,-38.72)) raymesh_model(bevel_new, y = 0, override_material = TRUE, material = glossy(color="darkred")) |> add_object(scene_base) |> add_object(sphere(x=-30,z=30,y=18,radius=30,material=light(color="white", intensity=5))) |> render_scene(lookfrom=c(-1, 28, -20.32), lookat=c(-1, 1.46, -2), sample_method = "sobol_blue", clamp_value = 10, width=800,height=800,fov=20,samples=256) } } inflate_california(c(1,4,16,64)) }
# Skeletonize a complex {sf} object and set return_skeleton_polygons = TRUE in # generate_beveled_polygon(). This returns skeleton object with polygons included, which # allows for quickly generating 3D models with different bevels. if(run_documentation()) { library(rayrender) library(rayvertex) us_states = spData::us_states cali = us_states[us_states$NAME == "California",] cali_skeleton = skeletonize(cali) plot_skeleton(cali_skeleton) # We add manual offsets to ensure that the polygon can be morphed all along its interior bevel = generate_bevel(manual_offsets = seq(0,1,by=0.01), max_height=0.5) bevel_model_cali = generate_beveled_polygon(cali_skeleton, bevel_offsets = bevel, return_skeleton_polygons = TRUE) bevel_new = change_polygon_bevel(bevel_model_cali, bevel_offsets = generate_bevel(max_height=0.5, bevel_end=0.5)) |> center_mesh() scene_base = xz_rect(xwidth=100,zwidth=100, material=diffuse(color="grey20", checkercolor="white")) |> add_object(sphere(y=8,z=10,x=-3,material=light(intensity=100))) |> add_object(sphere(y=800,z=10,x=-3,radius=100,material=light(intensity=5))) raymesh_model(bevel_new, y=0.5, override_material = TRUE, material = diffuse(color="purple")) |> add_object(scene_base) |> render_scene(lookfrom=c(0,30,-10), sample_method = "sobol_blue",clamp_value = 10, width=800,height=800,fov=0,ortho_dimensions=c(12,12)) } # Change to a smooth bevel if(run_documentation()) { new_bevel = generate_bevel("circular", bevel_start = 0, bevel_end=1) bevel_new = change_polygon_bevel(bevel_model_cali, bevel_offsets = new_bevel, solid ) |> center_mesh() raymesh_model(bevel_new, override_material = TRUE, y=1,material = diffuse(color="purple")) |> add_object(scene_base) |> render_scene(lookfrom=c(0,30,-10), sample_method = "sobol_blue",clamp_value = 10, width=800,height=800,fov=0,ortho_dimensions=c(12,12)) } # Make a complex bevel if(run_documentation()) { complex_coords = generate_complex_bevel( bevel_type = c("angled","flat", "angled", "flat"), bevel_start = head(seq(0,1,by=0.05),-1), bevel_end = tail(seq(0,1,by=0.05),-1), overall_height = 1, angle = c(45,45,15,15), reverse = c(FALSE, FALSE,TRUE,TRUE), plot_bevel = TRUE ) bevel_new = change_polygon_bevel(bevel_model_cali, bevel_offsets = complex_coords) |> center_mesh() raymesh_model(bevel_new, override_material = TRUE, y=1,material = diffuse(color="purple")) |> add_object(scene_base) |> render_scene(lookfrom=c(0,30,-20), sample_method = "sobol_blue",clamp_value = 10, width=800,height=800,fov=0,ortho_dimensions=c(12,12)) } # Quickly generate new bevels to inflate California like a balloon using the arctan function. if(run_documentation()) { inflate_california = function(magnitudes) { for(val in magnitudes) { bevel_new = change_polygon_bevel(bevel_model_cali, bevel_heights = 1/2*atan(seq(0,val,length.out=100)), bevel_offsets = seq(0,1, length.out=100), base = TRUE) |> translate_mesh(c(-120.49,0,-38.72)) raymesh_model(bevel_new, y = 0, override_material = TRUE, material = glossy(color="darkred")) |> add_object(scene_base) |> add_object(sphere(x=-30,z=30,y=18,radius=30,material=light(color="white", intensity=5))) |> render_scene(lookfrom=c(-1, 28, -20.32), lookat=c(-1, 1.46, -2), sample_method = "sobol_blue", clamp_value = 10, width=800,height=800,fov=20,samples=256) } } inflate_california(c(1,4,16,64)) }
Generate 2D Bevel Profile for 3D Polygons
generate_bevel( bevel_type = "angled", bevel_start = 0, bevel_end = 0.2, max_height = 1, angle = NULL, curve_points = 50, reverse = FALSE, flip = FALSE, initial_height = 0, add_end_points = TRUE, manual_offsets = NULL, step_epsilon = 1e-08, plot_bevel = FALSE, set_minimum_zero = TRUE, zero_offset_epsilon = 1e-05 )
generate_bevel( bevel_type = "angled", bevel_start = 0, bevel_end = 0.2, max_height = 1, angle = NULL, curve_points = 50, reverse = FALSE, flip = FALSE, initial_height = 0, add_end_points = TRUE, manual_offsets = NULL, step_epsilon = 1e-08, plot_bevel = FALSE, set_minimum_zero = TRUE, zero_offset_epsilon = 1e-05 )
bevel_type |
Character 'angled'. Type of the bevel, one of the following options: - "circular": Creates a rounded bevel resembling a quarter-circle. - "exp": Creates an exponential curve, starting slow and accelerating. - "bump": Creates a bump-like profile, rising and falling within the coverage. - "step": Generates a step-like bevel with a flat top. - "block": Generates a block-like bevel, jumping straight to the max_height and back to the base. - "angled": Generates a straight angled bevel. You can optionally set the 'angle' parameter for this bevel. - "flat": Generates a flat area. |
bevel_start |
Default '0'. The starting point of the bevel along the curve, ranges between 0 and 1. |
bevel_end |
Default '0.2'. The ending point of the bevel along the curve, ranges between 0 and 1. |
max_height |
Default '1'. The maximum height of the bevel, as measured from the initial height. |
angle |
Default 'NULL'. Optional angle parameter in degrees for angular bevels. |
curve_points |
Default '50'. Number of points to plot for curve-based bevels. |
reverse |
Default 'FALSE'. If 'TRUE', the curve is reversed vertically. |
flip |
Default 'FALSE'. If 'TRUE', the curve is flipped horizontally. |
initial_height |
Default '0'. The initial height from which the bevel starts. The bevel is rescaled to fit within the range from initial_height to max_height. |
add_end_points |
Default 'TRUE'. Whether to ensure there is a point at zero and a point at one. |
manual_offsets |
Default 'NULL', none. This will force the bevel to add a point (interpolating between the two nearest points) at the specified offsets. This is useful when you want to add points at specific distances along the curve. |
step_epsilon |
Default '1e-5'. The size for the small percentage step when using a step bevel. |
plot_bevel |
Default 'FALSE'. Whether to plot the bevel. |
set_minimum_zero |
Default ‘TRUE'. Whether to offset the lowest point of the bevel so it’s at zero. |
zero_offset_epsilon |
Default '1e-5'. Amount to offset the bevel to ensure no self-intersection with the base. |
List containing 'x' and 'y', which are the coordinates of the 2D bevel profile.
# Generate a single bevel profile and plot it coords = generate_bevel("circular", 0.2, 0.8, 0.2, plot_bevel = TRUE) # Plot all bevel profiles in a grid plot_all_bevels = function() { oldpar = par(mfrow = c(4, 3), mai = c(0.2, 0.2, 0.5, 0.2)) on.exit(par(oldpar)) max_height = c(1,1,1,1) types = rep(c("circular", "exp", "bump", "step", "block", "angled"),2) reverses = c(rep(FALSE,6),rep(TRUE,6)) for(i in seq_len(length(types))) { coords = generate_bevel(types[i], 0.2, 0.8, 1, flip = TRUE, angle = 45, reverse = reverses[i], plot_bevel = TRUE) } } plot_all_bevels()
# Generate a single bevel profile and plot it coords = generate_bevel("circular", 0.2, 0.8, 0.2, plot_bevel = TRUE) # Plot all bevel profiles in a grid plot_all_bevels = function() { oldpar = par(mfrow = c(4, 3), mai = c(0.2, 0.2, 0.5, 0.2)) on.exit(par(oldpar)) max_height = c(1,1,1,1) types = rep(c("circular", "exp", "bump", "step", "block", "angled"),2) reverses = c(rep(FALSE,6),rep(TRUE,6)) for(i in seq_len(length(types))) { coords = generate_bevel(types[i], 0.2, 0.8, 1, flip = TRUE, angle = 45, reverse = reverses[i], plot_bevel = TRUE) } } plot_all_bevels()
This function generates a beveled 3D polygon from a straight skeleton.
generate_beveled_polygon( skeleton, bevel_offsets = generate_bevel(), bevel_heights = NULL, set_max_height = FALSE, max_height = NA, vertical_offset = 0, base = TRUE, base_height = 0, raw_offsets = FALSE, raw_heights = FALSE, swap_yz = TRUE, progress = TRUE, double_sided = FALSE, sides = FALSE, return_skeleton_polygons = FALSE, scale_all_max = FALSE, material = material_list(), bevel_material = NA, verbose = FALSE )
generate_beveled_polygon( skeleton, bevel_offsets = generate_bevel(), bevel_heights = NULL, set_max_height = FALSE, max_height = NA, vertical_offset = 0, base = TRUE, base_height = 0, raw_offsets = FALSE, raw_heights = FALSE, swap_yz = TRUE, progress = TRUE, double_sided = FALSE, sides = FALSE, return_skeleton_polygons = FALSE, scale_all_max = FALSE, material = material_list(), bevel_material = NA, verbose = FALSE )
skeleton |
Default 'NULL'. A straight skeleton generated from the 'skeletonize' function. |
bevel_offsets |
Default 'NULL'. The offset(s) of the bevel. |
bevel_heights |
Default is set to 'bevel_offsets'. Numeric vector specifying the heights of the bevels. Must be of the same length as 'bevel_offsets'. |
set_max_height |
Default 'FALSE'. A logical flag that controls whether to set the max height of the roof based on the 'max_height' argument. |
max_height |
Default '1'. The maximum height of the polygon. |
vertical_offset |
Default '0'. The vertical offset of the polygon. |
base |
Default 'TRUE'. A logical flag that controls whether to generate the bottom of the polygon. |
base_height |
Default 'NA'. Height of the base, defaulting to 'min(bevel_heights) + vertical_offset' . |
raw_offsets |
Default 'FALSE'. A logical flag indicating whether the 'bevel_offsets' are already in raw format and do not need to be multiplied by the maximum time of the skeleton. |
raw_heights |
Default 'FALSE'. A logical flag indicating whether the 'bevel_heights' are already in raw format and do not need to be multiplied by the maximum time of the skeleton. |
swap_yz |
Default 'TRUE'. A logical flag that controls whether to swap the y and z coordinates in the resulting mesh. If 'TRUE', the y and z coordinates will be swapped. |
progress |
Default 'TRUE'. A logical flag to control whether a progress bar is displayed during roof generation. |
double_sided |
Default 'FALSE'. A logical flag that controls whether the polygon should be double-sided. |
sides |
Default 'FALSE'. A logical flag on whether to draw the sides. This will automatically be set to 'TRUE' if 'base = TRUE' and the 'base_height' is less than 'vertical_offset'. |
return_skeleton_polygons |
Default 'FALSE'. A logical flag that controls whether to return the skeleton polygons along with the 3D mesh. |
scale_all_max |
Default 'FALSE'. If passing in a list of multiple skeletons with polygons, whether to scale each polygon to the overall max height, or whether to scale each max height to the maximum internal distance in the polygon. |
material |
Default 'material_list()'. Interface to set the color/appearance/material options for the resulting 'ray_mesh' mesh. |
bevel_material |
Default 'NA', uses the material specified in 'material'. Interface to set the color/appearance/material options for the resulting 'ray_mesh' bevel mesh. |
verbose |
Default 'FALSE'. A logical flag to control whether additional timing information should be displayed. |
A 3D mesh of the beveled polygon model.
#Generate vertices and holes vertices = matrix(c(0,0, 7,0, 7,7, 0,7, 0,0), ncol = 2, byrow = TRUE)-3.5 hole_1 = matrix(c(1,1, 2,1, 2,2, 1,2, 1,1), ncol = 2, byrow = TRUE)[5:1,]-3.5 hole_2 = matrix(c(5,5, 6,5, 6,6, 5,6, 5,5), ncol = 2, byrow = TRUE)[5:1,]-3.5 skeleton = skeletonize(vertices, holes = list(hole_1, hole_2)) plot_skeleton(skeleton) #Generate a roof model and specify the material if(run_documentation()) { library(rayrender) library(rayvertex) scene_base = xz_rect(xwidth=100,zwidth=100, material=diffuse(color="grey20", checkercolor="white")) |> add_object(sphere(y=8,z=10,x=-3,material=light(intensity=100))) |> add_object(sphere(y=800,z=10,x=-3,radius=100,material=light(intensity=5))) |> add_object(sphere(x=-10,z=-10,y=5,material=light(color="red", intensity=40))) |> add_object(sphere(x=10,z=-10,y=5,material=light(color="orange", intensity=40))) bevel = generate_bevel("angled", bevel_start = 0, bevel_end = 0.2, max_height=0.25) roof_model = generate_beveled_polygon(skeleton, bevel_offsets = bevel, material = material_list(diffuse="purple")) raymesh_model(roof_model, override_material = FALSE) |> add_object(scene_base) |> render_scene(lookfrom=c(10,30,20), sample_method = "sobol_blue", width=800,height=800,fov=0,ortho_dimensions=c(10,10)) } # Change the bevel to be circular if(run_documentation()) { bevel = generate_bevel("circular", bevel_start = 0, bevel_end = 0.2, max_height=0.25) roof_model = generate_beveled_polygon(skeleton, bevel_offsets = bevel, material = material_list(diffuse="purple")) raymesh_model(roof_model, override_material = FALSE) |> add_object(scene_base) |> render_scene(lookfrom=c(10,30,20), sample_method = "sobol_blue", width=800,height=800,fov=0,ortho_dimensions=c(10,10)) } # Change the bevel to type "bump", change the max height, and raise it off the surface if(run_documentation()) { bevel = generate_bevel("bump", bevel_start = 0, bevel_end = 0.4, max_height=0.25) roof_model = generate_beveled_polygon(skeleton, base_height=1, bevel_offsets = bevel, material = material_list(diffuse="purple")) raymesh_model(roof_model, override_material = FALSE) |> add_object(scene_base) |> render_scene(lookfrom=c(10,30,20), sample_method = "sobol_blue", width=800,height=800,fov=0,ortho_dimensions=c(10,10)) } # Generate a complex bevel and use the exact specified heights if(run_documentation()) { bevel = generate_complex_bevel(c("bump", "exp", "circular","step"), bevel_start = c(0,0.3,0.7,0.95), bevel_end = c(0.1,0.6,0.95,1), reverse = c(F,F,T,F), segment_height = c(0.25,0.5,0.5,4), plot_bevel = TRUE) roof_model = generate_beveled_polygon(skeleton, vertical_offset=0.1, bevel_offsets = bevel, raw_heights = TRUE, material = material_list(diffuse="purple")) raymesh_model(roof_model, override_material = FALSE) |> add_object(scene_base) |> render_scene(lookfrom=c(10,30,20), sample_method = "sobol_blue", width=800,height=800,fov=0,ortho_dimensions=c(10,10)) } # Turn the polygon into a ziggurat, using the step bevel type if(run_documentation()) { offs = seq(0, 1, by = 0.05) bevel = generate_complex_bevel("step", bevel_start = offs[-length(offs)], bevel_end = offs[-1], segment_height = 0.2) roof_model = generate_beveled_polygon(skeleton, vertical_offset=0.2, bevel_offsets = bevel, raw_heights = TRUE, material = material_list(diffuse = "purple")) raymesh_model(roof_model, override_material = FALSE) |> add_object(scene_base) |> render_scene(lookfrom = c(10,30,20), sample_method = "sobol_blue", width = 800, height = 800, fov = 0, ortho_dimensions = c(10,10)) } # Turn the polygon into a smooth wavy slide, taking advantage of vector recycling to flip/reverse if(run_documentation()) { offs = seq(0, 1, by = 0.1) bevel = generate_complex_bevel("exp", bevel_start = offs[-length(offs)], bevel_end = offs[-1], reverse = c(TRUE, FALSE), flip = c(TRUE, FALSE), segment_height = 0.25) roof_model = generate_beveled_polygon(skeleton, vertical_offset=0.2, bevel_offsets = bevel, raw_heights = TRUE, material = material_list(diffuse = "purple")) raymesh_model(roof_model, override_material = FALSE) |> add_object(scene_base) |> render_scene(lookfrom = c(10,30,20), sample_method = "sobol_blue", width = 800, height = 800, fov = 0, ortho_dimensions = c(10,10)) } # Skeletonize and turn an {sf} object into a beveled polygon if(run_documentation()) { us_states = spData::us_states texas = us_states[us_states$NAME == "Texas",] texas_skeleton = skeletonize(texas) plot_skeleton(texas_skeleton) bevel = generate_bevel("angled" , bevel_end=0.3, max_height = 0.3) roof_model_texas = generate_beveled_polygon(texas_skeleton, bevel_offsets = bevel, material = material_list(diffuse = "purple")) |> center_mesh() |> translate_mesh(c(0,0.3,0)) raymesh_model(roof_model_texas, material = diffuse(color="purple")) |> add_object(scene_base) |> add_object(sphere(x=-10,z=-10,y=5,material=light(color="red", intensity=40))) |> add_object(sphere(x=10,z=-10,y=5,material=light(color="orange", intensity=40))) |> render_scene(lookfrom=c(0,10,0),camera_up=c(0,0,1), sample_method = "sobol_blue", width=800,height=800,fov=0, ortho_dimensions=c(15,15)) } # Generate a smooth bevel if(run_documentation()) { bevel = generate_bevel("exp", bevel_start = 0, bevel_end=0.5, max_height=2) roof_model_texas = generate_beveled_polygon(texas_skeleton, bevel_offsets = bevel, material = material_list(diffuse = "purple")) |> center_mesh() |> translate_mesh(c(0,0.5,0)) raymesh_model(roof_model_texas, material = diffuse(color="purple")) |> add_object(scene_base) |> add_object(sphere(x=-10,z=-10,y=5,material=light(color="red", intensity=40))) |> add_object(sphere(x=10,z=-10,y=5,material=light(color="orange", intensity=40))) |> render_scene(lookfrom=c(0,10,0),camera_up=c(0,0,1), sample_method = "sobol_blue", width=800,height=800,fov=0, ortho_dimensions=c(15,15)) }
#Generate vertices and holes vertices = matrix(c(0,0, 7,0, 7,7, 0,7, 0,0), ncol = 2, byrow = TRUE)-3.5 hole_1 = matrix(c(1,1, 2,1, 2,2, 1,2, 1,1), ncol = 2, byrow = TRUE)[5:1,]-3.5 hole_2 = matrix(c(5,5, 6,5, 6,6, 5,6, 5,5), ncol = 2, byrow = TRUE)[5:1,]-3.5 skeleton = skeletonize(vertices, holes = list(hole_1, hole_2)) plot_skeleton(skeleton) #Generate a roof model and specify the material if(run_documentation()) { library(rayrender) library(rayvertex) scene_base = xz_rect(xwidth=100,zwidth=100, material=diffuse(color="grey20", checkercolor="white")) |> add_object(sphere(y=8,z=10,x=-3,material=light(intensity=100))) |> add_object(sphere(y=800,z=10,x=-3,radius=100,material=light(intensity=5))) |> add_object(sphere(x=-10,z=-10,y=5,material=light(color="red", intensity=40))) |> add_object(sphere(x=10,z=-10,y=5,material=light(color="orange", intensity=40))) bevel = generate_bevel("angled", bevel_start = 0, bevel_end = 0.2, max_height=0.25) roof_model = generate_beveled_polygon(skeleton, bevel_offsets = bevel, material = material_list(diffuse="purple")) raymesh_model(roof_model, override_material = FALSE) |> add_object(scene_base) |> render_scene(lookfrom=c(10,30,20), sample_method = "sobol_blue", width=800,height=800,fov=0,ortho_dimensions=c(10,10)) } # Change the bevel to be circular if(run_documentation()) { bevel = generate_bevel("circular", bevel_start = 0, bevel_end = 0.2, max_height=0.25) roof_model = generate_beveled_polygon(skeleton, bevel_offsets = bevel, material = material_list(diffuse="purple")) raymesh_model(roof_model, override_material = FALSE) |> add_object(scene_base) |> render_scene(lookfrom=c(10,30,20), sample_method = "sobol_blue", width=800,height=800,fov=0,ortho_dimensions=c(10,10)) } # Change the bevel to type "bump", change the max height, and raise it off the surface if(run_documentation()) { bevel = generate_bevel("bump", bevel_start = 0, bevel_end = 0.4, max_height=0.25) roof_model = generate_beveled_polygon(skeleton, base_height=1, bevel_offsets = bevel, material = material_list(diffuse="purple")) raymesh_model(roof_model, override_material = FALSE) |> add_object(scene_base) |> render_scene(lookfrom=c(10,30,20), sample_method = "sobol_blue", width=800,height=800,fov=0,ortho_dimensions=c(10,10)) } # Generate a complex bevel and use the exact specified heights if(run_documentation()) { bevel = generate_complex_bevel(c("bump", "exp", "circular","step"), bevel_start = c(0,0.3,0.7,0.95), bevel_end = c(0.1,0.6,0.95,1), reverse = c(F,F,T,F), segment_height = c(0.25,0.5,0.5,4), plot_bevel = TRUE) roof_model = generate_beveled_polygon(skeleton, vertical_offset=0.1, bevel_offsets = bevel, raw_heights = TRUE, material = material_list(diffuse="purple")) raymesh_model(roof_model, override_material = FALSE) |> add_object(scene_base) |> render_scene(lookfrom=c(10,30,20), sample_method = "sobol_blue", width=800,height=800,fov=0,ortho_dimensions=c(10,10)) } # Turn the polygon into a ziggurat, using the step bevel type if(run_documentation()) { offs = seq(0, 1, by = 0.05) bevel = generate_complex_bevel("step", bevel_start = offs[-length(offs)], bevel_end = offs[-1], segment_height = 0.2) roof_model = generate_beveled_polygon(skeleton, vertical_offset=0.2, bevel_offsets = bevel, raw_heights = TRUE, material = material_list(diffuse = "purple")) raymesh_model(roof_model, override_material = FALSE) |> add_object(scene_base) |> render_scene(lookfrom = c(10,30,20), sample_method = "sobol_blue", width = 800, height = 800, fov = 0, ortho_dimensions = c(10,10)) } # Turn the polygon into a smooth wavy slide, taking advantage of vector recycling to flip/reverse if(run_documentation()) { offs = seq(0, 1, by = 0.1) bevel = generate_complex_bevel("exp", bevel_start = offs[-length(offs)], bevel_end = offs[-1], reverse = c(TRUE, FALSE), flip = c(TRUE, FALSE), segment_height = 0.25) roof_model = generate_beveled_polygon(skeleton, vertical_offset=0.2, bevel_offsets = bevel, raw_heights = TRUE, material = material_list(diffuse = "purple")) raymesh_model(roof_model, override_material = FALSE) |> add_object(scene_base) |> render_scene(lookfrom = c(10,30,20), sample_method = "sobol_blue", width = 800, height = 800, fov = 0, ortho_dimensions = c(10,10)) } # Skeletonize and turn an {sf} object into a beveled polygon if(run_documentation()) { us_states = spData::us_states texas = us_states[us_states$NAME == "Texas",] texas_skeleton = skeletonize(texas) plot_skeleton(texas_skeleton) bevel = generate_bevel("angled" , bevel_end=0.3, max_height = 0.3) roof_model_texas = generate_beveled_polygon(texas_skeleton, bevel_offsets = bevel, material = material_list(diffuse = "purple")) |> center_mesh() |> translate_mesh(c(0,0.3,0)) raymesh_model(roof_model_texas, material = diffuse(color="purple")) |> add_object(scene_base) |> add_object(sphere(x=-10,z=-10,y=5,material=light(color="red", intensity=40))) |> add_object(sphere(x=10,z=-10,y=5,material=light(color="orange", intensity=40))) |> render_scene(lookfrom=c(0,10,0),camera_up=c(0,0,1), sample_method = "sobol_blue", width=800,height=800,fov=0, ortho_dimensions=c(15,15)) } # Generate a smooth bevel if(run_documentation()) { bevel = generate_bevel("exp", bevel_start = 0, bevel_end=0.5, max_height=2) roof_model_texas = generate_beveled_polygon(texas_skeleton, bevel_offsets = bevel, material = material_list(diffuse = "purple")) |> center_mesh() |> translate_mesh(c(0,0.5,0)) raymesh_model(roof_model_texas, material = diffuse(color="purple")) |> add_object(scene_base) |> add_object(sphere(x=-10,z=-10,y=5,material=light(color="red", intensity=40))) |> add_object(sphere(x=10,z=-10,y=5,material=light(color="orange", intensity=40))) |> render_scene(lookfrom=c(0,10,0),camera_up=c(0,0,1), sample_method = "sobol_blue", width=800,height=800,fov=0, ortho_dimensions=c(15,15)) }
All arguments are recycled to the length of the longest argument, allowing for the generation of complex and repetitive bevel patterns without manual replication of argument values.
generate_complex_bevel( bevel_type, bevel_start = 0, bevel_end = 1, segment_height = 1, angle = 45, curve_points = 30, reverse = FALSE, flip = FALSE, manual_offsets = NULL, add_end_points = TRUE, plot_bevel = FALSE, overall_height = NA, set_minimum_zero = TRUE, zero_offset_epsilon = 1e-06 )
generate_complex_bevel( bevel_type, bevel_start = 0, bevel_end = 1, segment_height = 1, angle = 45, curve_points = 30, reverse = FALSE, flip = FALSE, manual_offsets = NULL, add_end_points = TRUE, plot_bevel = FALSE, overall_height = NA, set_minimum_zero = TRUE, zero_offset_epsilon = 1e-06 )
bevel_type |
Vector of bevel types. Options are: '"circular"', '"exp"', '"bump"', '"step"', '"block"', '"angled"'. Note that for the '"step"' type, the transition occurs at 'bevel_start'. |
bevel_start |
Numeric vector of values between '0' and '1'. Percentage distance in the interior the polygon at which to begin the corresponding 'bevel_type'. Note that for the '"step"' type, this is ignored. |
bevel_end |
Numeric vector of values between '0' and '1'. Percentage distance in the interior the polygon at which to end the corresponding 'bevel_type'. |
segment_height |
Numeric vector. The maximum heights of each bevel, as measured from the initial height at the end of the previous bevel. |
angle |
Default 'NULL'. Numeric vector. Optional angle parameter in degrees for angular bevels (overrides values in 'max_height'). |
curve_points |
Default '50'. Integer vector of number of points for each curve. |
reverse |
Default 'FALSE'. Whether to reverse each bevel. |
flip |
Default 'FALSE'. Whether to reverse each bevel horizontally. |
manual_offsets |
Default 'NULL', none. This will force the bevel to add a point (interpolating between the two nearest points) at the specified offsets. This is useful when you want to add points at specific distances along the curve. |
add_end_points |
Default 'TRUE'. Whether to ensure there is a point at zero and a point at one. |
plot_bevel |
Default 'FALSE'. Whether to plot the resulting bevel. |
overall_height |
Default 'NA'. Numeric value specifying the overall height of the curve. |
set_minimum_zero |
Default ‘TRUE'. Whether to offset the lowest point of the bevel so it’s at zero. |
zero_offset_epsilon |
Default '1e-5'. Amount to offset the bevel to ensure no self-intersection with the base. |
List containing 'x' and 'y', which are the coordinates of the complex 2D bevel profile
# Generate a complex bevel profile and plot it complex_coords = generate_complex_bevel( bevel_type = c("circular", "bump", "step", "block", "angled"), bevel_start = c(0, 0.2, 0.6, 0.7, 0.9), bevel_end = c(0.2, 0.5, 0.7, 0.8, 1.0), segment_height = c(0.1, 0.2, 0.2, 0.2, 0.4), angle = 45, curve_points = c(50, 50, 50, 1, 1), reverse = c(FALSE, TRUE, FALSE, FALSE, FALSE), plot_bevel = TRUE ) # Create a step function with reverses to generate a square wave pattern complex_coords = generate_complex_bevel( bevel_type = "step", bevel_start = head(seq(0,1,by=0.05),-1), bevel_end = 1, segment_height = 0.1, angle = 45, reverse = c(FALSE, TRUE), plot_bevel = TRUE ) #Generate an increasing sawtooth pattern with angles complex_coords = generate_complex_bevel( bevel_type = "angled", bevel_start = head(seq(0,1,by=0.05),-1), bevel_end = tail(seq(0,1,by=0.05),-1), segment_height = 0.1, angle = c(45,30), reverse = c(FALSE, TRUE), plot_bevel = TRUE ) # Create a step function to turn polygons into a ziggurat (note bevel_end is ignored) complex_coords = generate_complex_bevel( bevel_type = "step", bevel_start = head(seq(0,1,by=0.05),-1), bevel_end = 1, segment_height = 0.1, reverse = FALSE, plot_bevel = TRUE )
# Generate a complex bevel profile and plot it complex_coords = generate_complex_bevel( bevel_type = c("circular", "bump", "step", "block", "angled"), bevel_start = c(0, 0.2, 0.6, 0.7, 0.9), bevel_end = c(0.2, 0.5, 0.7, 0.8, 1.0), segment_height = c(0.1, 0.2, 0.2, 0.2, 0.4), angle = 45, curve_points = c(50, 50, 50, 1, 1), reverse = c(FALSE, TRUE, FALSE, FALSE, FALSE), plot_bevel = TRUE ) # Create a step function with reverses to generate a square wave pattern complex_coords = generate_complex_bevel( bevel_type = "step", bevel_start = head(seq(0,1,by=0.05),-1), bevel_end = 1, segment_height = 0.1, angle = 45, reverse = c(FALSE, TRUE), plot_bevel = TRUE ) #Generate an increasing sawtooth pattern with angles complex_coords = generate_complex_bevel( bevel_type = "angled", bevel_start = head(seq(0,1,by=0.05),-1), bevel_end = tail(seq(0,1,by=0.05),-1), segment_height = 0.1, angle = c(45,30), reverse = c(FALSE, TRUE), plot_bevel = TRUE ) # Create a step function to turn polygons into a ziggurat (note bevel_end is ignored) complex_coords = generate_complex_bevel( bevel_type = "step", bevel_start = head(seq(0,1,by=0.05),-1), bevel_end = 1, segment_height = 0.1, reverse = FALSE, plot_bevel = TRUE )
This function generates an interior offset polygon from a straight skeleton.
generate_offset_polygon(skeleton, offset, progress = FALSE)
generate_offset_polygon(skeleton, offset, progress = FALSE)
skeleton |
Default 'NULL'. A straight skeleton generated from the 'skeletonize' function. |
offset |
Default 'NULL'. The offset(s) of the polygon. |
progress |
Default 'FALSE'. Whether to display a progress bar. |
A list of data frames, each representing a polygon offset by the specified amount.
# Simple polygon example simple_poly = matrix(c(0,0, 3,0, 3,3, 0,3, 0,0), ncol=2, byrow=TRUE) skeleton = skeletonize(simple_poly) offset_polys = generate_offset_polygon(skeleton, c(0.25, 0.5)) print(offset_polys) # Polygon with hole example # Outer polygon vertices = matrix(c(0,0, 7,0, 7,7, 0,7, 0,0), ncol = 2, byrow = TRUE) # Holes inside the polygon hole_1 = matrix(c(1,1, 2,1, 2,2, 1,2, 1,1), ncol = 2, byrow = TRUE)[5:1,] hole_2 = matrix(c(5,5, 6,5, 6,6, 5,6, 5,5), ncol = 2, byrow = TRUE)[5:1,] skeleton = skeletonize(vertices, holes = list(hole_1, hole_2)) plot_skeleton(skeleton) #Generate three offsets plot_offset_polygon(generate_offset_polygon(skeleton, c(0.25,0.75,1.5,2))) #Generate many offsets plot_offset_polygon(generate_offset_polygon(skeleton, seq(0,2.5,by=0.1)+0.05)) # Skeletonize and plot an {sf} object if(length(find.package("spData",quiet = TRUE)) > 0) { us_states = spData::us_states texas = us_states[us_states$NAME == "Texas",] texas_skeleton = skeletonize(texas) plot_offset_polygon(generate_offset_polygon(texas_skeleton, seq(0, 2.5, by = 0.1)), border = heat.colors, linewidth = 1) }
# Simple polygon example simple_poly = matrix(c(0,0, 3,0, 3,3, 0,3, 0,0), ncol=2, byrow=TRUE) skeleton = skeletonize(simple_poly) offset_polys = generate_offset_polygon(skeleton, c(0.25, 0.5)) print(offset_polys) # Polygon with hole example # Outer polygon vertices = matrix(c(0,0, 7,0, 7,7, 0,7, 0,0), ncol = 2, byrow = TRUE) # Holes inside the polygon hole_1 = matrix(c(1,1, 2,1, 2,2, 1,2, 1,1), ncol = 2, byrow = TRUE)[5:1,] hole_2 = matrix(c(5,5, 6,5, 6,6, 5,6, 5,5), ncol = 2, byrow = TRUE)[5:1,] skeleton = skeletonize(vertices, holes = list(hole_1, hole_2)) plot_skeleton(skeleton) #Generate three offsets plot_offset_polygon(generate_offset_polygon(skeleton, c(0.25,0.75,1.5,2))) #Generate many offsets plot_offset_polygon(generate_offset_polygon(skeleton, seq(0,2.5,by=0.1)+0.05)) # Skeletonize and plot an {sf} object if(length(find.package("spData",quiet = TRUE)) > 0) { us_states = spData::us_states texas = us_states[us_states$NAME == "Texas",] texas_skeleton = skeletonize(texas) plot_offset_polygon(generate_offset_polygon(texas_skeleton, seq(0, 2.5, by = 0.1)), border = heat.colors, linewidth = 1) }
This function generates a 3D roof model from a straight skeleton.
generate_roof( skeleton, max_height = NA, vertical_offset = 0, base = FALSE, base_height = 0, angle = 45, sides = FALSE, double_sided = FALSE, scale_all_max = FALSE, swap_yz = TRUE, progress = TRUE, material = material_list(), roof_material = NA, verbose = FALSE )
generate_roof( skeleton, max_height = NA, vertical_offset = 0, base = FALSE, base_height = 0, angle = 45, sides = FALSE, double_sided = FALSE, scale_all_max = FALSE, swap_yz = TRUE, progress = TRUE, material = material_list(), roof_material = NA, verbose = FALSE )
skeleton |
Default 'NULL'. A straight skeleton generated from the 'skeletonize' function. |
max_height |
Default 'NA'. The maximum height of the roof. |
vertical_offset |
Default '0'. The vertical offset of the roof. |
base |
Default 'TRUE'. A logical flag that controls whether to generate the bottom of the roof. |
base_height |
Default 'vertical_offset'. Height of the base. |
angle |
Default '45'. Angle of the roof. |
sides |
Default 'FALSE'. A logical flag on whether to draw the sides. This will automatically be set to 'TRUE' if 'base = TRUE' and the 'base_height' is less than 'vertical_offset'. |
double_sided |
Default 'FALSE'. A logical flag that controls whether the polygon should be double-sided. |
scale_all_max |
Default 'FALSE'. If passing in a list of multiple skeletons with polygons, whether to scale each polygon to the overall max height, or whether to scale each max height to the maximum internal distance in the polygon. |
swap_yz |
Default 'TRUE'. A logical flag that controls whether to swap the y and z coordinates in the resulting mesh. If 'TRUE', the y and z coordinates will be swapped. |
progress |
Default 'TRUE'. A logical flag to control whether a progress bar is displayed during roof generation. |
material |
Default 'material_list()'. Interface to set the color/appearance/material options for the resulting 'ray_mesh' mesh. |
roof_material |
Default 'NA', uses the material specified in 'material'. Interface to set the color/appearance/material options for the resulting 'ray_mesh' rooftop mesh. |
verbose |
Default 'FALSE'. A logical flag to control whether additional timing information should be displayed. |
A 3D mesh of the roof model.
#Generate vertices and holes vertices = matrix(c(0,0, 7,0, 7,7, 0,7, 0,0), ncol = 2, byrow = TRUE)-3.5 hole_1 = matrix(c(1,1, 2,1, 2,2, 1,2, 1,1), ncol = 2, byrow = TRUE)[5:1,]-3.5 hole_2 = matrix(c(5,5, 6,5, 6,6, 5,6, 5,5), ncol = 2, byrow = TRUE)[5:1,]-3.5 skeleton = skeletonize(vertices, holes = list(hole_1, hole_2)) if(run_documentation()) { plot_skeleton(skeleton) } #Generate a roof model and specify the material if(run_documentation()) { library(rayrender) library(rayvertex) roof_model = generate_roof(skeleton, material = material_list(diffuse="purple")) scene_base = xz_rect(xwidth=100,zwidth=100, material=diffuse(color="grey20", checkercolor="white")) |> add_object(sphere(y=8,z=10,x=-3,material=light(intensity=100))) |> add_object(sphere(y=800,z=10,x=-3,radius=100,material=light(intensity=5))) raymesh_model(roof_model, override_material = FALSE) |> add_object(scene_base) |> render_scene(lookfrom=c(10,30,20), sample_method = "sobol_blue", width=800,height=800,fov=0,ortho_dimensions=c(10,10)) } # Change the maximum height of the roof if(run_documentation()) { roof_model = generate_roof(skeleton, max_height=5) raymesh_model(roof_model, material = diffuse(color="purple")) |> add_object(scene_base) |> render_scene(lookfrom=c(10,30,20), sample_method = "sobol_blue", width=800,height=800,fov=0,ortho_dimensions=c(10,10)) } #Add a vertical_offset to the roof, without a base if(run_documentation()) { roof_model = generate_roof(skeleton, vertical_offset = 2, base = FALSE) raymesh_model(roof_model, material = diffuse(color="purple")) |> add_object(scene_base) |> render_scene(lookfrom=c(10,10,20), lookat=c(0,2,0), sample_method = "sobol_blue", width=800,height=800,fov=0,ortho_dimensions=c(10,10)) } # Add a base if(run_documentation()) { roof_model = generate_roof(skeleton, vertical_offset = 2, base = TRUE) raymesh_model(roof_model, material = diffuse(color="purple")) |> add_object(scene_base) |> render_scene(lookfrom=c(10,10,20), lookat=c(0,2,0), sample_method = "sobol_blue", width=800,height=800,fov=0,ortho_dimensions=c(10,10)) } # Change the base height (note that the vertical_offset is measured from the base, not from zero) if(run_documentation()) { roof_model = generate_roof(skeleton, vertical_offset = 2, base = TRUE, base_height=1) raymesh_model(roof_model, material = diffuse(color="purple")) |> add_object(scene_base) |> render_scene(lookfrom=c(10,10,20), lookat=c(0,2,0), sample_method = "sobol_blue", width=800,height=800,fov=0,ortho_dimensions=c(10,10)) } # Skeletonize and turn an {sf} object into a roof if(run_documentation()) { us_states = spData::us_states cali = us_states[us_states$NAME == "California",] cali_skeleton = skeletonize(cali) plot_skeleton(cali_skeleton) roof_model_cali = generate_roof(cali_skeleton, max_height = 2) |> center_mesh() |> translate_mesh(c(0,1,0)) raymesh_model(roof_model_cali, material = diffuse(color="purple")) |> add_object(scene_base) |> add_object(sphere(x=-10,z=-10,y=4,material=light(color="red", intensity=40))) |> add_object(sphere(x=10,z=-10,y=4,material=light(color="orange", intensity=40))) |> render_scene(lookfrom=c(0,10,-1), sample_method = "sobol_blue", width=800,height=800,fov=0, ortho_dimensions=c(12,12)) }
#Generate vertices and holes vertices = matrix(c(0,0, 7,0, 7,7, 0,7, 0,0), ncol = 2, byrow = TRUE)-3.5 hole_1 = matrix(c(1,1, 2,1, 2,2, 1,2, 1,1), ncol = 2, byrow = TRUE)[5:1,]-3.5 hole_2 = matrix(c(5,5, 6,5, 6,6, 5,6, 5,5), ncol = 2, byrow = TRUE)[5:1,]-3.5 skeleton = skeletonize(vertices, holes = list(hole_1, hole_2)) if(run_documentation()) { plot_skeleton(skeleton) } #Generate a roof model and specify the material if(run_documentation()) { library(rayrender) library(rayvertex) roof_model = generate_roof(skeleton, material = material_list(diffuse="purple")) scene_base = xz_rect(xwidth=100,zwidth=100, material=diffuse(color="grey20", checkercolor="white")) |> add_object(sphere(y=8,z=10,x=-3,material=light(intensity=100))) |> add_object(sphere(y=800,z=10,x=-3,radius=100,material=light(intensity=5))) raymesh_model(roof_model, override_material = FALSE) |> add_object(scene_base) |> render_scene(lookfrom=c(10,30,20), sample_method = "sobol_blue", width=800,height=800,fov=0,ortho_dimensions=c(10,10)) } # Change the maximum height of the roof if(run_documentation()) { roof_model = generate_roof(skeleton, max_height=5) raymesh_model(roof_model, material = diffuse(color="purple")) |> add_object(scene_base) |> render_scene(lookfrom=c(10,30,20), sample_method = "sobol_blue", width=800,height=800,fov=0,ortho_dimensions=c(10,10)) } #Add a vertical_offset to the roof, without a base if(run_documentation()) { roof_model = generate_roof(skeleton, vertical_offset = 2, base = FALSE) raymesh_model(roof_model, material = diffuse(color="purple")) |> add_object(scene_base) |> render_scene(lookfrom=c(10,10,20), lookat=c(0,2,0), sample_method = "sobol_blue", width=800,height=800,fov=0,ortho_dimensions=c(10,10)) } # Add a base if(run_documentation()) { roof_model = generate_roof(skeleton, vertical_offset = 2, base = TRUE) raymesh_model(roof_model, material = diffuse(color="purple")) |> add_object(scene_base) |> render_scene(lookfrom=c(10,10,20), lookat=c(0,2,0), sample_method = "sobol_blue", width=800,height=800,fov=0,ortho_dimensions=c(10,10)) } # Change the base height (note that the vertical_offset is measured from the base, not from zero) if(run_documentation()) { roof_model = generate_roof(skeleton, vertical_offset = 2, base = TRUE, base_height=1) raymesh_model(roof_model, material = diffuse(color="purple")) |> add_object(scene_base) |> render_scene(lookfrom=c(10,10,20), lookat=c(0,2,0), sample_method = "sobol_blue", width=800,height=800,fov=0,ortho_dimensions=c(10,10)) } # Skeletonize and turn an {sf} object into a roof if(run_documentation()) { us_states = spData::us_states cali = us_states[us_states$NAME == "California",] cali_skeleton = skeletonize(cali) plot_skeleton(cali_skeleton) roof_model_cali = generate_roof(cali_skeleton, max_height = 2) |> center_mesh() |> translate_mesh(c(0,1,0)) raymesh_model(roof_model_cali, material = diffuse(color="purple")) |> add_object(scene_base) |> add_object(sphere(x=-10,z=-10,y=4,material=light(color="red", intensity=40))) |> add_object(sphere(x=10,z=-10,y=4,material=light(color="orange", intensity=40))) |> render_scene(lookfrom=c(0,10,-1), sample_method = "sobol_blue", width=800,height=800,fov=0, ortho_dimensions=c(12,12)) }
Plot the offset polygons generated by the 'generate_offset_polygon' function.
plot_offset_polygon( offset_polygons, plot_original_polygon = TRUE, fill = NA, color = "dodgerblue", xlim = NULL, ylim = NULL, linewidth = 1, background = "white", plot_skeleton = FALSE, return_layers = FALSE, ... )
plot_offset_polygon( offset_polygons, plot_original_polygon = TRUE, fill = NA, color = "dodgerblue", xlim = NULL, ylim = NULL, linewidth = 1, background = "white", plot_skeleton = FALSE, return_layers = FALSE, ... )
offset_polygons |
Default 'NULL'. A 'rayskeleton_polygon' or 'rayskeleton_polygon_list' object, generated from 'generate_offset_polygon()'. |
plot_original_polygon |
Default 'TRUE'. Whether to plot the original polygon. |
fill |
Default ‘NULL'. A color or palette function to generate the fill palette for the polygons’ interiors. |
color |
Default ‘grDevices::heat.colors'. A color or palette function to generate the color palette for the offset polygons’ borders. |
xlim |
Default 'NULL'. The x-axis limits as a vector of two values (min, max). If 'NULL', it calculates the limits from the data. |
ylim |
Default 'NULL'. The y-axis limits as a vector of two values (min, max). If 'NULL', it calculates the limits from the data. |
linewidth |
Default '1'. The linewidth of the polygon. |
background |
Default '"white"'. Background color. |
plot_skeleton |
Default 'FALSE'. Whether to plot the straight skeleton. |
return_layers |
Default 'FALSE', plots the figure. If 'TRUE', this will instead return a list of the ggplot layers. |
... |
Additional arguments to pass to 'plot_skeleton()' if 'plot_skeleton = TRUE' |
A plot showing the offset polygons.
# Outer polygon vertices = matrix(c(0,0, 7,0, 7,7, 0,7, 0,0), ncol = 2, byrow = TRUE) # Holes inside the polygon hole_1 = matrix(c(1,1, 2,1, 2,2, 1,2, 1,1), ncol = 2, byrow = TRUE)[5:1,] hole_2 = matrix(c(5,5, 6,5, 6,6, 5,6, 5,5), ncol = 2, byrow = TRUE)[5:1,] skeleton = skeletonize(vertices, holes = list(hole_1, hole_2)) plot_skeleton(skeleton) #Generate three offsets with the skeleton plot_offset_polygon(generate_offset_polygon(skeleton, c(0.25,0.75,1.5,2)), plot_skeleton = TRUE) #Generate many offsets plot_offset_polygon(generate_offset_polygon(skeleton, seq(0.05,2.55,by=0.1))) #Pass a palette plot_offset_polygon(generate_offset_polygon(skeleton, seq(0.05,2.55,by=0.1)), color = heat.colors) #Pass colors manually (colors in excess of the number of offsets are ignored) plot_offset_polygon(generate_offset_polygon(skeleton, seq(0.05,2.55,by=0.1)), color = rep(c("red","red","blue","blue"),100)) # Skeletonize and plot an {sf} object if(length(find.package("spData",quiet = TRUE)) > 0) { us_states = spData::us_states texas = us_states[us_states$NAME == "Texas",] texas_skeleton = skeletonize(texas) plot_offset_polygon(generate_offset_polygon(texas_skeleton, seq(0, 2.5, by = 0.1)), color = heat.colors, linewidth = 1) }
# Outer polygon vertices = matrix(c(0,0, 7,0, 7,7, 0,7, 0,0), ncol = 2, byrow = TRUE) # Holes inside the polygon hole_1 = matrix(c(1,1, 2,1, 2,2, 1,2, 1,1), ncol = 2, byrow = TRUE)[5:1,] hole_2 = matrix(c(5,5, 6,5, 6,6, 5,6, 5,5), ncol = 2, byrow = TRUE)[5:1,] skeleton = skeletonize(vertices, holes = list(hole_1, hole_2)) plot_skeleton(skeleton) #Generate three offsets with the skeleton plot_offset_polygon(generate_offset_polygon(skeleton, c(0.25,0.75,1.5,2)), plot_skeleton = TRUE) #Generate many offsets plot_offset_polygon(generate_offset_polygon(skeleton, seq(0.05,2.55,by=0.1))) #Pass a palette plot_offset_polygon(generate_offset_polygon(skeleton, seq(0.05,2.55,by=0.1)), color = heat.colors) #Pass colors manually (colors in excess of the number of offsets are ignored) plot_offset_polygon(generate_offset_polygon(skeleton, seq(0.05,2.55,by=0.1)), color = rep(c("red","red","blue","blue"),100)) # Skeletonize and plot an {sf} object if(length(find.package("spData",quiet = TRUE)) > 0) { us_states = spData::us_states texas = us_states[us_states$NAME == "Texas",] texas_skeleton = skeletonize(texas) plot_offset_polygon(generate_offset_polygon(texas_skeleton, seq(0, 2.5, by = 0.1)), color = heat.colors, linewidth = 1) }
This function visualizes the straight skeleton derived from a given polygon. The original polygon (with holes if present) is plotted in black, while the straight skeleton is plotted in red.
plot_skeleton( skeleton, use_arrow = TRUE, use_points = TRUE, xlim = c(0, 1), ylim = c(0, 1), arrow_color = "red", polygon_color = "black", size = 1, arrow_size = 0.05, highlight_links = NULL, highlight_color = "green", return_layers = FALSE )
plot_skeleton( skeleton, use_arrow = TRUE, use_points = TRUE, xlim = c(0, 1), ylim = c(0, 1), arrow_color = "red", polygon_color = "black", size = 1, arrow_size = 0.05, highlight_links = NULL, highlight_color = "green", return_layers = FALSE )
skeleton |
A list object of class 'rayskeleton' containing the straight skeleton details. It should have 'nodes' and 'links' as its primary components. |
use_arrow |
Default 'TRUE'. A logical value indicating whether or not to use arrows to represent the links of the straight skeleton. Default is TRUE. |
use_points |
Default 'TRUE'. Whether to plot the vertex points as well. |
xlim |
Default'c(0,1)'. A numeric vector of length 2 specifying the x-limits of the plot in the form 'c(min, max)'. These are proportional limits relative to the bounding box around the skeleton. |
ylim |
Default 'c(0,1)'. A numeric vector of length 2 specifying the y-limits of the plot in the form c(min, max). These are proportional limits relative to the bounding box around the skeleton. |
arrow_color |
Default '"red"'. Color of the arrows. |
polygon_color |
Default '"black"'. Color of the polygon. |
size |
Default '1'. Size of the vertex points. |
arrow_size |
Default '1'. Scales the arrow size. |
highlight_links |
Default 'NULL'. A numeric vector indicating which links (by their index) to highlight. If specified, the corresponding links will be colored with the 'highlight_color'. |
highlight_color |
Default '"purple"'. Color of the highlighted links. |
return_layers |
Default 'FALSE', plots the figure. If 'TRUE', this will instead return a list of the ggplot layers. |
The function uses the 'ggplot2' package for plotting. The straight skeleton is visualized based on the details provided in the 'skeleton' object. The original polygon and holes are plotted based on attributes stored in the 'skeleton' object.
A ggplot object visualizing the straight skeleton and the original polygon.
# Assuming skeleton1 is already defined as in the previous example # Outer polygon vertices = matrix(c(0,0, 7,0, 7,7, 0,7, 0,0), ncol = 2, byrow = TRUE) # Holes inside the polygon hole1 = matrix(c(1,1, 1,2, 2,2, 2,1, 1,1), ncol = 2, byrow = TRUE) hole2 = matrix(c(5,5, 5,6, 6,6, 6,5, 5,5), ncol = 2, byrow = TRUE) skeleton = skeletonize(vertices, holes = list(hole1, hole2)) if(length(find.package("ggplot2",quiet = TRUE)) > 0) { plot_skeleton(skeleton) } # Skeletonize and plot an {sf} object if(length(find.package("spData",quiet = TRUE)) > 0) { us_states = spData::us_states texas = us_states[us_states$NAME == "Texas",] plot_skeleton(skeletonize(texas)) } # Highlighting certain links in the skeleton max_links =which(skeleton$links$destination_time == max(skeleton$links$destination_time)) if(length(find.package("ggplot2",quiet = TRUE)) > 0) { plot_skeleton(skeleton, highlight_links = max_links, highlight_color = "green") }
# Assuming skeleton1 is already defined as in the previous example # Outer polygon vertices = matrix(c(0,0, 7,0, 7,7, 0,7, 0,0), ncol = 2, byrow = TRUE) # Holes inside the polygon hole1 = matrix(c(1,1, 1,2, 2,2, 2,1, 1,1), ncol = 2, byrow = TRUE) hole2 = matrix(c(5,5, 5,6, 6,6, 6,5, 5,5), ncol = 2, byrow = TRUE) skeleton = skeletonize(vertices, holes = list(hole1, hole2)) if(length(find.package("ggplot2",quiet = TRUE)) > 0) { plot_skeleton(skeleton) } # Skeletonize and plot an {sf} object if(length(find.package("spData",quiet = TRUE)) > 0) { us_states = spData::us_states texas = us_states[us_states$NAME == "Texas",] plot_skeleton(skeletonize(texas)) } # Highlighting certain links in the skeleton max_links =which(skeleton$links$destination_time == max(skeleton$links$destination_time)) if(length(find.package("ggplot2",quiet = TRUE)) > 0) { plot_skeleton(skeleton, highlight_links = max_links, highlight_color = "green") }
This function determines if the examples are being run in pkgdown. It is not meant to be called by the user.
run_documentation()
run_documentation()
Boolean value.
# See if the documentation should be run. run_documentation()
# See if the documentation should be run. run_documentation()
This function generates a straight skeleton of a polygon, based on a set of vertices and holes. It uses the CGAL library to create the straight skeleton using exact arithmetic, and then parses that file into a more manageable format.
skeletonize( vertices, holes = list(), debug = FALSE, merge_nodes_tolerance = 1e-05, return_raw_ss = FALSE, progress = TRUE )
skeletonize( vertices, holes = list(), debug = FALSE, merge_nodes_tolerance = 1e-05, return_raw_ss = FALSE, progress = TRUE )
vertices |
Default 'NULL'. A matrix of x and y coordinates representing the vertices of the polygon in counter-clockwise (CCW) order. |
holes |
Default 'list()'. A list of matrices, each representing a hole in the polygon with x and y coordinates in clockwise (CW) order. |
debug |
Default 'FALSE'. A logical flag that controls whether debugging information should be printed. |
merge_nodes_tolerance |
Default '1e-5'. A numeric value specifying the tolerance level for merging nodes. It should be a value between 0 and 1. This value species the size of the grid that the nodes are snapped to determining identical nodes. |
return_raw_ss |
Default 'FALSE'. A logical flag that controls whether the raw straight skeleton should be returned. |
progress |
Default 'TRUE'. A logical flag that controls whether a progress bar should be displayed while skeletonizing. |
If ‘return_raw_ss' is FALSE, a list with two data frames, ’nodes' and 'links', which represent the nodes and edges of the straight skeleton, respectively. If 'return_raw_ss' is TRUE, a data frame representing the raw straight skeleton is returned. If the polygon is not simple, a warning is issued and NULL is returned.
# Example 1: Simple rectangle polygon with no holes vertices1 = matrix(c(0,0, 4,0, 4,3, 0,3, 0,0), ncol = 2, byrow = TRUE) skeleton1 = skeletonize(vertices1) plot_skeleton(skeleton1) # Example 2: Triangle polygon with no holes vertices2 = matrix(c(0,0, 2,0, 1,2, 0,0), ncol = 2, byrow = TRUE) skeleton2 = skeletonize(vertices2) plot_skeleton(skeleton2) # Example 3: Polygon with a hole # Outer polygon vertices3 = matrix(c(0,0, 5,0, 5,5, 0,5, 0,0), ncol = 2, byrow = TRUE) # Hole inside the polygon hole3 = matrix(c(1,1, 4,1, 4,4, 1,4, 1,1), ncol = 2, byrow = TRUE)[5:1,] skeleton3 = skeletonize(vertices3, holes = list(hole3)) plot_skeleton(skeleton3) # Example 4: Polygon with multiple holes # Outer polygon vertices4 = matrix(c(0,0, 7,0, 7,7, 0,7, 0,0), ncol = 2, byrow = TRUE) # Holes inside the polygon hole4_1 = matrix(c(1,1, 2,1, 2,2, 1,2, 1,1), ncol = 2, byrow = TRUE)[5:1,] hole4_2 = matrix(c(5,5, 6,5, 6,6, 5,6, 5,5), ncol = 2, byrow = TRUE)[5:1,] skeleton4 = skeletonize(vertices4, holes = list(hole4_1, hole4_2)) plot_skeleton(skeleton4) # Example 5: Using debug and returning raw straight skeleton vertices5 = matrix(c(0,0, 3,0, 3,3, 0,3, 0,0), ncol = 2, byrow = TRUE) raw_skeleton5 = skeletonize(vertices5, debug = TRUE, return_raw_ss = TRUE) # Skeletonize and plot an {sf} object if(length(find.package("spData",quiet = TRUE)) > 0) { us_states = spData::us_states texas = us_states[us_states$NAME == "Texas",] plot_skeleton(skeletonize(texas)) }
# Example 1: Simple rectangle polygon with no holes vertices1 = matrix(c(0,0, 4,0, 4,3, 0,3, 0,0), ncol = 2, byrow = TRUE) skeleton1 = skeletonize(vertices1) plot_skeleton(skeleton1) # Example 2: Triangle polygon with no holes vertices2 = matrix(c(0,0, 2,0, 1,2, 0,0), ncol = 2, byrow = TRUE) skeleton2 = skeletonize(vertices2) plot_skeleton(skeleton2) # Example 3: Polygon with a hole # Outer polygon vertices3 = matrix(c(0,0, 5,0, 5,5, 0,5, 0,0), ncol = 2, byrow = TRUE) # Hole inside the polygon hole3 = matrix(c(1,1, 4,1, 4,4, 1,4, 1,1), ncol = 2, byrow = TRUE)[5:1,] skeleton3 = skeletonize(vertices3, holes = list(hole3)) plot_skeleton(skeleton3) # Example 4: Polygon with multiple holes # Outer polygon vertices4 = matrix(c(0,0, 7,0, 7,7, 0,7, 0,0), ncol = 2, byrow = TRUE) # Holes inside the polygon hole4_1 = matrix(c(1,1, 2,1, 2,2, 1,2, 1,1), ncol = 2, byrow = TRUE)[5:1,] hole4_2 = matrix(c(5,5, 6,5, 6,6, 5,6, 5,5), ncol = 2, byrow = TRUE)[5:1,] skeleton4 = skeletonize(vertices4, holes = list(hole4_1, hole4_2)) plot_skeleton(skeleton4) # Example 5: Using debug and returning raw straight skeleton vertices5 = matrix(c(0,0, 3,0, 3,3, 0,3, 0,0), ncol = 2, byrow = TRUE) raw_skeleton5 = skeletonize(vertices5, debug = TRUE, return_raw_ss = TRUE) # Skeletonize and plot an {sf} object if(length(find.package("spData",quiet = TRUE)) > 0) { us_states = spData::us_states texas = us_states[us_states$NAME == "Texas",] plot_skeleton(skeletonize(texas)) }