kcl-samples → propeller
propeller

KCL
// Ceiling Propeller // A twisted 3-blade ceiling fan geometry made using boolean cutouts @settings(defaultLengthUnit = mm) // Main Parameters bladeTwistAngle = 5deg // Twist angle applied to the void cut geometry bladeSpanLength = 100 // Blade span (radial length) bladeWidth = 17.5 // Half-width of the blade at its widest point bladeBaseThickness = 10 // Total thickness of the extruded root/base bladeThickness = 2 // Thickness of the profile at void section // Root geometry bladeRootWidth = bladeWidth * 2 bladeSeamLength = bladeRootWidth / 2 / cos(30deg) // Angled base segment (30°) bladeNeckLength = (bladeRootWidth / 2 - (bladeWidth / 2)) / sin(30deg) // Neck connects to span // Fillet radii rootFillet = bladeNeckLength / tan(30deg) * 0.5 // Rounded base root tipFillet = bladeWidth * 0.49 // Rounded blade tip // Void cutout dimensions voidCutoutLength = bladeSpanLength + 30 // Longitudinal length of the void voidCutoutWidth = bladeWidth * 3 // Width of the void cut voidCutoutHeight = bladeWidth * 2 // Height (used in tangential arc) // Construct blade profile bladePlane = offsetPlane(XY, offset = -bladeBaseThickness / 2) bladeSketch = startSketchOn(XY) bladeProfile = startProfile(bladePlane, at = [0, 0]) |> angledLine(angle = 30deg, length = bladeSeamLength) |> angledLine(angle = 120deg, length = bladeNeckLength, tag = $segUpperNeck) |> yLine(length = bladeSpanLength, tag = $segSpanTop) |> xLine(length = -bladeWidth, tag = $seg01) |> yLine(length = -bladeSpanLength, tag = $segSpanBottom) |> angledLine(angle = 240deg, length = bladeNeckLength, tag = $segLowerNeck) |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> close() // Extrude blade solid and apply fillets bladeSolid = extrude(bladeProfile, length = bladeBaseThickness) |> fillet( radius = rootFillet, tags = [ getCommonEdge(faces = [segSpanBottom, segLowerNeck]), getCommonEdge(faces = [segUpperNeck, segSpanTop]) ], ) |> fillet( radius = tipFillet, tags = [ getCommonEdge(faces = [segSpanTop, seg01]), getCommonEdge(faces = [seg01, segSpanBottom]) ], ) // Construct twisted void cutout (one side only) voidPlane = offsetPlane(YZ, offset = -voidCutoutWidth / 2) voidSketch = startSketchOn(voidPlane) voidProfile = startProfile( voidSketch, at = [ bladeSpanLength * 1.5, bladeThickness / 2 ], ) |> xLine(length = -bladeSpanLength * 1.15) // Arc defining central void (based on voidCutoutHeight) |> tangentialArc(end = [-voidCutoutHeight, voidCutoutHeight]) |> xLine(length = bladeSpanLength * 1.5) |> line(endAbsolute = [profileStartX(%), profileStartY(%)]) |> close() voidCutoutOne = extrude(voidProfile, length = voidCutoutWidth) |> rotate(roll = 0, pitch = bladeTwistAngle, yaw = 0) // Mirror second void cut to other side voidCutoutTwo = clone(voidCutoutOne) |> rotate(roll = 0, pitch = 180, yaw = 0) // Subtract voids from blade bladeWithVoidOne = subtract([bladeSolid], tools = [voidCutoutOne]) bladeWithVoids = subtract([bladeWithVoidOne], tools = [voidCutoutTwo]) // Circular pattern: 3 blade instance fan propellerAssembly = patternCircular3d( bladeWithVoids, instances = 3, axis = [0, 0, 1], center = [0, 0, 0], )