1
0
mirror of https://github.com/JustinSDK/dotSCAD.git synced 2025-08-30 01:40:02 +02:00

move files

This commit is contained in:
Justin Lin
2019-09-08 14:56:09 +08:00
parent 10744c9337
commit ff2cf213da
9 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,77 @@
include <line2d.scad>;
include <square_maze.scad>;
maze_rows = 8;
block_width = 2;
wall_thickness = 1;
inner_cube = false;
travel_all = true;
module cube_maze(maze_rows, block_width, wall_thickness, inner_cube, travel_all) {
blocks_size = block_width * maze_rows;
cube_size = blocks_size - wall_thickness;
maze_size = blocks_size + wall_thickness;
half_wall_thickness = wall_thickness / 2;
half_cube_size = cube_size / 2;
half_maze_size = maze_size / 2;
origin = half_wall_thickness - half_maze_size;
module two_mazes() {
module one_maze() {
translate([origin, origin, half_cube_size])
linear_extrude(wall_thickness) build_square_maze(
maze_rows,
maze_rows,
go_maze(
1, 1, // starting point
starting_maze(maze_rows, maze_rows),
maze_rows, maze_rows
),
block_width,
wall_thickness
);
}
one_maze();
rotate([180, 0, 0])
one_maze();
}
if(inner_cube) {
cube(cube_size + 0.01, center= true);
}
difference() {
union() {
two_mazes();
rotate([90, 0, 0]) two_mazes();
rotate([0, 90, 0]) two_mazes();
}
if(travel_all) {
union() {
translate([half_maze_size - wall_thickness * 2, -half_maze_size, half_cube_size])
cube(wall_thickness);
translate([half_maze_size - wall_thickness, half_maze_size - wall_thickness * 2, half_cube_size])
cube(wall_thickness);
translate([half_maze_size - wall_thickness, half_maze_size - wall_thickness, -half_cube_size])
cube(wall_thickness);
translate([-half_maze_size + wall_thickness, half_maze_size - wall_thickness, -half_cube_size - wall_thickness])
cube(wall_thickness);
translate([-half_maze_size, -half_maze_size + wall_thickness, -half_cube_size - wall_thickness])
cube(wall_thickness);
translate([-half_maze_size, -half_maze_size, half_cube_size - wall_thickness])
cube(wall_thickness);
}
}
}
}
cube_maze(maze_rows, block_width, wall_thickness, inner_cube, travel_all);

View File

@@ -0,0 +1,91 @@
include <hollow_out.scad>;
include <bend.scad>;
include <square_maze.scad>;
radius = 30;
height = 60;
block_width = 8;
wall_thickness = 5;
wall_height = 5;
wall_top_scale = 0.25;
fn = 24;
module build_ramp_maze(rows, columns, blocks, block_width, wall_thickness, wall_height, wall_top_scale) {
module ramp_line(point1, point2, width = 1, height = 1, top_scale = 0.25) {
angle = 90 - atan((point2[1] - point1[1]) / (point2[0] - point1[0]));
offset_x = 0.5 * width * cos(angle);
offset_y = 0.5 * width * sin(angle);
offset1 = [-offset_x, offset_y];
offset2 = [offset_x, -offset_y];
hull() {
translate(point1)
linear_extrude(height, scale = top_scale)
square(width, center = true);
translate(point2)
linear_extrude(height, scale = top_scale)
square(width, center = true);
}
}
module draw_ramp_block(wall_type, block_width, wall_thickness, wall_height, wall_top_scale) {
if(wall_type == UPPER_WALL || wall_type == UPPER_RIGHT_WALL) {
ramp_line(
[0, block_width], [block_width, block_width], wall_thickness, wall_height, wall_top_scale
);
}
if(wall_type == RIGHT_WALL || wall_type == UPPER_RIGHT_WALL) {
ramp_line(
[block_width, block_width], [block_width, 0], wall_thickness, wall_height, wall_top_scale
);
}
}
for(block = blocks) {
translate([get_x(block) - 1, get_y(block) - 1] * block_width)
draw_ramp_block(
get_wall_type(block),
block_width,
wall_thickness,
wall_height,
wall_top_scale
);
}
ramp_line(
[0, 0], [block_width * columns, 0],
wall_thickness, wall_height, wall_top_scale
);
}
module maze_cylinder() {
maze_rows = round(height / block_width);
maze_columns = round(2 * 3.14159 * radius / block_width);
maze_blocks = go_maze(
1, maze_rows,
starting_maze(maze_rows, maze_columns),
maze_rows, maze_columns,
x_circular = true
);
leng_circumference = block_width * maze_columns + wall_thickness;
bend(size = [leng_circumference, block_width * maze_rows + wall_thickness, wall_height], angle = 360 + 360 * wall_thickness / leng_circumference, frags = fn)
translate([0, wall_thickness / 2, 0]) build_ramp_maze(
maze_rows,
maze_columns,
maze_blocks,
block_width,
wall_thickness,
wall_height,
wall_top_scale
);
}
maze_cylinder();

