// ============================================================================= // Cyclone Separator Inlet Adapter // ============================================================================= // // Geometry: // * Vertical inlet: 40 mm OD, 35 mm ID // * 90 deg elbow (centerline radius 40 mm) // * Horizontal outlet: 70 mm long // - First 10 mm: ID tapers 35 -> 30 mm (converging) // - Last 60 mm: ID widens 30 -> 32.1 mm (opening) // // Wall thickness: 2.5 mm constant (OD = ID + 5 mm everywhere) // // Construction: // Built as the difference between two swept hulls (outer envelope minus // inner envelope) along the 3D centerline. This guarantees a smooth bore // and a smooth outside that follows the internal contour. // // Print orientation suggestion: // Place the inlet opening face-down on the print bed so the entire // internal bore can be printed with minimal support material. // ============================================================================= $fn = 80; // ---------- User-tunable parameters (mm) ---------- inlet_length = 15; // length of the straight vertical inlet section od_inlet = 40; // outer diameter at the inlet id_inlet = 35; // inner diameter at the inlet and through the elbow elbow_radius = 40; // centerline radius of the 90 deg elbow outlet_length = 70; // total length of the horizontal outlet narrow_length = 10; // length of the converging region (35 -> 30 mm ID) id_narrow = 30; // inner diameter at the narrow point id_outlet = 32.1; // inner diameter at the outlet opening n_elbow = 20; // number of cross-sections along the elbow arc // Internal diameter at a distance s past the elbow exit (0 <= s <= outlet_length). function id_at(s) = s <= narrow_length ? id_inlet - (id_inlet - id_narrow) * s / narrow_length : id_narrow + (id_outlet - id_narrow) * (s - narrow_length) / (outlet_length - narrow_length); module adapter() { // Coordinates where the elbow ends and the straight outlet begins. ex = elbow_radius; ez = inlet_length + elbow_radius; difference() { // ============================================================= // Outer envelope: hull of outer cross-section discs // ============================================================= hull() { // Vertical inlet straight section translate([0, 0, 0]) cylinder(d = od_inlet, h = 1); translate([0, 0, inlet_length]) cylinder(d = od_inlet, h = 1); // 90 deg elbow: arc in the XZ plane. // start: (0, 0, inlet_length) tangent +Z // end: (R, 0, inlet_length + R) tangent +X for (i = [0 : n_elbow]) { theta = 180 - i * 90 / n_elbow; x_pos = elbow_radius + elbow_radius * cos(theta); z_pos = inlet_length + elbow_radius * sin(theta); // Tangent direction at angle theta: (sin(theta), 0, -cos(theta)). // Rotation around Y by (180 - theta) maps +Z to that tangent. translate([x_pos, 0, z_pos]) rotate([0, 180 - theta, 0]) cylinder(d = od_inlet, h = 1); } // Horizontal outlet cross-sections (s = distance from elbow exit). // OD(s) = ID(s) + 5 mm (constant 2.5 mm wall). for (s = [0, 5, 10, 40, 70]) { translate([ex + s, 0, ez]) cylinder(d = id_at(s) + 5, h = 1); } } // ============================================================= // Inner envelope: hull of inner cross-section discs. // Subtracted from the outer envelope to create the bore. // ============================================================= hull() { translate([0, 0, 0]) cylinder(d = id_inlet, h = 1); translate([0, 0, inlet_length]) cylinder(d = id_inlet, h = 1); for (i = [0 : n_elbow]) { theta = 180 - i * 90 / n_elbow; x_pos = elbow_radius + elbow_radius * cos(theta); z_pos = inlet_length + elbow_radius * sin(theta); translate([x_pos, 0, z_pos]) rotate([0, 180 - theta, 0]) cylinder(d = id_inlet, h = 1); } for (s = [0, 5, 10, 40, 70]) { translate([ex + s, 0, ez]) cylinder(d = id_at(s), h = 1); } } } } adapter();