2020 Corner Bracket
A 90 deg corner bracket that joins two 2020 aluminium extrusions with one M5 screw and T-nut per leg. Tongues on both outer faces key into the 6 mm slots to square the joint, and a diagonal gusset closes the L into a stiff triangle, with an access hole in the gusset for inserting and tightening each screw. The default bracket measures 41.5 x 41.5 x 20 mm. Print it lying on its side as modeled: all walls are vertical and the tongue flanks are 45 deg, so no supports are needed. Adjustable parameters: slot width, tongue height and clearance, leg length and thickness, gusset thickness, bracket width, screw position, clearance hole and access hole diameter.
# 2020 Corner Bracket - 90 deg joint for 20 x 20 extrusion
#
# Use: place the two outer faces against two 2020 profiles that meet at a right
# angle. The tongues on the outer faces key into the 6 mm slots and square the
# joint; one M5 screw per leg goes through the leg into a T-nut in the slot.
# The diagonal gusset closes the L into a stiff triangle. Each screw is put in
# through the access hole in the gusset and tightened with a hex key through it.
#
# Print orientation: lying on its side (the L profile on the bed, Z = bracket
# width). Every wall is vertical, the tongue flanks are 45 deg, no supports.
# Leg A runs along +Y (outer face X = 0), leg B runs along +X (outer face Y = 0).
#
# Assumed 2020 slot dimensions (B-type, 6 mm slot) - adjust to your extrusion.
@param 5.6..6.6..0.1 group:"Extrusion" desc:"Slot opening width (mm, assumed 6.2)"
slot_w = 6.2
@param 0..0.4..0.05 group:"Extrusion" desc:"Tongue clearance per side in the slot (mm)"
tongue_clear = 0.15
@param 0.5..2.0..0.1 group:"Extrusion" desc:"Tongue height into the slot (mm, keep below the 1.8 lip)"
tongue_h = 1.5
@param 36..60 group:"Bracket" desc:"Leg length from the outer corner (mm)"
leg = 40
@param 3..6..0.5 group:"Bracket" desc:"Leg thickness (mm)"
leg_t = 4
@param 3..6..0.5 group:"Bracket" desc:"Gusset thickness (mm)"
gusset_t = 4
@param 12..20 group:"Bracket" desc:"Bracket width = profile face width (mm)"
width = 20
@param 5.3..6.0..0.1 group:"Screws" desc:"M5 clearance hole diameter (mm)"
hole_d = 5.6
@param 10..25 group:"Screws" desc:"Screw position from the outer corner (mm)"
screw_pos = 17
@param 9..12..0.5 group:"Screws" desc:"Access hole in the gusset for the screw head and key (mm)"
access_d = 10
inner_r = 2 # fillet of the triangular opening
# --- Profile (XY): L with a diagonal gusset, closed into a triangle ---
s2 = sqrt(2)
outer = polyline [(0, 0), (leg, 0), (leg, leg_t), (leg_t, leg), (0, leg)]
hyp_in = leg + leg_t - gusset_t * s2 # inner gusset line: x + y = hyp_in
opening = polyline [(leg_t, leg_t), (hyp_in - leg_t, leg_t), (leg_t, hyp_in - leg_t)]
| offset (-inner_r) | offset inner_r
frame = (outer - opening) | extrude width
# --- Tongues: 45 deg trapezoid ridges on the outer faces, centered on the width ---
w0 = slot_w - tongue_clear * 2 # width at the root
w1 = w0 - tongue_h * 2 # width at the tip
zc = width / 2
t0 = 0.5 # start a little away from the corner
tongue_a = workplane XZ
| polyline [(0, zc - w0 / 2), (0, zc + w0 / 2), (-tongue_h, zc + w1 / 2), (-tongue_h, zc - w1 / 2)]
| extrude (leg - t0) | translate 0 t0 0
tongue_b = workplane YZ
| polyline [(0, zc - w0 / 2), (0, zc + w0 / 2), (-tongue_h, zc + w1 / 2), (-tongue_h, zc - w1 / 2)]
| extrude (leg - t0) | translate t0 0 0
# --- M5 clearance holes (one per leg) and access holes through the gusset ---
hole_a = cylinder (hole_d / 2) (leg_t * 2 + tongue_h * 4) | rotate 0 90 0 | translate 0 screw_pos zc
hole_b = cylinder (hole_d / 2) (leg_t * 2 + tongue_h * 4) | rotate 90 0 0 | translate screw_pos 0 zc
acc_l = leg + 10
acc_a = cylinder (access_d / 2) acc_l | rotate 0 90 0 | translate (leg_t + 0.5 + acc_l / 2) screw_pos zc
acc_b = cylinder (access_d / 2) acc_l | rotate 90 0 0 | translate screw_pos (leg_t + 0.5 + acc_l / 2) zc
bracket = frame + tongue_a + tongue_b - [hole_a, hole_b, acc_a, acc_b]
# --- Intent ---
assert w1 >= 2 # tongue tip still a usable key
assert screw_pos + access_d / 2 <= hyp_in - leg_t - 1 # screw head fits inside the triangle
assert screw_pos - access_d / 2 >= leg_t # head clears the other leg
assert bracket.solids == 1
assert bracket.bbox.x ~ leg + tongue_h
assert bracket.bbox.y ~ leg + tongue_h
assert bracket.bbox.z ~ width
assert bracket.bbox.min[2] ~ 0 tol:0.01
bracket