jukebox/cartridge.scad

269 lines
5.7 KiB
OpenSCAD

// Cartridge base dimensions
cartridge_width = 102;
cartridge_length = 133;
cartridge_height = 21;
// Tape guide dimensions
tape_guide_width = 6;
tape_guide_depth = 16;
tape_guide_slope = tape_guide_width / tape_guide_depth;
// Track dimensions
track_front_inset = 8;
track_back_inset = 4;
track_side_inset = 6;
track_radius = 1;
track_taper_length = 12;
// Foot dimensions
foot_width = 2.5;
foot_height = 1;
foot_front_inset = 8;
foot_back_inset = 4;
foot_side_inset = 6;
// Fillets
back_vertical_fillet_radius = 4;
side_vertical_fillet_radius = 16;
front_vertical_fillet_radius = 5;
horizontal_fillets_radius = 1;
// Windows on front wall
window_vertical_inset = 2;
window_side_inset = 14;
window_depth = 6; // 13
left_window_width = 20;
right_window_width = 20;
window_gap = 5;
roller_window_depth = 8;
roller_window_offset = 3.5;
// Emulated gap between top and bottom half
gap_height = 1;
gap_depth = 0.3;
gap_elevation = 14;
// Grips
grip_wedge_width = 2.5;
grip_count = 5;
// Tape
roller_inset = 0;
roller_radius = 0;
roller_position = [12, 79.5];
tape_line_position = [2, 14];
tape_height = 6.4;
// NFC Coin
nfc_coin_depth = 1;
nfc_coin_diameter = 25;
nfc_coin_tolerance = 0.1;
module cartridge() {
difference() {
base();
windows();
grips();
gap();
undercut();
nfc_coin();
}
tape();
}
module base() {
translate([0, 0, horizontal_fillets_radius]) minkowski() {
linear_extrude(cartridge_height - 2 * horizontal_fillets_radius)
offset(-horizontal_fillets_radius)
footprint();
sphere(horizontal_fillets_radius);
}
tracks();
feet();
}
module windows() {
rectangular_windows();
roller_window();
}
module rectangular_windows() {
translate([
0,
window_side_inset,
window_vertical_inset
]) {
window_height = cartridge_height - 2 * window_vertical_inset;
cube([window_depth, left_window_width, window_height]);
translate([
0,
left_window_width + window_gap,
])
cube([window_depth, right_window_width, window_height]);
}
}
module roller_window() {
translate([
-roller_window_depth,
roller_position.y - roller_window_offset,
])
cylinder(h=cartridge_height, r=12);
}
module grips() {
for(i=[0:grip_count-1]) {
translate([cartridge_length - i * grip_wedge_width - back_vertical_fillet_radius, 0]) {
grip_wedge();
translate([0, cartridge_width]) mirror([0, 1]) grip_wedge();
}
}
}
module grip_wedge() {
linear_extrude(gap_elevation)
polygon([
[0, 0],
[0, 1 + gap_depth],
[-grip_wedge_width, gap_depth],
[-grip_wedge_width, 0]
]);
}
module gap() {
translate([0, 0, gap_elevation])
linear_extrude(gap_height)
difference() {
footprint();
offset(-gap_depth) footprint();
}
}
module undercut() {
translate([53, cartridge_width - 7, -foot_height])
linear_extrude(gap_elevation + foot_height)
rotate(45)
offset(3)
square([16, 16]);
}
module tape() {
translate([0, 0, (cartridge_height - tape_height) / 2]) {
roller();
tape_line();
}
}
module roller() {
translate(roller_position)
cylinder(
h=tape_height,
r=10,
);
}
module tape_line() {
translate(tape_line_position)
cube([
window_depth - tape_line_position.x,
roller_position.y - tape_line_position.y,
tape_height
]);
}
module nfc_coin() {
translate([
cartridge_length / 2,
cartridge_width / 2,
cartridge_height - nfc_coin_depth
])
cylinder(
h=nfc_coin_depth + nfc_coin_tolerance,
d=nfc_coin_diameter + 2 * nfc_coin_tolerance,
);
};
module footprint() {
hull() {
one_side_vertical_fillets();
translate([0, cartridge_width]) mirror([0, 1]) one_side_vertical_fillets();
}
}
module one_side_vertical_fillets() {
translate([
cartridge_length - back_vertical_fillet_radius,
back_vertical_fillet_radius,
])
circle(back_vertical_fillet_radius);
translate([
tape_guide_depth + side_vertical_fillet_radius * tan(0.5 * atan(tape_guide_slope)),
side_vertical_fillet_radius,
])
circle(side_vertical_fillet_radius);
translate([
front_vertical_fillet_radius,
tape_guide_width + front_vertical_fillet_radius * tan(0.5 * atan(1 / tape_guide_slope)),
])
circle(front_vertical_fillet_radius);
}
module tracks() {
track_interval = cartridge_width - 2 * track_side_inset;
translate([track_front_inset, track_side_inset, cartridge_height])
rotate([0, 90, 0]) {
track();
translate([0, track_interval]) track();
}
}
module track() {
track_length = cartridge_length - track_front_inset - track_back_inset;
cylinder(
h=track_taper_length,
r1=0,
r2=track_radius,
);
translate([0, 0, track_taper_length]) cylinder(
h=track_length - 2 * track_taper_length,
r=track_radius,
);
translate([0, 0, track_length - track_taper_length]) cylinder(
h=track_taper_length,
r1=track_radius,
r2=0,
);
}
module feet() {
foot_interval = cartridge_width - 2 * foot_side_inset - foot_width;
translate([foot_front_inset, foot_side_inset, -foot_height]) {
foot();
translate([0, foot_interval, 0]) foot();
}
}
module foot() {
foot_length = cartridge_length - foot_front_inset - foot_back_inset;
translate([foot_height, 0])
cube([
foot_length - foot_height * 2,
foot_width,
foot_height,
]);
intersection() {
cube([
cartridge_length,
foot_width,
foot_height,
]);
union() {
translate([foot_height, foot_width, foot_height])
rotate([90, 90, 0])
cylinder(h=foot_width, r=foot_height);
translate([foot_length - foot_height, foot_width, foot_height])
rotate([90, 90, 0])
cylinder(h=foot_width, r=foot_height);
}
}
}