View File

@@ -0,0 +1,65 @@
include <line2d.scad>;
include <arc.scad>;
number_of_circles = 15;
minimum_radius = 3;
gap_distance = 3;
line_width = 1.5;
module euler_maze(n, r, d, width = 1) {
function angle(r, d) = acos(
(2 * pow(r, 2) - pow(d, 2)) / (2 * pow(r, 2))
);
module oneGapCircle(r, d, gap_angle1, gap_angle2, width = 1) {
arc(radius = r, angle = [gap_angle2, gap_angle1 + 360], width = width);
}
module twoGapsCircle(r, d, gap_angle, gap_angle1_begin, gap_angle2_begin, width = 1) {
arc(radius = r, angle = [gap_angle1_begin + gap_angle, gap_angle2_begin], width = width);
arc(radius = r, angle = [gap_angle2_begin + gap_angle, gap_angle1_begin + 360], width = width);
}
module euler_circles(n, inner_r, pre_gap_angle, pre_gap_angle_offset) {
outer_r = inner_r + r;
gap_angle = angle(outer_r, d);
gap_angle_offset = pre_gap_angle_offset + pre_gap_angle / 2 - gap_angle / 2;
p1 = [inner_r * cos(pre_gap_angle_offset), inner_r * sin(pre_gap_angle_offset)];
p2 = [outer_r * cos(gap_angle_offset), outer_r * sin(gap_angle_offset)];
p3 = [inner_r * cos(pre_gap_angle + pre_gap_angle_offset), inner_r * sin(pre_gap_angle + pre_gap_angle_offset)];
p4 = [outer_r * cos(gap_angle_offset + gap_angle), outer_r * sin(gap_angle_offset + gap_angle)];
line2d(p1, p2, width = width, p1Style = "CAP_ROUND", p2Style = "CAP_ROUND");
line2d(p3, p4, width = width, p1Style = "CAP_ROUND", p2Style = "CAP_ROUND");
if(n != 0) {
rand_a = rands(15, 180, 15)[0];
angle_between_gap = rand_a - gap_angle;
twoGapsCircle(outer_r, d,
gap_angle,
gap_angle_offset,
gap_angle_offset + gap_angle + angle_between_gap,
width = width);
euler_circles(n - 1, outer_r, gap_angle, gap_angle_offset + rand_a);
} else {
oneGapCircle(outer_r, d, gap_angle_offset, gap_angle_offset + gap_angle, width = width);
}
}
gap_angle = angle(r, d);
oneGapCircle(r, d, 0, gap_angle, width = width);
euler_circles(n - 2, r, gap_angle, 0);
}
euler_maze(
number_of_circles,
minimum_radius,
gap_distance,
line_width,
$fn = 96
);

View File

@@ -0,0 +1,26 @@
include <hull_polyline3d.scad>;
include <rotate_p.scad>;
include <square_maze.scad>;
rows = 48;
columns = 8;
block_width = 2;
wall_thickness = 1;
angle = 180;
// $fn = 24;
leng = rows * block_width;
radius = 0.5 * leng / PI;
a_step = 360 / leng;
blocks = go_maze(
1, 1, // starting point
starting_maze(rows, columns),
rows, columns, y_circular = true
);
walls = maze_walls(blocks, rows, columns, block_width, bottom_border = false);
for(wall_pts = y_twist(walls, angle, rows, columns, block_width)) {
z_rotated = [for(pt = wall_pts) rotate_p([radius + pt[0], 0, pt[2]], a_step * pt[1])];
hull_polyline3d(z_rotated, wall_thickness);
}

View File

@@ -0,0 +1,70 @@
include <line2d.scad>;
include <square_maze.scad>;
maze_rows = 8;
block_width = 10;
stairs_width = 5;
module pyramid_with_stairs(base_width, stairs_width, rows) {
height = base_width * sqrt(2) / 2;
module layer(i) {
base_w = base_width - (base_width / rows) * (i - 1) + stairs_width;
floor_h = height / rows * 2;
stairsteps = rows;
staircase_h = floor_h / stairsteps;
staircase_w = stairs_width / stairsteps * 2;
translate([0, 0, floor_h / 2 * (i - 1)])
for(j = [1:stairsteps]) {
square_w = base_w - j * staircase_w;
translate([0, 0, staircase_h * (j - 1)])
linear_extrude(staircase_h)
square([square_w, square_w], center = true);
}
}
for(i = [1:2:rows - 1]) {
layer(i);
}
}
module pyramidal_staircase_maze(maze_rows, block_width, stairs_width) {
maze_blocks = go_maze(
1, 1, // starting point
starting_maze(maze_rows, maze_rows),
maze_rows, maze_rows
);
intersection() {
pyramid_with_stairs(
maze_rows * block_width, stairs_width, maze_rows);
linear_extrude(maze_rows * block_width * sqrt(2) / 2) difference() {
square([block_width * maze_rows + stairs_width, block_width * maze_rows + stairs_width], center = true);
translate([-(maze_rows * block_width) / 2, -(maze_rows * block_width) / 2, 0])
difference() {
build_square_maze(
maze_rows,
maze_rows,
maze_blocks,
block_width,
stairs_width
);
// entry
translate([0, stairs_width])
square(stairs_width, center = true);
// exit
translate([maze_rows * block_width, maze_rows * block_width - stairs_width])
square(stairs_width, center = true);
}
}
}
}
pyramidal_staircase_maze(maze_rows, block_width, stairs_width);

View File

@@ -0,0 +1,278 @@
NO_WALL = 0;
UPPER_WALL = 1;
RIGHT_WALL = 2;
UPPER_RIGHT_WALL = 3;
function block_data(x, y, wall_type, visited) = [x, y, wall_type, visited];
function get_x(block_data) = block_data[0];
function get_y(block_data) = block_data[1];
function get_wall_type(block_data) = block_data[2];
// create a starting maze for being visited later.
function starting_maze(rows, columns) = [
for(y = [1:rows])
for(x = [1:columns])
block_data(
x, y,
// all blocks have upper and right walls
UPPER_RIGHT_WALL,
// unvisited
false
)
];
// find out the index of a block with the position (x, y)
function indexOf(x, y, maze, i = 0) =
i > len(maze) ? -1 : (
[get_x(maze[i]), get_y(maze[i])] == [x, y] ? i :
indexOf(x, y, maze, i + 1)
);
// is (x, y) visited?
function visited(x, y, maze) = maze[indexOf(x, y, maze)][3];
// is (x, y) visitable?
function visitable(x, y, maze, rows, columns) =
y > 0 && y <= rows && // y bound
x > 0 && x <= columns && // x bound
!visited(x, y, maze); // unvisited
// setting (x, y) as being visited
function set_visited(x, y, maze) = [
for(b = maze)
[x, y] == [get_x(b), get_y(b)] ?
[x, y, get_wall_type(b), true] : b
];
// 0(right)、1(upper)、2(left)、3(down)
function rand_dirs() =
[
[0, 1, 2, 3],
[0, 1, 3, 2],
[0, 2, 1, 3],
[0, 2, 3, 1],
[0, 3, 1, 2],
[0, 3, 2, 1],
[1, 0, 2, 3],
[1, 0, 3, 2],
[1, 2, 0, 3],
[1, 2, 3, 0],
[1, 3, 0, 2],
[1, 3, 2, 0],
[2, 0, 1, 3],
[2, 0, 3, 1],
[2, 1, 0, 3],
[2, 1, 3, 0],
[2, 3, 0, 1],
[2, 3, 1, 0],
[3, 0, 1, 2],
[3, 0, 2, 1],
[3, 1, 0, 2],
[3, 1, 2, 0],
[3, 2, 0, 1],
[3, 2, 1, 0]
][round(rands(0, 24, 1)[0])];
// get x value by dir
function next_x(x, dir, columns, circular) =
let(nx = x + [1, 0, -1, 0][dir])
circular ?
nx < 1 ? nx + columns : (
nx > columns ? nx % columns : nx
)
:
nx;
// get y value by dir
function next_y(y, dir, rows, circular) =
let(ny = y + [0, 1, 0, -1][dir])
circular ?
ny < 1 ? ny + rows : (
ny > rows ? ny % rows : ny
)
:
ny;
// go right and carve the right wall
function go_right_from(x, y, maze) = [
for(b = maze) [get_x(b), get_y(b)] == [x, y] ? (
get_wall_type(b) == UPPER_RIGHT_WALL ?
[x, y, UPPER_WALL, visited(x, y, maze)] :
[x, y, NO_WALL, visited(x, y, maze)]
) : b
];
// go up and carve the upper wall
function go_up_from(x, y, maze) = [
for(b = maze) [get_x(b), get_y(b)] == [x, y] ? (
get_wall_type(b) == UPPER_RIGHT_WALL ?
[x, y, RIGHT_WALL, visited(x, y, maze)] :
[x, y, NO_WALL, visited(x, y, maze)]
) : b
];
// go left and carve the right wall of the left block
function go_left_from(x, y, maze, columns) =
let(
x_minus_one = x - 1,
nx = x_minus_one < 1 ? x_minus_one + columns : x_minus_one
)
[
for(b = maze) [get_x(b), get_y(b)] == [nx, y] ? (
get_wall_type(b) == UPPER_RIGHT_WALL ?
[nx, y, UPPER_WALL, visited(nx, y, maze)] :
[nx, y, NO_WALL, visited(nx, y, maze)]
) : b
];
// go down and carve the upper wall of the down block
function go_down_from(x, y, maze, rows) = [
let(
y_minus_one = y - 1,
ny = y_minus_one < 1 ? y_minus_one + rows : y_minus_one
)
for(b = maze) [get_x(b), get_y(b)] == [x, ny] ? (
get_wall_type(b) == UPPER_RIGHT_WALL ?
[x, ny, RIGHT_WALL, visited(x, ny, maze)] :
[x, ny, NO_WALL, visited(x, ny, maze)]
) : b
];
// 0(right)、1(upper)、2(left)、3(down)
function try_block(dir, x, y, maze, rows, columns) =
dir == 0 ? go_right_from(x, y, maze) : (
dir == 1 ? go_up_from(x, y, maze) : (
dir == 2 ? go_left_from(x, y, maze, columns) :
go_down_from(x, y, maze, rows) // dir is 3
)
);
// find out visitable dirs from (x, y)
function visitable_dirs_from(x, y, maze, rows, columns, x_circular, y_circular) = [
for(dir = [0, 1, 2, 3])
if(visitable(next_x(x, dir, columns, x_circular), next_y(y, dir, rows, y_circular), maze, rows, columns))
dir
];
// go maze from (x, y)
function go_maze(x, y, maze, rows, columns, x_circular = false, y_circular = false) =
// have visitable dirs?
len(visitable_dirs_from(x, y, maze, rows, columns, x_circular, y_circular)) == 0 ?
set_visited(x, y, maze) // road closed
: walk_around_from(
x, y,
rand_dirs(),
set_visited(x, y, maze),
rows, columns,
x_circular, y_circular
);
// try four directions
function walk_around_from(x, y, dirs, maze, rows, columns, x_circular, y_circular, i = 4) =
// all done?
i > 0 ?
// not yet
walk_around_from(x, y, dirs,
// try one direction
try_routes_from(x, y, dirs[4 - i], maze, rows, columns, x_circular, y_circular),
rows, columns,
x_circular, y_circular,
i - 1)
: maze;
function try_routes_from(x, y, dir, maze, rows, columns, x_circular, y_circular) =
// is the dir visitable?
visitable(next_x(x, dir, columns, x_circular), next_y(y, dir, rows, y_circular), maze, rows, columns) ?
// try the block
go_maze(
next_x(x, dir, columns, x_circular), next_y(y, dir, rows, y_circular),
try_block(dir, x, y, maze, rows, columns),
rows, columns,
x_circular, y_circular
)
// road closed so return maze directly
: maze;
module build_square_maze(rows, columns, blocks, block_width, wall_thickness, left_border = true, bottom_border = true) {
module build_block(wall_type, block_width, wall_thickness) {
if(wall_type == UPPER_WALL || wall_type == UPPER_RIGHT_WALL) {
// draw a upper wall
line2d(
[0, block_width], [block_width, block_width], wall_thickness
);
}
if(wall_type == RIGHT_WALL || wall_type == UPPER_RIGHT_WALL) {
// draw a right wall
line2d(
[block_width, block_width], [block_width, 0], wall_thickness
);
}
}
for(block = blocks) {
// move a block to a right position.
translate([get_x(block) - 1, get_y(block) - 1] * block_width)
build_block(
get_wall_type(block),
block_width,
wall_thickness
);
}
if(left_border) {
line2d([0, 0], [0, block_width * rows], wall_thickness);
}
if(bottom_border) {
line2d([0, 0], [block_width * columns, 0], wall_thickness);
}
}
function block_walls(block, block_width) =
let(
loc = [get_x(block) - 1, get_y(block) - 1] * block_width,
wall_type = get_wall_type(block),
upper_wall = wall_type == UPPER_WALL || wall_type == UPPER_RIGHT_WALL ? [[0, block_width] + loc, [block_width, block_width] + loc] : [],
right_wall = wall_type == RIGHT_WALL || wall_type == UPPER_RIGHT_WALL ? [[block_width, block_width] + loc, [block_width, 0] + loc] : []
)
concat(
upper_wall,
right_wall
);
function maze_walls(blocks, rows, columns, block_width, left_border = true, bottom_border = true) =
let(
left_walls = left_border ? [for(y = [0:rows - 1]) [[0, block_width * (y + 1)], [0, block_width * y]]] : [],
buttom_walls = bottom_border ? [for(x = [0:columns - 1]) [[block_width * x, 0], [block_width * (x + 1), 0]]] : []
)
concat(
[
for(block = blocks)
let(pts = block_walls(block, block_width))
if(pts != []) pts
]
, left_walls, buttom_walls
);
function y_twist(walls, angle, rows, columns, block_width) =
let(
x_offset = columns * block_width / 2,
x_centered = [
for(wall_pts = walls)
[for(pt = wall_pts) [pt[0], pt[1], 0] + [-x_offset, 0, 0]]
],
a_step = angle / (rows * block_width)
)
[
for(wall_pts = x_centered)
[
for(pt = wall_pts)
rotate_p(pt, [0, pt[1] * a_step, 0]) + [x_offset, 0, 0]
]
];

View File

@@ -0,0 +1,128 @@
include <line2d.scad>;
include <polyline2d.scad>;
include <stereographic_extrude.scad>;
include <square_maze.scad>;
x_cells = 10;
cell_radius = 20;
wall_thickness = 12;
fn = 24;
shadow = "YES"; // [YES, NO]
wall_height = 1;
// build a hex maze
module build_hex_maze(y_cells, x_cells, maze_vector, cell_radius, wall_thickness, left_border = true, bottom_border = true) {
function cell_position(x_cell, y_cell) =
let(
grid_h = 2 * cell_radius * sin(60),
grid_w = cell_radius + cell_radius * cos(60)
)
[grid_w * x_cell, grid_h * y_cell + (x_cell % 2 == 0 ? 0 : grid_h / 2), 0];
module hex_seg(begin, end) {
polyline2d(
[for(a = [begin:60:end])
[cell_radius * cos(a), cell_radius * sin(a)]],
wall_thickness,
startingStyle = "CAP_ROUND", endingStyle = "CAP_ROUND"
);
}
module up_right_wall() { hex_seg(0, 60); }
module upper_wall() { hex_seg(60, 120); }
module up_left_wall() { hex_seg(120, 180); }
module down_left_wall() { hex_seg(180, 240); }
module down_wall() { hex_seg(240, 300); }
module down_right_wall() { hex_seg(300, 360); }
module build_cell(x, y, wall_type) {
module build_right_wall(x_cell) {
if(x_cell % 2 != 0) {
down_right_wall();
}
else {
up_right_wall();
}
}
module build_row_wall(x_cell, y_cell) {
if(x_cell % 2 != 0) {
up_right_wall();
up_left_wall();
}
else {
down_right_wall();
}
}
build_row_wall(x, y);
if(wall_type == UPPER_WALL || wall_type == UPPER_RIGHT_WALL) {
upper_wall();
}
if(wall_type == RIGHT_WALL || wall_type == UPPER_RIGHT_WALL) {
build_right_wall(x);
}
}
// create the wall of maze
for(cell = maze_vector) {
x = cell[0] - 1;
y = cell[1] - 1;
wall_type = cell[2];
translate(cell_position(x, y)) {
build_cell(x, y, wall_type);
}
}
if(left_border) {
for(y = [0:y_cells - 1]) {
translate(cell_position(0, y)) {
up_left_wall();
down_left_wall();
}
}
}
if(bottom_border) {
for(x = [0:x_cells - 1]) {
translate(cell_position(x, 0)) {
down_wall();
if(x % 2 == 0) {
down_left_wall();
down_right_wall();
}
}
}
}
}
module hex_maze_stereographic_projection(x_cells, cell_radius, wall_thickness, fn, wall_height, shadow) {
y_cells = round(0.866 * x_cells - 0.211);
grid_h = 2 * cell_radius * sin(60);
grid_w = cell_radius + cell_radius * cos(60);
square_w = grid_w * (x_cells - 1) + cell_radius * 2 + wall_thickness * 2;
square_h = grid_h * y_cells + grid_h / 2 + wall_thickness * 2;
square_offset_x = square_w / 2 -cell_radius - wall_thickness;
square_offset_y = square_h / 2 -grid_h / 2 - wall_thickness;
pyramid_height = square_w / sqrt(2);
// create a maze
maze_vector = go_maze(1, 1, starting_maze(y_cells, x_cells), y_cells, x_cells);
stereographic_extrude(square_w, $fn = fn)
translate([grid_w - square_w / 2, grid_h - square_w / 2, 0])
build_hex_maze(y_cells, x_cells, maze_vector, cell_radius, wall_thickness);
if(shadow == "YES") {
color("black")
linear_extrude(wall_height)
translate([grid_w - square_w / 2, grid_h - square_w / 2, 0])
build_hex_maze(y_cells, x_cells, maze_vector, cell_radius, wall_thickness);
}
}
hex_maze_stereographic_projection(x_cells, cell_radius, wall_thickness, fn, wall_height, shadow);

