kcl-samples → propeller

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], )