Skip to content

Instantly share code, notes, and snippets.

@mcneds
Last active August 7, 2024 09:08
Show Gist options
  • Save mcneds/799788f3a9d4395f964f82b869511dc5 to your computer and use it in GitHub Desktop.
Save mcneds/799788f3a9d4395f964f82b869511dc5 to your computer and use it in GitHub Desktop.
Parkour simulation 2
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import tkinter as tk
from tkinter import ttk
# Define the parameters for the paraboloid
vertex_x = 0
vertex_y = 1
root1 = -4.25
root2 = root1 * -1
step = 1 / 16
# Create a grid of x and y values
x = np.arange(root1, root2 + step, step)
y = np.arange(root1, root2 + step, step)
X, Y = np.meshgrid(x, y)
# Calculate the z values for the original paraboloid
a = -1 / ((root2 - vertex_x) ** 2)
Z = a * (X ** 2 + Y ** 2) + vertex_y
# Function to create the paraboloid based on combined root scaling
def create_paraboloid(difficulty):
if difficulty <= 5:
# Logarithmic scaling for root from 0 to 3
log_scale = (difficulty / 5)
new_root = 3 * log_scale
else:
# Exponential scaling for root from 3 to 4.25
exp_scale = (difficulty - 5) / 5
new_root = 3 + exp_scale * (root2 - 3)
a_difficulty = -1 / (new_root ** 2)
Z_difficulty = a_difficulty * (X ** 2 + Y ** 2) + vertex_y
return Z_difficulty, new_root
# Precompute base paraboloid once
base_Z_difficulty, _ = create_paraboloid(1)
# Calculate the outer bounds for the true simulation
def calculate_outer_bounds_paraboloid(difficulty):
Z_difficulty, _ = create_paraboloid(difficulty)
max_Z_difficulty = np.max(Z_difficulty)
min_Z_difficulty = np.min(Z_difficulty)
# Extend the grid to cover the 20x20 grid space
outer_X = np.arange(root1 - 10 * step, root2 + 10 * step + step, step)
outer_Y = np.arange(root1 - 10 * step, root2 + 10 * step + step, step)
outer_X, outer_Y = np.meshgrid(outer_X, outer_Y)
a_difficulty = -1 / (4.25 ** 2)
outer_Z_difficulty = a_difficulty * (outer_X ** 2 + outer_Y ** 2) + vertex_y
return outer_X, outer_Y, outer_Z_difficulty, min_Z_difficulty, max_Z_difficulty
# Function to update the plot
def update_plot(difficulty):
global base_Z_difficulty
Z_difficulty, root_distance = create_paraboloid(difficulty)
if difficulty != 1:
base_Z_difficulty = Z_difficulty
ax.clear()
if show_original.get():
ax.scatter(X, Y, Z, color='blue', s=1)
if show_difficulty.get():
if show_true_simulation.get():
outer_X, outer_Y, outer_Z_difficulty, _, _ = calculate_outer_bounds_paraboloid(difficulty)
ax.scatter(outer_X, outer_Y, outer_Z_difficulty, color='green', s=1)
else:
ax.scatter(X, Y, Z_difficulty, color='green', s=1)
if show_ground_plane.get():
ax.plot_surface(X, Y, np.zeros_like(X), color='gray', alpha=0.5)
ax.scatter(0, 0, 0, color='red', s=50, label='Jump Origin', zorder=1000000) # Ensure the origin point is plotted last
ax.set_title(f'Paraboloid with Difficulty {difficulty}')
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
root_label.config(text=f"Root Distance: {root_distance:.4f}")
canvas.draw()
# Function to handle slider interaction
def on_slider_change(event):
slider_paused.set(False)
update_plot(slider.get())
slider_paused.set(True)
# Function to pause rendering during slider interaction
def on_slider_scrub(event):
slider_paused.set(False)
# Creating the Tkinter window
root = tk.Tk()
root.title("Paraboloid Visualization")
# Create a figure and axis for the 3D plot
fig = plt.figure(figsize=(8, 6))
ax = fig.add_subplot(111, projection='3d')
# Embed the plot in the Tkinter window
canvas = FigureCanvasTkAgg(fig, master=root)
canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
# Create Boolean variables for toggling visibility
show_original = tk.BooleanVar(value=True)
show_difficulty = tk.BooleanVar(value=True)
show_ground_plane = tk.BooleanVar(value=True)
show_true_simulation = tk.BooleanVar(value=False)
slider_paused = tk.BooleanVar(value=True)
# Create toggle buttons
toggle_original_btn = ttk.Checkbutton(root, text="Toggle Original Paraboloid", variable=show_original, command=lambda: update_plot(slider.get()))
toggle_original_btn.pack(side=tk.LEFT, padx=10, pady=10)
toggle_difficulty_btn = ttk.Checkbutton(root, text="Toggle Difficulty Paraboloid", variable=show_difficulty, command=lambda: update_plot(slider.get()))
toggle_difficulty_btn.pack(side=tk.LEFT, padx=10, pady=10)
toggle_ground_plane_btn = ttk.Checkbutton(root, text="Toggle Ground Plane", variable=show_ground_plane, command=lambda: update_plot(slider.get()))
toggle_ground_plane_btn.pack(side=tk.LEFT, padx=10, pady=10)
toggle_true_simulation_btn = ttk.Checkbutton(root, text="Toggle True Simulation", variable=show_true_simulation, command=lambda: update_plot(slider.get()))
toggle_true_simulation_btn.pack(side=tk.LEFT, padx=10, pady=10)
# Create a slider for adjusting the difficulty
slider = ttk.Scale(root, from_=1, to=10, orient=tk.HORIZONTAL)
slider.set(1)
slider.pack(side=tk.BOTTOM, fill=tk.X, padx=10, pady=10)
slider.bind("<ButtonRelease-1>", on_slider_change)
slider.bind("<ButtonPress-1>", on_slider_scrub)
# Display for root distance
root_label = tk.Label(root, text="Root Distance: 0.0000")
root_label.pack(side=tk.BOTTOM, padx=10, pady=10)
# Create the initial plot
update_plot(1)
# Run the Tkinter event loop
root.mainloop()
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <omp.h>
#include <hdf5.h>
#define ROOT1 -68
#define ROOT2 68
#define VERTEX_Y 16
#define STEP 1
#define MAX_HEIGHT 160 // 10 blocks, each block is 16 pixels
#define CHUNK_SIZE 50
// Function prototypes
double* create_max_paraboloid();
double calculate_difficulty(double root_distance);
void generate_points(double** points, int* point_count);
void save_chunk_to_file(double* chunk_data, int chunk_index, int point_count);
void combine_chunks(int total_chunks);
int main() {
int total_simulations = 400; // 20x20 origins
int completed_simulations = 0;
int chunk_index = 0;
int chunk_count = 0;
omp_set_num_threads(4);
printf("Starting full simulation\n");
double* chunk_data = (double*)malloc(CHUNK_SIZE * 1000000 * 8 * sizeof(double)); // Allocate enough space for each chunk
if (chunk_data == NULL) {
fprintf(stderr, "Memory allocation failed for chunk data array\n");
return 1;
}
int chunk_data_count = 0;
// Generate the maximum difficulty paraboloid points
double* max_paraboloid_points = NULL;
int max_paraboloid_point_count = 0;
generate_points(&max_paraboloid_points, &max_paraboloid_point_count);
// Offset these points according to different origins
for (int ox = -10; ox <= 10; ox++) { // 20px range centered on 0
for (int oy = -10; oy <= 10; oy++) { // 20px range centered on 0
for (int i = 0; i < max_paraboloid_point_count; i += 8) {
double abs_rx = max_paraboloid_points[i + 3] + ox;
double abs_ry = max_paraboloid_points[i + 4] + oy;
double abs_rz = max_paraboloid_points[i + 5];
// Exclude points within the 20x20x32 exclusion zone below the origin
if (!(abs_rx >= -10 && abs_rx <= 10 && abs_ry >= -10 && abs_ry <= 10 && abs_rz >= -32 && abs_rz <= 0)) {
if (chunk_data_count >= CHUNK_SIZE * 1000000 * 8) {
save_chunk_to_file(chunk_data, chunk_index++, chunk_data_count);
chunk_data_count = 0;
}
chunk_data[chunk_data_count++] = ox;
chunk_data[chunk_data_count++] = oy;
chunk_data[chunk_data_count++] = 0; // Fixed origin z = 0
chunk_data[chunk_data_count++] = abs_rx;
chunk_data[chunk_data_count++] = abs_ry;
chunk_data[chunk_data_count++] = abs_rz;
chunk_data[chunk_data_count++] = max_paraboloid_points[i + 6];
chunk_data[chunk_data_count++] = max_paraboloid_points[i + 7];
}
}
completed_simulations++;
printf("Simulation %d / %d completed.\n", completed_simulations, total_simulations);
}
}
// Save any remaining data
if (chunk_data_count > 0) {
save_chunk_to_file(chunk_data, chunk_index++, chunk_data_count);
}
free(max_paraboloid_points);
free(chunk_data);
printf("Data generation complete.\n");
combine_chunks(chunk_index);
printf("All chunks combined into final file.\n");
return 0;
}
double* create_max_paraboloid() {
static double Z_difficulty[(ROOT2 - ROOT1 + 1) * (ROOT2 - ROOT1 + 1)];
int index = 0;
double a_difficulty = -1.0 / ((68.0 / 16.0) * (68.0 / 16.0)); // Max root distance for max difficulty
for (int x = ROOT1; x <= ROOT2; x += STEP) {
for (int y = ROOT1; y <= ROOT2; y += STEP) {
double z = a_difficulty * (x * x + y * y) + VERTEX_Y;
Z_difficulty[index++] = z; // Allow negative z values
}
}
return Z_difficulty;
}
double calculate_difficulty(double root_distance) {
double root_blocks = root_distance / 16.0;
if (root_blocks <= 3) {
return (root_blocks / 3.0) * 5.0;
} else {
return 5.0 + ((root_blocks - 3.0) / (4.25 - 3.0)) * 5.0;
}
}
void generate_points(double** points, int* point_count) {
int max_points = 1000000; // Large initial allocation size
*points = (double*)malloc(max_points * 8 * sizeof(double));
if (*points == NULL) {
fprintf(stderr, "Memory allocation failed for points array\n");
exit(1);
}
*point_count = 0;
double* Z_difficulty = create_max_paraboloid();
int index = 0;
for (int x = ROOT1; x <= ROOT2; x += STEP) {
for (int y = ROOT1; y <= ROOT2; y += STEP) {
double rz = Z_difficulty[index++];
int abs_rx = x;
int abs_ry = y;
int abs_rz = rz;
double root_distance = sqrt(abs_rx * abs_rx + abs_ry * abs_ry);
double difficulty = calculate_difficulty(root_distance);
if (*point_count >= max_points * 8) {
max_points *= 2;
*points = (double*)realloc(*points, max_points * 8 * sizeof(double));
if (*points == NULL) {
fprintf(stderr, "Memory reallocation failed for points array\n");
exit(1);
}
}
(*points)[(*point_count)++] = 0;
(*points)[(*point_count)++] = 0;
(*points)[(*point_count)++] = 0; // Fixed origin z = 0
(*points)[(*point_count)++] = abs_rx;
(*points)[(*point_count)++] = abs_ry;
(*points)[(*point_count)++] = abs_rz;
(*points)[(*point_count)++] = root_distance;
(*points)[(*point_count)++] = difficulty;
}
}
}
void save_chunk_to_file(double* chunk_data, int chunk_index, int point_count) {
char filename[50];
sprintf(filename, "simulation_chunk_%d.h5", chunk_index);
printf("Saving chunk %d to %s\n", chunk_index, filename);
hid_t file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
if (file_id < 0) {
fprintf(stderr, "Error: Failed to create file %s\n", filename);
return;
}
hsize_t dims[2] = { point_count / 8, 8 };
hid_t dataspace_id = H5Screate_simple(2, dims, NULL);
if (dataspace_id < 0) {
fprintf(stderr, "Error: Failed to create dataspace\n");
H5Fclose(file_id);
return;
}
hid_t plist_id = H5Pcreate(H5P_DATASET_CREATE);
H5Pset_deflate(plist_id, 9); // Maximum compression level
H5Pset_chunk(plist_id, 2, dims);
hid_t dataset_id = H5Dcreate2(file_id, "data", H5T_NATIVE_DOUBLE, dataspace_id, H5P_DEFAULT, plist_id, H5P_DEFAULT);
if (dataset_id < 0) {
fprintf(stderr, "Error: Failed to create dataset\n");
H5Sclose(dataspace_id);
H5Pclose(plist_id);
H5Fclose(file_id);
return;
}
if (H5Dwrite(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, chunk_data) < 0) {
fprintf(stderr, "Error: Failed to write data to dataset\n");
} else {
printf("Data successfully written to %s\n", filename);
}
H5Dclose(dataset_id);
H5Sclose(dataspace_id);
H5Pclose(plist_id);
H5Fclose(file_id);
printf("Chunk %d saved to %s\n", chunk_index, filename);
}
void combine_chunks(int total_chunks) {
printf("Combining %d chunks into final file\n", total_chunks);
hid_t final_file_id = H5Fcreate("simulation_data.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
if (final_file_id < 0) {
fprintf(stderr, "Error: Failed to create final file simulation_data.h5\n");
return;
}
hsize_t total_size = 0;
for (int i = 0; i < total_chunks; i++) {
char filename[50];
sprintf(filename, "simulation_chunk_%d.h5", i);
hid_t chunk_file_id = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT);
if (chunk_file_id < 0) {
fprintf(stderr, "Error: Failed to open chunk file %s\n", filename);
H5Fclose(final_file_id);
return;
}
hid_t dataset_id = H5Dopen2(chunk_file_id, "data", H5P_DEFAULT);
if (dataset_id < 0) {
fprintf(stderr, "Error: Failed to open dataset in chunk file %s\n", filename);
H5Fclose(chunk_file_id);
H5Fclose(final_file_id);
return;
}
hid_t dataspace_id = H5Dget_space(dataset_id);
hsize_t dims[2];
H5Sget_simple_extent_dims(dataspace_id, dims, NULL);
total_size += dims[0] * dims[1];
H5Sclose(dataspace_id);
H5Dclose(dataset_id);
H5Fclose(chunk_file_id);
}
hsize_t final_dims[2] = { total_size / 8, 8 };
hid_t final_dataspace_id = H5Screate_simple(2, final_dims, NULL);
if (final_dataspace_id < 0) {
fprintf(stderr, "Error: Failed to create dataspace for final file\n");
H5Fclose(final_file_id);
return;
}
hid_t final_plist_id = H5Pcreate(H5P_DATASET_CREATE);
H5Pset_deflate(final_plist_id, 9); // Maximum compression level
H5Pset_chunk(final_plist_id, 2, final_dims);
hid_t final_dataset_id = H5Dcreate2(final_file_id, "data", H5T_NATIVE_DOUBLE, final_dataspace_id, H5P_DEFAULT, final_plist_id, H5P_DEFAULT);
if (final_dataset_id < 0) {
fprintf(stderr, "Error: Failed to create dataset in final file\n");
H5Sclose(final_dataspace_id);
H5Pclose(final_plist_id);
H5Fclose(final_file_id);
return;
}
hsize_t offset = 0;
for (int i = 0; i < total_chunks; i++) {
char filename[50];
sprintf(filename, "simulation_chunk_%d.h5", i);
hid_t chunk_file_id = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT);
if (chunk_file_id < 0) {
fprintf(stderr, "Error: Failed to open chunk file %s\n", filename);
H5Fclose(final_dataset_id);
H5Fclose(final_dataspace_id);
H5Pclose(final_plist_id);
H5Fclose(final_file_id);
return;
}
hid_t dataset_id = H5Dopen2(chunk_file_id, "data", H5P_DEFAULT);
if (dataset_id < 0) {
fprintf(stderr, "Error: Failed to open dataset in chunk file %s\n", filename);
H5Fclose(chunk_file_id);
H5Fclose(final_dataset_id);
H5Fclose(final_dataspace_id);
H5Pclose(final_plist_id);
H5Fclose(final_file_id);
return;
}
hid_t dataspace_id = H5Dget_space(dataset_id);
hsize_t dims[2];
H5Sget_simple_extent_dims(dataspace_id, dims, NULL);
hsize_t chunk_size = dims[0] * dims[1];
double* chunk_data = (double*)malloc(chunk_size * sizeof(double));
if (chunk_data == NULL) {
fprintf(stderr, "Error: Memory allocation failed for chunk data\n");
H5Sclose(dataspace_id);
H5Dclose(dataset_id);
H5Fclose(chunk_file_id);
H5Fclose(final_dataset_id);
H5Fclose(final_dataspace_id);
H5Pclose(final_plist_id);
H5Fclose(final_file_id);
return;
}
H5Dread(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, chunk_data);
hsize_t final_offset[2] = { offset, 0 };
hsize_t final_count[2] = { dims[0], dims[1] };
hid_t final_memspace_id = H5Screate_simple(2, final_count, NULL);
H5Sselect_hyperslab(final_dataspace_id, H5S_SELECT_SET, final_offset, NULL, final_count, NULL);
H5Dwrite(final_dataset_id, H5T_NATIVE_DOUBLE, final_memspace_id, final_dataspace_id, H5P_DEFAULT, chunk_data);
free(chunk_data);
H5Sclose(final_memspace_id);
H5Sclose(dataspace_id);
H5Dclose(dataset_id);
H5Fclose(chunk_file_id);
offset += dims[0];
// Delete the chunk file after combining
if (remove(filename) != 0) {
fprintf(stderr, "Error: Failed to delete chunk file %s\n", filename);
} else {
printf("Chunk file %s deleted successfully\n", filename);
}
}
H5Dclose(final_dataset_id);
H5Sclose(final_dataspace_id);
H5Pclose(final_plist_id);
H5Fclose(final_file_id);
printf("All chunks combined into final file successfully\n");
}
import numpy as np
import h5py
import matplotlib.pyplot as plt
# Define the path to the combined HDF5 file
combined_file_path = "simulation_data.h5"
# Open the HDF5 file and read the data
with h5py.File(combined_file_path, 'r') as f:
data = f['data'][:]
# Extract the relevant columns from the data
ox = data[:, 0]
oy = data[:, 1]
oz = data[:, 2]
rx = data[:, 3]
ry = data[:, 4]
rz = data[:, 5]
difficulty = data[:, 7]
# Create a scatter plot of the points, colored by difficulty
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')
sc = ax.scatter(rx, ry, rz, c=difficulty, cmap='viridis', s=1)
# Add color bar to indicate the difficulty levels
cbar = plt.colorbar(sc)
cbar.set_label('Difficulty')
# Set labels and title
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_title('Visualizing Points with Color-coded Difficulty')
# Show the plot
plt.show()
@mcneds
Copy link
Author

mcneds commented Aug 6, 2024

image
This is what the visualizer looks like.
The file that the generator outputs is ~25mb.

@mcneds
Copy link
Author

mcneds commented Aug 7, 2024

image

Static data visualized

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment