320 lines
13 KiB
OpenSCAD
320 lines
13 KiB
OpenSCAD
// straight and angeled building blocks
|
|
//----------------------- parameters ---------------------------
|
|
/* [Block type] */
|
|
// Type
|
|
Block_type = 0; // [0 : no output, 1:Basic block, 2:Angle block, 3:Symmetric angle block]
|
|
/* [Block options] */
|
|
// Length of a block
|
|
Block_length = 30; // [15.0 : 15.0 : 120.0]
|
|
// Is this a flat block (7.5mm)?
|
|
Flat_block = false;
|
|
// Number of pins
|
|
Pins = 1; // [0, 1, 2]
|
|
// A hole in the middle of the block?
|
|
Has_bore=false;
|
|
// Square holes in the middle?
|
|
Is_square = false;
|
|
/* [Options for the angle block] */
|
|
// Angle of the top side
|
|
Angle = 7.5;
|
|
// Use a pin on the standard angle block?
|
|
With_pin = true;
|
|
/* [Add. options for the sym. angle block] */
|
|
// Which pins should be used?
|
|
Which_pins = 3; // [0: Nothing, 1:left side, 2:right side, 3:both sides]
|
|
// Which grooves should be used?
|
|
Which_grooves = 2; // [0: Nothing, 1:left side, 2:right side, 3:both sides]
|
|
// Which kind of groove at the bottom if no grooves on the sides
|
|
Which_bottom_groove = 2; // [0: None, 1:Flat groove, 2:Round groove]
|
|
// Use short grooves (applied to all grooves)
|
|
Has_short_grooves = true;
|
|
/* [Hidden] */
|
|
|
|
// **********************
|
|
// ** Static Settings: **
|
|
// **********************
|
|
include<ft_util.scad>
|
|
|
|
// --------------------------------------------------------------------
|
|
// A basic block 7,5 or 15 x 15 of arbitrary length.
|
|
// The 15 x 15 block may have 0 - 2 pins at the small side of the block
|
|
// and a hole (either round or a sqare).
|
|
// If the small side has no pin, a groove is placed instead of the pin
|
|
// The default is a block of 30 mm with a pin and a groove and
|
|
// without hole at the center
|
|
// The flat block 7.5 x 15 has flat grooves on the long side and round
|
|
// holes at the small side. It also has no pins or grooves at the
|
|
// bottom or top and no hole in the middle.
|
|
// --------------------------------------------------------------------
|
|
module basic_block(length=30, pins=1, flatblock = false, bore=false, squarehole=false) {
|
|
|
|
y_offset = flatblock ? (BASIC_BLOCK_SIZE / 2) : BASIC_BLOCK_SIZE;
|
|
difference() {
|
|
// First, build the block and cut out the four grooves at the
|
|
// long sides
|
|
cube([BASIC_BLOCK_SIZE, y_offset, length], center=true);
|
|
translate([0, -y_offset/2 ,0])
|
|
rotate ([0, 0, 0])
|
|
if (flatblock)
|
|
flat_groove(length);
|
|
else
|
|
round_groove(length);
|
|
translate([BASIC_BLOCK_HALF, 0, 0])
|
|
rotate([0, 0, 90])
|
|
round_groove(length);
|
|
translate([0, y_offset/2, 0])
|
|
rotate([0, 0, 180])
|
|
if (flatblock)
|
|
flat_groove(length);
|
|
else
|
|
round_groove(length);
|
|
translate([-BASIC_BLOCK_HALF, 0, 0])
|
|
rotate([0, 0, 270])
|
|
round_groove(length);
|
|
// Then, cut out the grooves at the top and bottom as required
|
|
if (!flatblock)
|
|
top_grooves(length, pins);
|
|
// Do we have a hole through the block?
|
|
if (!flatblock && bore) {
|
|
rotate ([90, 0, 0])
|
|
cylinder(h = BASIC_BLOCK_SIZE + MANIFOLD_CORRECTION, r = 2, center = true);
|
|
// and if yes, does it have square endings?
|
|
if (squarehole) {
|
|
translate([0, (BASIC_BLOCK_SIZE - 4.5) / 2, 0])
|
|
cube(4.51, center=true);
|
|
translate([0, -(BASIC_BLOCK_SIZE - 4.5) / 2, 0])
|
|
cube(4.51, center=true);
|
|
}
|
|
}
|
|
}
|
|
// Finally add the pins as required
|
|
if (!flatblock)
|
|
top_pins(length, pins);
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
// add the grooves at the top and bottom of the block
|
|
// --------------------------------------------------------------------
|
|
module top_grooves(length = 30, pins = 1) {
|
|
// small correction value for the cutouts
|
|
mfc = 0.01;
|
|
if (pins < 2) {
|
|
translate([0, 0, -length / 2]) {
|
|
rotate([90, 0, 0])
|
|
round_groove(len = BASIC_BLOCK_SIZE, endcube = 3);
|
|
}
|
|
// translate([0, BASIC_BLOCK_HALF - GROOVE_RADIUS, -(length - 4.5) / 2])
|
|
// cube(GROOVE_RADIUS * 2 + mfc, center=true);
|
|
// translate([0, -(BASIC_BLOCK_HALF - GROOVE_RADIUS), -(length - 4.5) / 2])
|
|
// cube(GROOVE_RADIUS * 2 + mfc, center=true);
|
|
}
|
|
if (pins == 0) {
|
|
translate([0, 0, length / 2]){
|
|
rotate([270, 0, 0])
|
|
round_groove(len = BASIC_BLOCK_SIZE, endcube = 3);
|
|
}
|
|
// translate([0, BASIC_BLOCK_HALF - GROOVE_RADIUS, (length - 4.5) / 2])
|
|
// cube(GROOVE_RADIUS * 2 + mfc, center=true);
|
|
// translate([0, -BASIC_BLOCK_HALF - GROOVE_RADIUS, (length - 4.5) / 2])
|
|
// cube(GROOVE_RADIUS * 2 + mfc, center=true);
|
|
}
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
// add the pins at the top and bottom of the block
|
|
// --------------------------------------------------------------------
|
|
module top_pins(length = 30, pins = 1) {
|
|
if (pins > 0) {
|
|
translate([0, 0, length / 2 - 0.01])
|
|
pin(diameter = PIN_DIAMETER, base_width = PIN_BASE_WIDTH, base_length = PIN_BASE_LENGTH);
|
|
if (pins == 2) {
|
|
translate([0, 0, -length / 2 + 0.01])
|
|
rotate([180, 0, 0])
|
|
// pin(diameter = PIN_DIAMETER, base_width = PIN_BASE_WIDTH, base_length = PIN_BASE_LENGTH);
|
|
pin(diameter = PIN_DIAMETER, base_width = PIN_BASE_WIDTH, base_length = PIN_BASE_LENGTH);
|
|
}
|
|
}
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
// Angle blocks
|
|
// --------------------------------------------------------------------
|
|
|
|
// --------------------------------------------------------------------
|
|
// An angle block to build the standard fischertechnik angle blocks
|
|
// with 7.5, 15 and 30 degrees. The blocks top and bottom use
|
|
// the fischertechnik 15 x 15 grid. It always has a round or flat
|
|
// groove at the bottom and may or may not have a pin at the top.
|
|
// Caveats:
|
|
// - Angles smaller than 6 degrees are unusable because the bottom
|
|
// groove intersects with the top surface.
|
|
// - Angles greater than 40 degrees look somehow weird because the
|
|
// trapezoid sides are quite large. The module is mainly ment for
|
|
// angles between the standard fischertechnik angles (from 7.5 to
|
|
// 30 degrees) which can not be constructed otherwise.
|
|
// - Angles greater than 72 degrees result in realy ugly blocks. Don't
|
|
// use them...
|
|
// --------------------------------------------------------------------
|
|
module angle_block(angle, with_pin=true) {
|
|
// calculate the radius based on the requested angle
|
|
radius = (angle^2 / 45) - (1.5 * angle) + 40;
|
|
// Center the block on the x and y axis
|
|
translate([radius, 0, 0])
|
|
rotate([270, 0, 0])
|
|
difference() {
|
|
union() {
|
|
// build the basic block
|
|
rotate_extrude(angle = angle, $fn = 5)
|
|
translate ([-radius, 0, 0])
|
|
square(BASIC_BLOCK_SIZE, center = true);
|
|
// and attach the pin if required
|
|
if(with_pin)
|
|
rotate([90, 0, angle])
|
|
translate([-radius, 0, 0])
|
|
pin();
|
|
}
|
|
// now remove the groove
|
|
translate([-radius, 0, 0])
|
|
rotate([0, 0, 180])
|
|
if (angle >= 15)
|
|
round_groove(BASIC_BLOCK_SIZE);
|
|
else
|
|
flat_groove(BASIC_BLOCK_SIZE);
|
|
}
|
|
}
|
|
|
|
// --------------------------------------------------------------------
|
|
// The symmetrical angle block is somehow special. fischertechnik only
|
|
// has the 60 degree blocks which are symetric by definition.
|
|
// This block has two variants: one with a groove and two pins and one
|
|
// with three grooves with a length of 7.5 + 2 mm to get a stable block.
|
|
// This module builds blocks with a given angle and two equal sides of
|
|
// 15 x 15mm (the fischertechnik grid).
|
|
// The length of the base varies, depending on the angle but does NOT
|
|
// fit in the fischertechnik grid (except the 60 degree part, of course).
|
|
// This module has a lot of parameters:
|
|
// angle: The angle between the two 15 x 15 sides
|
|
// pins: An integer describing the pins to use on the 15 x 15 sides:
|
|
// 0 - No pins at all
|
|
// 1 - One pin on the left
|
|
// 2 - One pin on the right
|
|
// 3 - Two pins, one on each side
|
|
// grooves: An integer describing the grooves to use on the 15 x 15
|
|
// sides:
|
|
// 0 - No grooves at all
|
|
// 1 - One groove on the left
|
|
// 2 - One groove on the right
|
|
// 3 - Two groove, one on each side
|
|
// bottom_groove: An integer describing the groove at the bottom.
|
|
// 0 - No groove at all
|
|
// 1 - A flat groove
|
|
// 2 - A round groove. Only used if no grooves are used on
|
|
// the 15 x 15 sides.
|
|
// short_grooves: Use short grooves instead of a groove through the
|
|
// complete block. Gives the block more stability. This
|
|
// parameter is applied to all grooves of the block.
|
|
// Caveats:
|
|
// - Three grooves make no sense if the angle is less than 60 degrees
|
|
// because in that case the grooves would overlap.
|
|
// - A groove in the bottom makes no sense if the angle is less than
|
|
// 30 degrees because it would produce walls which are too thin.
|
|
//
|
|
// --------------------------------------------------------------------
|
|
module symmetrical_angle_block(angle = 45, pins = 2, grooves = 1, bottom_groove = 2, short_grooves = true) {
|
|
// some trigonometric calculations for the resulting triangle
|
|
base = 2 * BASIC_BLOCK_SIZE * sin(angle / 2);
|
|
height = BASIC_BLOCK_SIZE * cos(angle / 2);
|
|
offset1 = sqrt(BASIC_BLOCK_HALF^2 - (height/2)^2) - 0.1;
|
|
// Calculate the length and position of the grooves based on
|
|
// whether we have short grooves or not
|
|
flat_groove_len = short_grooves ? BASIC_BLOCK_SIZE / 2 + 2 : BASIC_BLOCK_SIZE;
|
|
flat_groove_offset = short_grooves ? -2.75 : 0;
|
|
// If we have two pins, they always win ...
|
|
which_grooves = pins == 3 ? 0 : grooves;
|
|
|
|
// center the block
|
|
translate([0,-height/2,0])
|
|
difference() {
|
|
// Get the basic triangle
|
|
linear_extrude(height = BASIC_BLOCK_SIZE, center = true)
|
|
polygon(points = [[-base/2, 0 ],
|
|
[ base/2, 0 ],
|
|
[ 0, height]]);
|
|
// Now substract all the used grooves:
|
|
// Use a bottom groove at all?
|
|
if (bottom_groove > 0) {
|
|
// Then decide whether to use a flat or round groove
|
|
if (which_grooves == 0 && bottom_groove == 2)
|
|
round_groove(GROOVE_LENGTH);
|
|
else
|
|
translate([0, 0, flat_groove_offset])
|
|
flat_groove(flat_groove_len);
|
|
}
|
|
// Cut out the grooves, but only if no pin is on that side
|
|
// Remember: the pins always win ...
|
|
if (which_grooves > 0) {
|
|
if (is_set(which_grooves, 1) && !is_set(pins, 1)) {
|
|
translate([-offset1, height / 2, flat_groove_offset])
|
|
rotate([0, 0, -90 - angle / 2])
|
|
flat_groove(flat_groove_len);
|
|
}
|
|
if (is_set(which_grooves, 2) && !is_set(pins, 2)) {
|
|
translate([offset1, height / 2, flat_groove_offset])
|
|
rotate([0, 0, 90 + angle / 2])
|
|
flat_groove(flat_groove_len);
|
|
}
|
|
}
|
|
}
|
|
// If we have pins, just add them as required
|
|
if (pins > 0) {
|
|
if (is_set(pins, 1)) {
|
|
translate([-offset1, 0, 0])
|
|
rotate([-angle / 2, 270, 0])
|
|
pin();
|
|
}
|
|
if (is_set(pins, 2)) {
|
|
translate([offset1, 0, 0])
|
|
rotate([-angle / 2, 90, 0])
|
|
pin();
|
|
}
|
|
}
|
|
}
|
|
// --------------------------------------------------------------------
|
|
// small helper function to test whether bit 0 (decimal 1) or
|
|
// bit 1 (decimal 2) is set.
|
|
// Openscad has no bitwise operators :-(
|
|
// --------------------------------------------------------------------
|
|
function is_set(var, which) = (var == which || var == 3);
|
|
|
|
|
|
// ********************
|
|
// ** Build section: **
|
|
// ********************
|
|
module main() {
|
|
|
|
if (Block_type == 0) {
|
|
// cube_with_cylinder(dir="right");
|
|
// pin();
|
|
// round_groove();
|
|
eyelet();
|
|
}
|
|
else if (Block_type == 1) {
|
|
basic_block(length=Block_length, pins=Pins, flatblock= Flat_block, bore=Has_bore, squarehole=Is_square);
|
|
}
|
|
else if (Block_type == 2) {
|
|
angle_block(Angle, with_pin=With_pin);
|
|
// translate ([20, 0, 0]) angle_block(15, with_pin=With_pin);
|
|
// translate ([40, 0, 0]) angle_block(30, with_pin=With_pin);
|
|
}
|
|
else if (Block_type == 3) {
|
|
symmetrical_angle_block(Angle, pins = Which_pins, grooves = Which_grooves, bottom_groove = Which_bottom_groove, short_grooves=Has_short_grooves);
|
|
// translate ([20, 0, 0]) symmetrical_angle_block(45, pins = Which_pins, grooves = Which_grooves, bottom_groove = Which_bottom_groove, short_grooves=Has_short_grooves);
|
|
// translate ([40, 0, 0]) symmetrical_angle_block(70, pins = Which_pins, grooves = Which_grooves, bottom_groove = Which_bottom_groove, short_grooves=Has_short_grooves);
|
|
}
|
|
}
|
|
|
|
main();
|
|
|
|
|
|
|