"""Straight-tooth gear rack, ISO 53 basic rack, section from KHK's SR steel racks. Length along X, centred on the origin; width along Y; base on the XY plane and teeth up along +Z. As many whole teeth as fit the length, centred, with the tooth roots' level running to both ends. Height H is the pitch-line height H0 plus one module.""" import math from steve import Model module = 1 # Module length = 300 # mm Rack length PRESSURE_ANGLE = 20 # degrees: ISO 53:1998 basic rack DEDENDUM = 1.25 # x module: ISO 53 # module: (face width B, overall height H, height to the pitch line H0). KHK Gears catalogue 2025, Racks, SR steel racks # table, https://khkgears.us/media/yzroimcg/catalog-2025-racks.pdf RACKS = {0.5: (5, 12, 11.5), 0.8: (8, 12.3, 11.5), 1: (10, 12, 11), 1.5: (15, 20, 18.5), 2: (20, 25, 23)} MAX_TEETH = 260 # more teeth than this take longer to build than a build is allowed B, H, H0 = RACKS[module] pitch = math.pi * module count = int(length // pitch) if count < 1: raise ValueError(f"The rack must be at least one pitch ({pitch:.3f} mm) long.") if count > MAX_TEETH: raise ValueError(f"{count} teeth is too long to build: at most {MAX_TEETH} teeth ({MAX_TEETH * pitch:.0f} mm at this module).") tan_a = math.tan(math.radians(PRESSURE_ANGLE)) root_z = H0 - DEDENDUM * module crest_half = pitch / 4 - module * tan_a root_half = pitch / 4 + DEDENDUM * module * tan_a points = [(-length / 2, 0), (length / 2, 0), (length / 2, root_z)] for i in reversed(range(count)): x = (i - (count - 1) / 2) * pitch points += [(x + root_half, root_z), (x + crest_half, H), (x - crest_half, H), (x - root_half, root_z)] points.append((-length / 2, root_z)) model = Model() with model.sketch("rack_sketch", on="XZ", name="Rack section") as sk: sk.polyline("profile", points, closed=True) model.extrude("rack", "rack_sketch", distance=B, both=True, name="Rack") model.material("steel-generic", color="#b4b8bd") result = model.result()