View File

@@ -0,0 +1,42 @@
include <line2d.scad>;
include <stereographic_extrude.scad>;
include <square_maze.scad>;
maze_rows = 10;
block_width = 40;
wall_thickness = 20;
fn = 24;
shadow = "YES"; // [YES, NO]
wall_height = 2;
module stereographic_projection_maze2(maze_rows, block_width, wall_thickness, fn, wall_height, shadow) {
maze_blocks = go_maze(
1, 1, // starting point
starting_maze(maze_rows, maze_rows),
maze_rows, maze_rows
);
length = block_width * maze_rows + wall_thickness;
module maze() {
translate([-block_width * maze_rows / 2, -block_width * maze_rows / 2, 0])
build_square_maze(
maze_rows,
maze_rows,
maze_blocks,
block_width,
wall_thickness
);
}
stereographic_extrude(shadow_side_leng = length, $fn = fn)
maze();
if(shadow == "YES") {
color("black")
linear_extrude(wall_height)
maze();
}
}
stereographic_projection_maze2(maze_rows, block_width, wall_thickness, fn, wall_height, shadow);

View File

@@ -0,0 +1,22 @@
include <hull_polyline3d.scad>;
include <rotate_p.scad>;
include <square_maze.scad>;
rows = 16;
columns = 8;
block_width = 4;
wall_thickness = 1;
angle = 180;
// $fn = 24;
blocks = go_maze(
1, 1, // starting point
starting_maze(rows, columns),
rows, columns
);
walls = maze_walls(blocks, rows, columns, block_width);
for(wall_pts = y_twist(walls, angle, rows, columns, block_width)) {
hull_polyline3d(wall_pts, wall_thickness);
}