kcl-samples → saturn-v
saturn-v

KCL
// Saturn V Rocket
// Modular construction of the iconic multi-stage rocket using parametric and revolve-based shapes
@settings(defaultLengthUnit = m)
r1 = 4.5 // baseRadiusStage1
r2 = 3.2 // baseRadiusUpperStage
// ----------------------------
// --- Engine Nozzles (x4) ---
// ----------------------------
// Created with revolve profiles to model conic nozzles; cloned and rotated to form quad layout
nozzleSketch = startSketchOn(YZ)
nozzleProfile = startProfile(nozzleSketch, at = [-0.1, 0])
|> yLine(length = 9)
|> line(end = [-2, -9])
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
nozzle1 = revolve(nozzleProfile, angle = 360, axis = Y)
|> translate(x = -r1, y = 0, z = 0)
|> appearance(%, color = "#292929")
nozzle2 = clone(nozzle1)
|> rotate(roll = 0, pitch = 0, yaw = 90)
nozzle3 = clone(nozzle1)
|> rotate(roll = 0, pitch = 0, yaw = 180)
nozzle4 = clone(nozzle1)
|> rotate(roll = 0, pitch = 0, yaw = 270)
// ------------------------------------
// --- Nozzle Hoods (Alternating) ---
// ------------------------------------
// Modeled identically to nozzles but translated upward and given alternating colors
hoodSketch = startSketchOn(YZ)
hoodProfile = startProfile(hoodSketch, at = [-0.1, 0])
|> yLine(length = 9)
|> line(end = [-2, -9])
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
hood1 = revolve(hoodProfile, angle = 360, axis = Y)
|> translate(x = -r1, y = 0, z = 4)
|> appearance(%, color = "#ffffff")
hood2 = clone(hood1)
|> rotate(roll = 0, pitch = 0, yaw = 90)
|> appearance(%, color = "#000000")
hood3 = clone(hood1)
|> rotate(roll = 0, pitch = 0, yaw = 180)
|> appearance(%, color = "#ffffff")
hood4 = clone(hood1)
|> rotate(roll = 0, pitch = 0, yaw = 270)
|> appearance(%, color = "#000000")
// ----------------------------
// --- Stabilizer Fins (x4) ---
// ----------------------------
// Small extrusions in X-Y profile, rotated to form cross pattern
finSketch = startSketchOn(YZ)
finProfile = startProfile(finSketch, at = [-4.23, 6.02])
|> xLine(length = -3.4)
|> yLine(length = 2.2)
|> line(end = [3.4, 3])
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
fin1 = extrude(finProfile, length = 0.1)
|> appearance(%, color = "#ffffff")
fin2 = clone(fin1)
|> rotate(roll = 0, pitch = 0, yaw = 90)
fin3 = clone(fin1)
|> rotate(roll = 0, pitch = 0, yaw = 180)
fin4 = clone(fin1)
|> rotate(roll = 0, pitch = 0, yaw = 270)
// -------------------------------
// --- Stage 1: Bottom Section ---
// -------------------------------
// Uses split white/black geometry to emulate paint scheme with mirrored arcs
bottomBasePlane = offsetPlane(XY, offset = 6)
blackPanelSketch = startSketchOn(bottomBasePlane)
blackPanelProfile = startProfile(blackPanelSketch, at = [0, -r1])
|> yLine(length = r1 * 2)
|> arc(interiorAbsolute = [r1, 0], endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
blackPanel = extrude(blackPanelProfile, length = 14)
|> appearance(%, color = "#000000")
whitePanelProfile = startProfile(blackPanelSketch, at = [0, -r1])
|> yLine(length = r1 * 2)
|> arc(interiorAbsolute = [-r1, 0], endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
whitePanel = extrude(whitePanelProfile, length = 14)
|> appearance(%, color = "#ffffff")
// ------------------------------
// --- Stage 1: Upper Section ---
// ------------------------------
// Alternating black and white zones using circular cross-sections
cylinderBasePlane = offsetPlane(XY, offset = 20)
cylinderSketch = startSketchOn(cylinderBasePlane)
stage1CylinderProfile = circle(cylinderSketch, center = [0, 0], radius = r1)
stage1Cylinder = extrude(stage1CylinderProfile, length = 18)
|> appearance(%, color = "#ffffff")
midStripePlane = offsetPlane(XY, offset = 38)
midStripeSketch = startSketchOn(midStripePlane)
midStripeProfileBlack = startProfile(midStripeSketch, at = [-r1, 0])
|> xLine(length = r1 * 2)
|> arc(interiorAbsolute = [0, r1], endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
midStripeBlack = extrude(midStripeProfileBlack, length = 9)
|> appearance(%, color = "#000000")
// White
midStripeProfileWhite = startProfile(midStripeSketch, at = [-r1, 0])
|> xLine(length = r1 * 2)
|> arc(interiorAbsolute = [0, -r1], endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
midStripeWhite = extrude(midStripeProfileWhite, length = 9)
|> appearance(%, color = "#ffffff")
// Ring
ringPlane = offsetPlane(XY, offset = 47)
ringSketch = startSketchOn(ringPlane)
ringProfile = circle(ringSketch, center = [0, 0], radius = r1)
ringBand = extrude(ringProfile, length = 2)
|> appearance(%, color = "#000000")
// Upper Cyl
upperCylPlane = offsetPlane(XY, offset = 49)
upperCylSketch = startSketchOn(upperCylPlane)
upperCylProfile = circle(upperCylSketch, center = [0, 0], radius = r1)
upperStage1 = extrude(upperCylProfile, length = 15)
|> appearance(%, color = "#ffffff")
// --------------------------------
// --- Stage Transition Cones ---
// --------------------------------
// This conic taper transitions between stage diameters
// lower cones
transitionLowerConeSketch = startSketchOn(YZ)
transitionLowerConeWhiteProfile = startProfile(transitionLowerConeSketch, at = [0, 64])
|> xLine(length = -r1)
|> line(end = [(r1 - r2) / 2, 2.5])
|> xLine(endAbsolute = 0)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
transitionLowerConeWhite = revolve(transitionLowerConeWhiteProfile, angle = 180, axis = Y)
|> appearance(%, color = "#ffffff")
transitionLowerConeBlackProfile = startProfile(transitionLowerConeSketch, at = [0, 64])
|> xLine(length = -r1)
|> line(end = [(r1 - r2) / 2, 2.5])
|> xLine(endAbsolute = 0)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
transitionLowerConeBlack = revolve(transitionLowerConeBlackProfile, angle = -180, axis = Y)
|> appearance(%, color = "#000000")
// upper cones
transitionUpperConeSketch = startSketchOn(YZ)
transitionUpperConeBlackProfile = startProfile(transitionUpperConeSketch, at = [0, 66.5])
|> xLine(length = (r1 - r2) / 2 - r1)
|> line(end = [(r1 - r2) / 2, 2.5])
|> xLine(endAbsolute = 0)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
transitionUpperConeBlack = revolve(transitionUpperConeBlackProfile, angle = 180, axis = Y)
|> appearance(%, color = "#000000")
transitionUpperConeWhiteProfile = startProfile(transitionUpperConeSketch, at = [0, 66.5])
|> xLine(length = (r1 - r2) / 2 - r1)
|> line(end = [(r1 - r2) / 2, 2.5])
|> xLine(endAbsolute = 0)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
transitionUpperConeWhite = revolve(transitionUpperConeWhiteProfile, angle = -180, axis = Y)
|> appearance(%, color = "#ffffff")
// ----------------------------
// --- Stage 2: Upper Body ---
// ----------------------------
// Simple white and black stack of extruded cylinders
// white
stage2Plane = offsetPlane(XY, offset = 69)
stage2Sketch = startSketchOn(stage2Plane)
stage2Profile = circle(stage2Sketch, center = [0, 0], radius = r2)
stage2White = extrude(stage2Profile, length = 9)
|> appearance(%, color = "#ffffff")
// black
stage2StripePlane = offsetPlane(XY, offset = 78)
stage2StripeSketch = startSketchOn(stage2StripePlane)
stage2StripeProfile = circle(stage2StripeSketch, center = [0, 0], radius = r2)
stage2Black = extrude(stage2StripeProfile, length = 2)
|> appearance(%, color = "#000000")
// ----------------------------
// --- Launch Escape System ---
// ----------------------------
// Final tapered nose modeled using a revolve profile for a sleek profile
lesSketch = startSketchOn(XZ)
lesProfile = startProfile(lesSketch, at = [0, 80])
|> xLine(length = -r2)
|> line(end = [1.75, 7.2])
|> yLine(length = 4)
|> line(end = [1, 1.2])
|> yLine(length = 7)
|> line(endAbsolute = [0, 100])
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
launchEscapeSystem = revolve(lesProfile, angle = 360, axis = Y)
|> appearance(%, color = '#FFFFFF')