Skip to content

Instantly share code, notes, and snippets.

@SeanCline
Created March 19, 2025 01:11
Show Gist options
  • Save SeanCline/eabb2d09f25f438894cb29aed430a2f1 to your computer and use it in GitHub Desktop.
Save SeanCline/eabb2d09f25f438894cb29aed430a2f1 to your computer and use it in GitHub Desktop.
A custom replacement nozzle for the "Violent Fan" air duster. https://www.aliexpress.us/item/3256807465794690.html
id_thin = 9;
wall_thickness = 1.6;
octagon_outer_diam = 35.5;
octagon_outer_th = 6.5;
octagon_hub_diam = 17;
octagon_hub_th = octagon_outer_th/2;
octagon_hub_magnet_diam = 15;
octagon_hub_magnet_depth = octagon_hub_th-.6;
octagon_peg_diam = 3;
octagon_peg_length = octagon_outer_th/2;
octagon_peg_fudge = .5;
octagon_peg_fit = .25;
spoke_th = 2;
// Original slope parameters.
orig_id_thin = 17.2;
orig_id_thick = 29.2;
orig_length = 34;
orig_slope = (orig_id_thick-orig_id_thin)/orig_length;
// Calculate the length to match the original slope of the cone.
length = (orig_id_thick-id_thin)/orig_slope;
$fn = $preview ? 50 : 150;
eps = .01;
module regular_polygon(n, midpoint_radius) {
r = midpoint_radius/cos(180/n);
circle(r, $fn=n);
}
module base() {
// Outer.
linear_extrude(octagon_outer_th)
difference() {
regular_polygon(8, octagon_outer_diam/2);
circle(d=orig_id_thick);
// Peg inserts.
for (i=[0:(360/8):360]) {
rotate(i)
translate([0, orig_id_thick/2+octagon_peg_diam/2+octagon_peg_fudge])
circle(d=octagon_peg_diam);
}
}
// Inner.
difference() {
union() {
// Hub.
linear_extrude(octagon_hub_th)
circle(d=octagon_hub_diam);
// Spokes.
linear_extrude(octagon_hub_th)
for (i=[0:(360/8):360]) {
rotate(i)
square([spoke_th, orig_id_thick
+eps], center=true);
}
}
// Hub magnet inlay.
translate([0,0, octagon_hub_th-octagon_hub_magnet_depth+eps])
linear_extrude(octagon_hub_magnet_depth)
circle(d=octagon_hub_magnet_diam);
}
}
base();
module to_3d() {
let (eps = .0001) {
linear_extrude(eps)
projection()
linear_extrude(eps)
children();
}
}
module loft_extrude(h=5, slices=5) {
hull() {
to_3d() children(1);
let (j=1) translate([0,0,j/slices*h]) minkowski() {
scale(j/slices) to_3d() children(0);
scale((slices-j)/slices) to_3d() children(1);
}
}
for(i=[1:slices-2]) {
hull() {
let (j=i) translate([0,0,j/slices*h]) minkowski() {
scale(j/slices) to_3d() children(0);
scale((slices-j)/slices) to_3d() children(1);
}
let (j=i+1) translate([0,0,j/slices*h]) minkowski() {
scale(j/slices) to_3d() children(0);
scale((slices-j)/slices) to_3d() children(1);
}
}
}
hull() {
let (j=slices-1) translate([0,0,j/slices*h]) minkowski() {
scale(j/slices) to_3d() children(0);
scale((slices-j)/slices) to_3d() children(1);
}
translate([0,0,h]) to_3d() children(0);
}
}
module nozzle() {
difference() {
loft_extrude(h=length) {
regular_polygon(8, octagon_outer_diam/2);
circle(d=id_thin+wall_thickness*2);
}
translate([0,0,-eps])
cylinder(h=length+2*eps, d1=id_thin, d2=orig_id_thick);
}
// Pegs.
translate([0,0,length-eps])
linear_extrude(octagon_peg_length)
for (i=[0:(360/8):360]) {
rotate(i)
translate([0, orig_id_thick/2+octagon_peg_diam/2+octagon_peg_fudge])
circle(d=octagon_peg_diam-octagon_peg_fit);
}
}
translate([octagon_outer_diam*1.5,0,0])
nozzle();
@SeanCline
Copy link
Author

violent_fan_nozzle2 scad_-_OpenSCAD_openscad_2025-03-18_21-07-08

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment