commit ad3925d108c9af78ec55f4a78dd32953a779f891 Author: Paul Mathieu Date: Thu Aug 15 17:25:56 2024 +0200 Initial commit: planetarium diff --git a/planets.ipynb b/planets.ipynb new file mode 100644 index 0000000..e6b2a17 --- /dev/null +++ b/planets.ipynb @@ -0,0 +1,314 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 34, + "id": "afcfc049", + "metadata": {}, + "outputs": [], + "source": [ + "import re\n", + "\n", + "orbits = \"\"\"\n", + "Mercury: 88 days.\n", + "Venus: 225 days.\n", + "Earth: 365 days.\n", + "Mars: 687 days.\n", + "Jupiter: 4333 days.\n", + "Saturn: 10759 days.\n", + "Uranus: 30687 days.\n", + "Neptune: 60190 days.\n", + "\"\"\".splitlines()" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "c0665887", + "metadata": {}, + "outputs": [], + "source": [ + "ratios = [int((re.findall(r'\\d+', x)[0:1] or [0])[0])/88 for x in orbits][1:]" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "56eb1e3f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[1.0,\n", + " 6.307132459970888,\n", + " 15.660844250363901,\n", + " 44.66812227074236,\n", + " 87.61280931586609]" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "[x / ratios[3] for x in ratios[3:]]" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "8401b303", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[1.0,\n", + " 1.5990053726670783,\n", + " 2.036596983383623,\n", + " 2.794068392473273,\n", + " 7.017024751533684,\n", + " 11.0571860632063,\n", + " 18.67393662543892,\n", + " 26.152959158138735]" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import math\n", + "[math.sqrt(x) for x in ratios]" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "id": "85f986fc", + "metadata": {}, + "outputs": [], + "source": [ + "dist = \"\"\"The distance from the Sun to Mercury is 0.39 AU, to Venus is 0.72 AU, to Earth is 1.00 AU, to Mars is 1.52 AU, to Jupiter is 5.20 AU, to Saturn is 9.54 AU, to Uranus is 19.22 AU, and to Neptune is 30.06 AU.\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "id": "7c321d05", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[5.875871902123325,\n", + " 15.072438995419457,\n", + " 20.0,\n", + " 26.280655022872775,\n", + " 44.729879383810726,\n", + " 53.83240228190293,\n", + " 64.3392710531322,\n", + " 71.04793076487243]" + ] + }, + "execution_count": 56, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "[20 + 1.5 * math.log(float(x))*10 for x in re.findall(r'[0-9]+.\\d+', dist)]" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "id": "36ce6b46", + "metadata": {}, + "outputs": [], + "source": [ + "planets = [\n", + " ('mercury', 1.0, 50),\n", + " ('venus', 1.6, 130),\n", + " ('earth', 2.0, 200),\n", + " ('mars', 2.8, 270),\n", + " ('jupiter', 7.0, 450),\n", + " ('saturn', 11, 540),\n", + " ('uranus', 18, 640),\n", + " ('neptune', 26, 710),\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "id": "6a36fcb8", + "metadata": {}, + "outputs": [], + "source": [ + "def b():\n", + " prevp = 1.0\n", + " for n, p, d in planets:\n", + " yield p / prevp\n", + " prevp = p\n", + " \n", + "ratios = list(b())" + ] + }, + { + "cell_type": "code", + "execution_count": 89, + "id": "5f6e6b6b", + "metadata": {}, + "outputs": [], + "source": [ + "scale = 5\n", + "\n", + "tooth_width = 0.8;\n", + "tooth_crop = 0.5;\n", + "tooth_thickness = 0.6;\n", + "\n", + "def gear_base_radius(n):\n", + " perimeter = tooth_width * (1 + 0.8*(1-tooth_crop)) * n\n", + " return perimeter / math.pi / 2;\n", + "\n", + "def gear_wheel_radius(n):\n", + " return math.sqrt(gear_base_radius(n)**2 + (tooth_width/2)**2);\n", + "\n", + "def gear_radius(n):\n", + " return scale * (gear_wheel_radius(n) + gear_base_radius(n) + tooth_crop)/2;\n", + "\n", + "def dcenter(n1, n2):\n", + " return gear_radius(n1) + gear_radius(n2)\n", + "\n", + "def search():\n", + " for n1 in range(11, 39):\n", + " n2 = 50 - n1\n", + " yield (n1, n2, n2 / n1, dcenter(n1, n2))\n", + " \n", + "rr = list(search())" + ] + }, + { + "cell_type": "code", + "execution_count": 92, + "id": "b64daa46", + "metadata": {}, + "outputs": [], + "source": [ + "def found():\n", + " for r in ratios:\n", + " for n1, n2, tr, _ in rr:\n", + " if tr < r:\n", + " yield (n1, n2, r, tr)\n", + " break" + ] + }, + { + "cell_type": "code", + "execution_count": 93, + "id": "c587ff67", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[(26, 24, 1.0, 0.9230769230769231),\n", + " (20, 30, 1.6, 1.5),\n", + " (23, 27, 1.25, 1.173913043478261),\n", + " (21, 29, 1.4, 1.380952380952381),\n", + " (15, 35, 2.5, 2.3333333333333335),\n", + " (20, 30, 1.5714285714285714, 1.5),\n", + " (19, 31, 1.6363636363636365, 1.631578947368421),\n", + " (21, 29, 1.4444444444444444, 1.380952380952381)]" + ] + }, + "execution_count": 93, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "list(found())" + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "id": "2d7d6f8b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[(11, 39, 3.5454545454545454, 47.19308954151068),\n", + " (12, 38, 3.1666666666666665, 47.18558098978421),\n", + " (13, 37, 2.8461538461538463, 47.179354476011646),\n", + " (14, 36, 2.5714285714285716, 47.17415487784531),\n", + " (15, 35, 2.3333333333333335, 47.16979419516311),\n", + " (16, 34, 2.125, 47.166131477877656),\n", + " (17, 33, 1.9411764705882353, 47.16305960247725),\n", + " (18, 32, 1.7777777777777777, 47.16049634511566),\n", + " (19, 31, 1.631578947368421, 47.158378230688704),\n", + " (20, 30, 1.5, 47.15665622507779),\n", + " (21, 29, 1.380952380952381, 47.15529268372393),\n", + " (22, 28, 1.2727272727272727, 47.154259179645024),\n", + " (23, 27, 1.173913043478261, 47.15353496521375),\n", + " (24, 26, 1.0833333333333333, 47.15310590655676),\n", + " (25, 25, 1.0, 47.15296378588499),\n", + " (26, 24, 0.9230769230769231, 47.15310590655676),\n", + " (27, 23, 0.8518518518518519, 47.15353496521375),\n", + " (28, 22, 0.7857142857142857, 47.154259179645024),\n", + " (29, 21, 0.7241379310344828, 47.15529268372393),\n", + " (30, 20, 0.6666666666666666, 47.15665622507779),\n", + " (31, 19, 0.6129032258064516, 47.158378230688704),\n", + " (32, 18, 0.5625, 47.16049634511566),\n", + " (33, 17, 0.5151515151515151, 47.16305960247725),\n", + " (34, 16, 0.47058823529411764, 47.166131477877656),\n", + " (35, 15, 0.42857142857142855, 47.16979419516311),\n", + " (36, 14, 0.3888888888888889, 47.17415487784531),\n", + " (37, 13, 0.35135135135135137, 47.179354476011646),\n", + " (38, 12, 0.3157894736842105, 47.18558098978421)]" + ] + }, + "execution_count": 81, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8c2dca2a", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.8" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/planets.scad b/planets.scad new file mode 100644 index 0000000..dae66c3 --- /dev/null +++ b/planets.scad @@ -0,0 +1,333 @@ +tooth_width = 0.8; +tooth_crop = 0.5; +tooth_thickness = 1.0; + +module tooth() { + width = tooth_width; + thickness = tooth_thickness; + crop = tooth_crop; + + points = [[0, width/2], [0, -width/2], [1, 0]]; + intersection() { +// rotate([90, 0, 0]) + linear_extrude(height=thickness, center=true) + polygon(points); + + cube([crop*2, width, thickness], center=true); + } +} + +function gear_base_radius(n) = + let (perimeter = tooth_width * (1 + 0.8*(1-tooth_crop)) * n) + perimeter / PI / 2; + +function gear_wheel_radius(n) = + sqrt(gear_base_radius(n)^2 + (tooth_width/2)^2); + +function gear_radius(n) = + (gear_wheel_radius(n) + + gear_base_radius(n) + tooth_crop)/2; + +module gear(n) { + radius = gear_base_radius(n); + wheel_radius = gear_wheel_radius(n); + thickness = tooth_thickness; + +// rotate([90, 0, 0]) + linear_extrude(height=thickness, center=true) + circle(wheel_radius, $fn=50); + + for (i=[0:n-1]) { + angle=360 / n; + rotate([0, 0, i * angle]) + translate([radius, 0, 0]) + tooth(); + } +} + +gear_scale = 5; + +module final_gear(n) { + scale([gear_scale, gear_scale, gear_scale]) + gear(n); +} + +module orbit_ring(n1, n2) { + difference() { + union() { + cylinder(h=24, r=20, center=true); + + translate([22, 0, 0]) + rotate([0, 90, 0]) + cylinder(h=10, r=5, center=true); + + translate([0, 0, 12]) + final_gear(n=n1); + + translate([0, 0, -12]) + final_gear(n=n2); + } + cylinder(h=100, r=14.7, center=true); + } +} + +module orbit(length, orbit_order, n1, n2=25, planet_size=40) { +// orbit_length = 100; +// orbit_order = 20; + + orbit_length = length + 50; + + thickness = 2.0; + + rotate([0, 90, 0]) + translate([0, 0, orbit_length/2]) + cylinder(h=orbit_length, r=thickness/2, center=true, $fn=50); + + translate([orbit_length, 0, 0]) + translate([0, 0, orbit_order/2]) + cylinder(h=orbit_order, r=thickness/2, center=true, $fn=50); + + translate([orbit_length, 0, orbit_order+planet_size/2]) + sphere(planet_size/2); + + orbit_ring(n1, n2); +} + +module _sidegear_diff(r) { + difference() { + cylinder(h=200, r=r, center=true); + + translate([-2.5, 0, -110]) + cube([5, 300, 300]); + + rotate([0, 0, 120]) + translate([-2.5, 0, -110]) + cube([5, 300, 300]); + + rotate([0, 0, 240]) + translate([-2.5, 0, -110]) + cube([5, 300, 300]); + + cylinder(h=210, r=8, center=true); + } + + cube([4, 4, 25], center=true); +} + +module sidegear(n) { + difference() { + final_gear(n); + _sidegear_diff(n*0.75); + } +} + +module flangebrace() { + translate([0, -30, 0]) + cube([14.7, 5, 23], center=true); + + difference() { + union() { + translate([0, -12, 10]) + cube([14.7, 39, 3], center=true); + + translate([0, -12, -10]) + cube([14.7, 39, 3], center=true); + } + + cylinder(h=50, r=4, center=true); + } +} + +module flange(offset) { + difference() { + cylinder(h=5, r=22, center=true); + + cylinder(h=10, r=14.4, center=true); + } + + difference() { + translate([offset, 0, 0]) + cylinder(h=5, r=32, center=true); + + translate([offset, -32, 0]) + cube([15, 10, 15], center=true); + + translate([offset, 0, 0]) + _sidegear_diff(25); + + translate([offset, 0, 0]) + cylinder(h=6, d=6.3, center=true); + } +} + +module shaftend() { + difference() { + cylinder(h=3, r=3.9, center=true); + + cube([4, 4, 5], center=true); + } +} + +module linkage(offset, n1=25, n2) { + color("pink") + translate([offset, 0, 0]) { + cube([4, 4, 25], center=true); + + translate([0, 0, 10]) + shaftend(); + + translate([0, 0, -10]) + shaftend(); + + translate([0, 0, 5]) + sidegear(n=n1); + + translate([0, 0, -5]) + sidegear(n=n2); + } + + color("white") + flange(offset); + + translate([offset, 0, 0]) + flangebrace(); +} + + +module sungear(n) { + difference() { + //orbit_ring(n1=25, n2=25); + final_gear(n); + cylinder(h=200, r=14.7, center=true); + } +} + + + +module sunshaft() { + translate([0, 0, -180]) + cylinder(h=400, r=15, center=true); + + translate([0, 0, -380]) + cylinder(h=20, r=150, center=true); + + translate([0, 0, 45]) + sphere(d=66); +} + +/* + +inner gears: +----- +25: 9 +30: 2 +27: 1 +29: 2 +35: 1 +31: 1 +----- + 16 + +side gears: +----- +25: 7 +20: 2 +23: 1 +19: 1 +21: 2 +15: 1 +----- + 14 + +*/ + +sh = 29; +fh = 5; +function sleevez(i) = -i * (sh + fh) - sh/2; +function flangez(i) = sleevez(i) - 17; +function orbitz(i) = 20 - sleevez(i); + +gear_offset = 48; + +orbit_ring(35, 25); + + +//color("white") sunshaft(); +/* +// mercury +color("grey") +translate([0, 0, sleevez(0)]) +orbit(50, orbitz(0), n1=25); + +translate([0, 0, flangez(0)]) +linkage(offset=gear_offset, n2=20); +/* +// venus +color("yellow") +translate([0, 0, sleevez(1)]) +orbit(130, orbitz(1), n1=30); + +translate([0, 0, flangez(1)]) +linkage(offset=gear_offset, n2=23); + +// earth +color("#34a56f") +translate([0, 0, sleevez(2)]) +orbit(200, orbitz(2), n1=27); + +translate([0, 0, flangez(2)]) +linkage(offset=gear_offset, n2=21); + +// mars +color("red") +translate([0, 0, sleevez(3)]) +orbit(270, orbitz(3), n1=29); + +translate([0, 0, flangez(3)]) +linkage(offset=50, n2=15); + +// jupiter +color("orange") +translate([0, 0, sleevez(4)]) +orbit(450, orbitz(4), n1=35); + +translate([0, 0, flangez(4)]) +linkage(offset=50, n2=20); + +// saturn +color("purple") +translate([0, 0, sleevez(5)]) +orbit(540, orbitz(5), n1=30); + +translate([0, 0, flangez(5)]) +linkage(offset=50, n2=19); + +// uranus +color("#aaaaff") +translate([0, 0, sleevez(6)]) +orbit(640, orbitz(6), n1=31); + +translate([0, 0, flangez(6)]) +linkage(offset=50, n2=21); + +// neptune +color("#3333aa") +translate([0, 0, sleevez(7)]) +orbit(710, orbitz(7), n1=29); + +/* +*/ + +/* +gear0 = 7; +gear1 = 7; + +spacing = 1.0; + +rotate([0, 0, $t*360]) +final_gear(gear0); + +translate([spacing + (gear_radius(gear0) + gear_radius(gear1)) * gear_scale, 0, 0]) +rotate([0, 0, -$t*360 * gear0 / gear1]) +final_gear(gear1); +*/ \ No newline at end of file