// 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 // -------------------------------------------------------------------- // 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();