New paste Repaste Download
// Brachistochrone Curve Marble Run Track Section
// Generates the first half of the arch (0-180 deg)
// Creates a channel suitable for a 20mm marble.
// Assumes units are in mm.
// --- Parameters ---
// Marble Properties
marble_diameter = 20; // mm
marble_radius = marble_diameter / 2;
// Track Design Properties
channel_clearance = 1; // Extra space around marble in channel (mm) on each side
wall_thickness = 3;  // Thickness of the track walls (mm)
base_thickness = 3;  // Thickness of the track base below the channel lowest point (mm)
// Curve Definition
// Radius 'r' of the generating circle (mm).
// This determines the overall scale and "depth" of the curve arch.
// Adjust this to control the curve steepness and overall size for your run.
// A larger radius makes the curve shallower relative to its length.
cycloid_radius = 50;
theta_max_deg = 180; // Use 180 degrees for the first half of the cycloid arch (starts steep, ends flat)
// Resolution and Rendering
steps = 100; // Number of points along the curve (more = smoother but slower)
$fa = 1;
$fs = 0.4;
// --- Calculated Track Dimensions ---
// Radius of the channel to be cut out (marble + clearance)
channel_radius = marble_radius + channel_clearance;
// Radius of the solid tube needed before cutting the base flat and carving the channel
// This needs to accommodate the channel radius plus the wall thickness.
solid_path_radius = channel_radius + wall_thickness;
// --- Curve Generation ---
// Function to calculate a point (x, y, z) on the inverted cycloid
// Input: theta_deg (degrees), r (cycloid generating radius)
// Output: [x, y, z] coordinates
function brachistochrone_point(theta_deg, r) =
    let(
        // Convert degrees to radians ONLY for the r*theta term in the formula
        theta_rad = theta_deg * PI / 180
    )
    [
        r * (theta_rad - sin(theta_deg)),  // x = r*(theta_rad - sin(theta_deg))
        r * (cos(theta_deg) - 1),          // y = r*(cos(theta_deg) - 1) [Inverted: y goes from 0 downwards]
        0                                  // z = 0 (Path lies in XY plane initially)
    ];
// Generate a list of points along the curve path
points = [ for (i = [0:steps])
             let(current_theta_deg = i/steps * theta_max_deg)
             brachistochrone_point(current_theta_deg, cycloid_radius)
         ];
// --- Helper Module for Creating Path Tube ---
// Module to draw a tube-like path by creating hulls between consecutive spheres
// This is used for both the solid part and the channel cutout.
module draw_curve_cutout(pts, tube_r) {
  hull() {
    for (i = [0 : len(pts) - 1]) {
      translate(pts[i]) sphere(r=tube_r);
    }
    // Add a sphere at the very last point for cleaner ends, especially for the subtraction
    translate(pts[len(pts)-1]) sphere(r=tube_r);
    // Add a sphere at the very first point too for symmetry
    translate(pts[0]) sphere(r=tube_r);
    translate([pts[len(pts)-1][0], pts[0][1], pts[0][2]]) sphere(r=tube_r);
  }
}
// --- Track Construction ---
// Calculate approximate bounding box of the path for efficient intersection cube size
min_x = min([for (p=points) p.x]);
max_x = max([for (p=points) p.x]);
min_y = min([for (p=points) p.y]); // This will be negative
max_y = max([for (p=points) p.y]); // This will be 0 if starting at theta=0
// Add padding to bounds based on the solid path radius to ensure cube covers everything
bound_padding = solid_path_radius * 1.1; // A little extra margin
bound_min = [min_x - bound_padding, min_y - bound_padding];
bound_max = [max_x + bound_padding, max_y + bound_padding]; // max_y will be ~0
bound_size = [bound_max[0] - bound_min[0], bound_max[1] - bound_min[1]];
// Echo dimensions for information (check Console output after preview/render)
echo("Track X Extent:", max_x);
echo("Track Y Extent (Depth):", min_y); // This is how far down it goes
echo("Solid Path Radius:", solid_path_radius);
echo("Channel Radius:", channel_radius);
// Create the final track shape using difference and intersection
//difference() {
    // Part 1: Create a solid object following the path, with a flat bottom surface.
  //  intersection() {
rotate([90, 0, 0])
difference() {
  translate([-marble_diameter, points[len(points)-1][1] - marble_diameter, -1.2*marble_diameter/2])
    cube([points[len(points)-1][0] + marble_diameter, abs(points[len(points)-1][1]) + marble_diameter, 1.2*marble_diameter]);
  // 1a. Create a thick tube following the path centerline.
  // The radius includes wall thickness.
  draw_curve_cutout(points, solid_path_radius);
}
Filename: None. Size: 5kb. View raw, , hex, or download this file.

This paste expires on 2025-05-25 23:02:10.326436. Pasted through web.