Addendum: V-22 Osprey Build

Addendum: V-22 Osprey — Multi-Part Assembly Project

The V-22 Osprey is a tiltrotor military aircraft — nacelles rotate between helicopter (vertical) and airplane (horizontal) mode. Printing one with working tilt mechanisms is a serious engineering project that exercises every skill from this guide.

Why This Project

  • Multi-part assembly — print 8+ components that must fit together with designed tolerances

  • Working mechanism — the nacelle tilt is a real pin joint, not a static display

  • Parametric design — change one dimension and the entire aircraft adapts

  • Math-heavy — airfoil cross-sections, rotational joints, symmetry operations

Parts Breakdown

Part Description OpenSCAD Technique Print Time (est.)

Fuselage (left half)

Main body, cargo bay

hull() of ellipsoids, difference() for interior

~4 hours

Fuselage (right half)

Mirror of left

mirror([1,0,0]) — reflection matrix

~4 hours

Wing

Straight wing, nacelle mounting points

cube() with airfoil polygon() extrusion

~2 hours

Nacelle (×2)

Engine housing, tilt pivot

cylinder() with pin hole via difference()

~1.5 hours each

Rotor assembly (×2)

3-blade prop, hub

for loop with rotate([0, 0, i*120]), airfoil hull()

~45 min each

Tail section

V-tail stabilizers

rotate() angled surfaces, hull() for blending

~1.5 hours

Landing gear (×3)

Nose + 2 main gear

cylinder() struts, sphere() wheels

~30 min each

Tilt pins (×2)

Pin joint for nacelle rotation

cylinder(r=1.4) inside cylinder(r=1.5) hole — 0.1mm clearance

~10 min each

Total estimated print time: ~16 hours across all parts.

The Tilt Mechanism

The heart of the V-22’s design — nacelles that actually rotate:

// V-22 Osprey — Nacelle Tilt Joint
// The critical mechanism: a pin joint with designed clearance
// 0.1mm clearance between pin and hole for free rotation

pin_radius   = 1.4;
hole_radius  = 1.5;   // 0.1mm clearance
nacelle_r    = 12;
nacelle_h    = 30;
wing_thick   = 6;

// Wing mounting bracket with hole
module wing_mount() {
    difference() {
        cube([20, wing_thick, 20], center=true);
        // Pin hole — slightly larger than pin
        rotate([90, 0, 0])
            cylinder(h=wing_thick+2, r=hole_radius, $fn=32, center=true);
    }
}

// Nacelle with pin stub
module nacelle() {
    // Engine housing
    cylinder(h=nacelle_h, r=nacelle_r, $fn=64);
    // Pin stub — protrudes to fit into wing mount
    translate([0, 0, nacelle_h/2])
        rotate([90, 0, 0])
            cylinder(h=wing_thick+4, r=pin_radius, $fn=32, center=true);
}

// Display: wing mount + nacelle at tilt angle
tilt_angle = 45;  // 0 = airplane, 90 = helicopter

wing_mount();
translate([0, 0, 15])
    rotate([tilt_angle, 0, 0])
        nacelle();

The critical dimension is the clearance between pin and hole. 0.1mm too tight and it won’t rotate. 0.1mm too loose and it wobbles. This is tolerance engineering — the difference between a working mechanism and a display piece.

Full V-22 Assembly

// V-22 Osprey — Full Assembly
// Tiltrotor aircraft with working nacelle joints
// Print in parts, assemble with pin joints

// === Parameters ===
fuselage_length = 120;
fuselage_width  = 20;
fuselage_height = 18;
wing_span       = 100;  // each side
wing_chord      = 18;   // front-to-back
wing_thick      = 5;
nacelle_r       = 10;
nacelle_h       = 25;
rotor_length    = 40;
rotor_width     = 4;
pin_r           = 1.4;
hole_r          = 1.5;  // 0.1mm clearance
tilt_angle      = 0;    // 0=airplane, 90=helicopter

// === Modules ===

module limb(length, r_top, r_bottom) {
    hull() {
        sphere(r=r_top, $fn=32);
        translate([0, 0, length])
            sphere(r=r_bottom, $fn=32);
    }
}

