$fn = 64; // --- Parameters --- medallion_radius = 45; base_thickness = 2; relief_height = 4.5; dragon_amp = 16; dragon_len = 56; dragon_start_y = -28; // --- Main Assembly --- union() { // Base plate and raised rim difference() { cylinder(r=medallion_radius, h=relief_height); translate([0, 0, base_thickness]) cylinder(r=medallion_radius - 2.5, h=relief_height); } // Hanging loop translate([0, medallion_radius + 2, 0]) difference() { cylinder(r=6, h=relief_height); translate([0, 0, -1]) cylinder(r=3, h=relief_height + 2); } // Lunar New Year Motifs dragon(); flaming_pearl(); clouds(); } // --- Modules --- module dragon() { // Dragon Body (Sine wave sweep) for(i=[0:10:350]) { r1 = 1.5 + (i/360) * 3.5; r2 = 1.5 + ((i+10)/360) * 3.5; x1 = dragon_amp * sin(i * 1.5); y1 = dragon_start_y + (i/360) * dragon_len; x2 = dragon_amp * sin((i+10) * 1.5); y2 = dragon_start_y + ((i+10)/360) * dragon_len; // Body segment hull() { translate([x1, y1, 0]) cylinder(r=r1, h=relief_height); translate([x2, y2, 0]) cylinder(r=r2, h=relief_height); } // Dorsal spikes if (i >= 20 && i <= 340) { translate([x1, y1, relief_height - 0.1]) cylinder(r1=r1*0.7, r2=0, h=2.5); } } // Tail tuft translate([0, dragon_start_y, 0]) { hull() { cylinder(r=1.5, h=relief_height); translate([-5, -6, 0]) cylinder(r=0.5, h=relief_height); } hull() { cylinder(r=1.5, h=relief_height); translate([5, -5, 0]) cylinder(r=0.5, h=relief_height); } } // Dragon Head hx = dragon_amp * sin(360 * 1.5); hy = dragon_start_y + dragon_len; translate([hx, hy, 0]) { // Main head cylinder(r=5.5, h=relief_height); // Snout hull() { cylinder(r=5.5, h=relief_height); rotate([0, 0, 15]) translate([-9, 4, 0]) cylinder(r=3.5, h=relief_height); } // Horns hull() { translate([2, -2, 0]) cylinder(r=1.5, h=relief_height); translate([8, -10, 0]) cylinder(r=0.5, h=relief_height); } hull() { translate([-2, -4, 0]) cylinder(r=1.5, h=relief_height); translate([-4, -13, 0]) cylinder(r=0.5, h=relief_height); } // Whiskers hull() { rotate([0, 0, 15]) translate([-9, 4, 0]) cylinder(r=1.5, h=relief_height); translate([-16, 0, 0]) cylinder(r=0.5, h=relief_height); } hull() { rotate([0, 0, 15]) translate([-9, 4, 0]) cylinder(r=1.5, h=relief_height); translate([-12, 13, 0]) cylinder(r=0.5, h=relief_height); } } // Legs leg(dragon_amp * sin(60 * 1.5), dragon_start_y + (60/360)*dragon_len, -30); leg(dragon_amp * sin(160 * 1.5), dragon_start_y + (160/360)*dragon_len, 180); leg(dragon_amp * sin(280 * 1.5), dragon_start_y + (280/360)*dragon_len, 30); leg(dragon_amp * sin(220 * 1.5), dragon_start_y + (220/360)*dragon_len, 135); } module leg(x, y, angle) { translate([x, y, 0]) rotate([0, 0, angle]) { hull() { cylinder(r=2, h=relief_height); translate([7, 0, 0]) cylinder(r=1.5, h=relief_height); } translate([7, 0, 0]) rotate([0, 0, 45]) { hull() { cylinder(r=1.5, h=relief_height); translate([4, 0, 0]) cylinder(r=1.2, h=relief_height); } // Claws translate([4, 0, 0]) { rotate([0, 0, 35]) translate([2.5, 0, 0]) cylinder(r1=0.8, r2=0.2, h=relief_height); rotate([0, 0, -35]) translate([2.5, 0, 0]) cylinder(r1=0.8, r2=0.2, h=relief_height); translate([2.5, 0, 0]) cylinder(r1=0.8, r2=0.2, h=relief_height); } } } } module flaming_pearl() { translate([-16, 30, 0]) { cylinder(r=3.5, h=relief_height); for(a=[0:90:270]) { rotate([0, 0, a + 45]) translate([0, 3.5, 0]) cylinder(r1=1.5, r2=0, h=relief_height); } } } module clouds() { cloud(24, -18, 0.9); cloud(-26, -8, 1); cloud(25, 14, 0.85); cloud(-20, -25, 0.7); cloud(-24, 15, 0.8); } module cloud(cx, cy, scale_factor=1) { translate([cx, cy, 0]) scale([scale_factor, scale_factor, 1]) { cylinder(r=4, h=relief_height); translate([5, 0, 0]) cylinder(r=3, h=relief_height); translate([-4, 2, 0]) cylinder(r=2.5, h=relief_height); translate([1, 4, 0]) cylinder(r=3.5, h=relief_height); // Stylized swirl tail hull() { translate([5, 0, 0]) cylinder(r=3, h=relief_height); translate([11, -3, 0]) cylinder(r=0.5, h=relief_height); } } }