module fuselage() {
    // Main body — hull of two ellipsoids for organic taper
    hull() {
        scale([1, fuselage_width/fuselage_length, fuselage_height/fuselage_length])
            sphere(r=fuselage_length/2, $fn=64);
        translate([fuselage_length*0.4, 0, 0])
            scale([0.3, 0.6, 0.7])
                sphere(r=fuselage_width/2, $fn=48);
    }
    // Tail boom
    translate([fuselage_length*0.4, 0, 0])
        limb(fuselage_length*0.3, fuselage_width/3, fuselage_width/6);
    // V-tail stabilizers
    translate([fuselage_length*0.65, 0, fuselage_width/6]) {
        rotate([0, 30, 0])
            cube([15, 1.5, 8]);
        rotate([0, 30, 0])
            mirror([0, 0, 1])
                cube([15, 1.5, 8]);
    }
}

module wing() {
    translate([-wing_chord/2, -wing_span, 0])
        cube([wing_chord, wing_span*2, wing_thick]);
}

module nacelle(tilt=0) {
    rotate([0, -tilt, 0]) {
        cylinder(h=nacelle_h, r=nacelle_r, $fn=48);
        // Intake cone
        translate([0, 0, nacelle_h])
            cylinder(h=5, r1=nacelle_r, r2=nacelle_r*0.6, $fn=48);
        // Exhaust
        translate([0, 0, -3])
            cylinder(h=3, r1=nacelle_r*0.7, r2=nacelle_r, $fn=48);
    }
}

module rotor(tilt=0) {
    rotate([0, -tilt, 0])
        translate([0, 0, nacelle_h+5])
            for (i = [0:2])
                rotate([0, 0, i*120])
                    translate([-rotor_width/2, 0, 0])
                        cube([rotor_width, rotor_length, 0.8]);
}

module landing_gear(height=15) {
    // Strut
    cylinder(h=height, r=1.5, $fn=16);
    // Wheel
    translate([0, 0, -2])
        rotate([90, 0, 0])
            cylinder(h=3, r=3, $fn=24, center=true);
}

// === Assembly ===

// Fuselage
fuselage();

// Wing — mounted on top of fuselage
translate([0, 0, fuselage_height/2])
    wing();

// Left nacelle + rotor
translate([0, -wing_span+10, fuselage_height/2 + wing_thick]) {
    nacelle(tilt_angle);
    rotor(tilt_angle);
}

// Right nacelle + rotor (mirror)
translate([0, wing_span-10, fuselage_height/2 + wing_thick]) {
    nacelle(tilt_angle);
    rotor(tilt_angle);
}

// Landing gear
translate([-fuselage_length*0.3, 0, -fuselage_height/2])
    landing_gear();
translate([fuselage_length*0.15, -8, -fuselage_height/2])
    landing_gear();
translate([fuselage_length*0.15, 8, -fuselage_height/2])
    landing_gear();

Print Strategy

  1. Print all parts with 20% infill, 0.20mm layer height

  2. Fuselage halves print flat (split side down) — no supports needed

  3. Nacelles print vertically for round cross-section accuracy

  4. Rotors print flat — enable "ironing" for smooth top surface

  5. Tilt pins print at 100% infill for strength

  6. Test-fit the pin joint before printing all parts — adjust clearance if needed

Assembly

  1. Glue fuselage halves (CA glue or plastic cement)

  2. Insert tilt pins through wing mounting points

  3. Slide nacelles onto pins — they should rotate freely

  4. Press-fit rotors onto nacelle shafts

  5. Snap landing gear into fuselage slots

Math in This Project

Concept Where It Appears

Reflection symmetry

mirror([1,0,0]) — fuselage halves, nacelles, rotors

Rotational symmetry

for (i=[0:2]) rotate([0,0,i*120]) — 3-blade rotors

Tolerance engineering

Pin diameter vs. hole diameter — clearance fit calculation

Airfoil geometry

polygon() points defining NACA airfoil cross-section

Trigonometry

Nacelle tilt angle: rotate([tilt_angle, 0, 0]) — 0° horizontal, 90° vertical

Parametric scaling

Change fuselage_length and everything downstream adjusts

Affine transforms

Composition of translate, rotate, scale to position every part

What You Learn

This single project teaches: multi-part design, tolerance engineering, assembly planning, print orientation strategy, mechanical joints, symmetry operations, parametric design, and the engineering iteration loop. It’s a capstone project that proves you understand every concept in this guide.