/* ******************************************* Objekt Info: Parametrierbares Kugellager ******************************************* Version: 01.10.2022 khf Dank an Rohin Gosling /* Beschreibung: - Parametrisches Kaefigkugellager - Auswahl und Parameter: o Anzahl der Kugeln o Innenring, Innendurchmesser o Aussendurchmesser. d.h. Aussenring, Aussendurchmesser. o Radiale Dicke der Ringe. o Axiale Spurweite. Dicke des axialen Kaefigs und der Schulterwaende. o Schulterhoehe. Radialhoehe der Schultern der Laufbahn. o Unabhaengige Bauteilabstaende: - Ball-zu-Ring-Freigabe. - Ball-zu-Kaefig-Freigabe. o Innere und aeussere Fasengroesse. o Innere und aeussere Raendelmerkmale: - Raendelzaehlung. - Raendelschnitttiefe. - Raendelschnittverhaeltnis. o Zugriffsanschluesse nach dem Drucken. Zugangsports werden verwendet, um die anfaengliche Manipulation der Kugeln zu erleichtern, um die Kugeln zu befreien aus dem Kaefig nach dem Drucken. - Der Durchmesser des Zugangsports ist parametisierbar. Generell gilt: Je groesser die Ports, desto besser. Es sollte jedoch darauf geachtet werden, dass der Portdurchmesser nicht zu gross wird, da sonst die axialen Waende des Kaefigs schwaecht werden. - Da keine Post-Print-Montage erforderlich ist, kann es ziemlich muehsam sein, die einzelnen Teile nach dem Drucken zu loesen. Die Zugangsoeffnungen sind so konzipiert, dass sie das Ausloesen der Kugeln aus dem Kaefig unterstuetzen. ******************************************* */ //*************** Auswahl ************* // Empfohlener Wert von 64 oder mehr. Standardwert = 128. resolution = 128; enable_inner_ring = 1; // [ 0:Nein, 1:Ja ] enable_outer_ring = 1; // [ 0:Nein, 1:Ja ] enable_cage = 1; // [ 0:Nein, 1:Ja ] enable_balls = 1; // [ 0:Nein, 1:Ja ] enable_inner_ring_chamfer = 1; // [ 0:Nein, 1:Ja ] enable_outer_ring_chamfer = 1; // [ 0:Nein, 1:Ja ] enable_inner_ring_knurling = 1; // [ 0:Nein, 1:Ja ] enable_outer_ring_knurling = 1; // [ 0:Nein, 1:Ja ] // Empfohlen, um Stuetzmaterial fuer die Baelle unterzubringen. enable_bottom_cage_access_ports = 1; // [ 0:Nein, 1:Ja ] enable_top_cage_access_ports = 1; // [ 0:Nein, 1:Ja ] /* [Farben] */ enable_multiple_colors = 1; // [ 0:Nein, 1:YJa ] default_color = "silver"; inner_ring_color = "red"; outer_ring_color = "grey"; ball_color = "yellow"; cage_color = "blue"; //***************************************** //*************** Libraries ************ // keine //***************************************** //*************** Parameter ************* /* [Ring und Kaefig] */ bore = 20.15; // Waehle +0,15 fuer eine enge Passform oder +0,2 fuer eine lockere Passform. outer_diameter = 55.0; shoulder_height = 1.0; radial_gauge = 2.0; axial_gauge = 1.0; cage_access_port_diameter = 2.5; /* [Mechanische Parameter] */ ball_count = 12; ball_ring_clearance = 0.1; // Empfohlen, 2x groesser als der Ballringabstand oder mehr. ball_cage_clearance = 0.4; inner_chamfer_size = 1.0; outer_chamfer_size = 1.0; inner_knurling_count = 3; inner_knurling_depth = 1.0; inner_knurling_cut_ratio = 0.2; outer_knurling_count = 18; outer_knurling_depth = 1.0; outer_knurling_cut_ratio = 0.2; //************** Programm ************** // Konvertierung von Ganzzahl in Boolesche. m_inner_ring_enabled = ( enable_inner_ring == 1 ) ? true : false; m_outer_ring_enabled = ( enable_outer_ring == 1 ) ? true : false; m_cage_enabled = ( enable_cage == 1 ) ? true : false; m_balls_enabled = ( enable_balls == 1 ) ? true : false; m_inner_ring_chamfer_enabled = ( enable_inner_ring_chamfer == 1 ) ? true : false; m_outer_ring_chamfer_enabled = ( enable_outer_ring_chamfer == 1 ) ? true : false; m_inner_ring_knurling_enabled = ( enable_inner_ring_knurling == 1 ) ? true : false; m_outer_ring_knurling_enabled = ( enable_outer_ring_knurling == 1 ) ? true : false; m_bottom_cage_access_ports_enabled = ( enable_bottom_cage_access_ports == 1 ) ? true : false; m_top_cage_access_ports_enabled = ( enable_top_cage_access_ports == 1 ) ? true : false; m_colors_enabled = ( enable_multiple_colors == 1 ) ? true : false; //***************************************** // System Konstanten. C_CONSTANT = 0 + 0; C_NULL = C_CONSTANT; C_FALSE = C_CONSTANT + 0; C_TRUE = C_CONSTANT + 1; // Toleranzen und Einschraenkungen minimal und maximal. C_EXCESS = C_CONSTANT + 0.5; // Kleines Ueberschwingen, um die Modellierung von Artefakten waehrend Schnitten (Differenzen) an koplanaren Flaechen zu verhindern. C_MIN_GAUGE = C_CONSTANT + 0.01; // Mindestgroesse der Spurweite. C_MIN_KNURLING_COUNT = C_CONSTANT + 1; // Mindestanzahl der Raendeln. C_MIN_RESOLUTION = C_CONSTANT + 32; // Minimale Modellaufloesung. C_MIN_BALL_COUNT = C_CONSTANT + 3; // Mindestanzahl von Kugeln. // Debuggen von Konstanten. C_EXTRUDE_ENABLED = C_TRUE; C_BALL_TEMPLATE_ENABLED = C_FALSE; C_CONSOLE_LOG_ENABLED = C_TRUE; // Mechanische Parameter. m_ball_ring_clearance = clip ( ball_ring_clearance, 0.0, 1.2 ); m_ball_cage_clearance = clip ( ball_cage_clearance, 0.0, 1.2 ); m_cage_ring_clearance = 0.2 + m_ball_ring_clearance + m_ball_cage_clearance; // Lagerparameter. m_radial_gauge = ( radial_gauge >= C_MIN_GAUGE ) ? radial_gauge : C_MIN_GAUGE; m_axial_gauge = ( axial_gauge >= C_MIN_GAUGE ) ? axial_gauge : C_MIN_GAUGE; m_bore = ( bore >= 0.0 ) ? bore : 0.0; m_outer_diameter = ( outer_diameter >= m_bore + 4.0*( 1.0 + m_radial_gauge + C_MIN_GAUGE ) ) ? outer_diameter : m_bore + 4.0*( 1.0 + m_radial_gauge + C_MIN_GAUGE ); m_shoulder_height = clip ( shoulder_height, 0.0, ( ( m_outer_diameter/2.0 - m_radial_gauge ) - ( m_bore/2.0 + m_radial_gauge ) )/2.0 - 2.0*m_ball_ring_clearance ); m_ball_diameter = ( m_outer_diameter - m_bore )/2.0 - 2.0*m_radial_gauge; m_width = m_ball_diameter + 2.0*m_axial_gauge; m_pitch_radius = m_bore/2.0 + ( m_outer_diameter - m_bore )/4.0; m_max_ball_count = max_ball_count ( m_pitch_radius, m_ball_diameter ); m_ball_count = clip ( ball_count, C_MIN_BALL_COUNT, m_max_ball_count ); // Kaefigparameter. m_access_port_diameter = clip ( cage_access_port_diameter, 0.0, ( ( m_outer_diameter/2.0 - m_radial_gauge - m_shoulder_height ) - ( m_bore/2.0 + m_radial_gauge + m_shoulder_height ) )/2.0 - 2.0*m_cage_ring_clearance ); // Raendelung-Parameter. m_inner_chamfer_size = clip ( inner_chamfer_size, 0.0, m_radial_gauge + m_shoulder_height ); m_outer_chamfer_size = clip ( outer_chamfer_size, 0.0, m_radial_gauge + m_shoulder_height ); m_inner_knurling_count = ( inner_knurling_count >= C_MIN_KNURLING_COUNT ) ? inner_knurling_count : C_MIN_KNURLING_COUNT; m_inner_knurling_depth = clip ( inner_knurling_depth, 0.0, m_radial_gauge - C_MIN_GAUGE ); m_inner_knurling_cut_ratio = clip ( inner_knurling_cut_ratio, 0.0, 1.0 ); m_outer_knurling_count = ( outer_knurling_count >= C_MIN_KNURLING_COUNT ) ? outer_knurling_count : C_MIN_KNURLING_COUNT; m_outer_knurling_depth = clip ( outer_knurling_depth, 0.0, m_radial_gauge - C_MIN_GAUGE ); m_outer_knurling_cut_ratio = clip ( outer_knurling_cut_ratio, 0.0, 1.0 ); // Modelloptionen. m_resolution = ( resolution >= C_MIN_RESOLUTION ) ? resolution : C_MIN_RESOLUTION; m_sphere_resolution = 3.0*m_resolution/5.0; m_default_color = default_color; m_inner_ring_color = inner_ring_color; m_outer_ring_color = outer_ring_color; m_ball_color = ball_color; m_cage_color = cage_color; // Meldungen an die Konsole if ( C_CONSOLE_LOG_ENABLED ) { echo ( cage_ring_clearance = m_cage_ring_clearance ); echo ( ball_diameter = m_ball_diameter - m_ball_ring_clearance ); echo ( width = m_width ); echo ( bore = m_bore ); echo ( pitch_radius = m_pitch_radius ); echo ( outer_diameter = m_outer_diameter ); echo ( ball_count = m_ball_count ); echo ( shoulder_height = m_shoulder_height ); echo ( access_port_diameter = m_access_port_diameter ); } // --------------------------------------------------------------------------- // Modul: Hauptmodul // Modul Type: Model // // Beschreibung: // // - Einstiegspunkt fuer das Programm. // --------------------------------------------------------------------------- main(); module main () { $fn = m_resolution; if ( m_inner_ring_enabled ) component_inner_ring (); if ( m_outer_ring_enabled ) component_outer_ring (); if ( m_balls_enabled ) component_ball_array ( m_ball_count, m_ball_diameter, m_ball_ring_clearance ); if ( m_cage_enabled ) component_cage (); if ( C_BALL_TEMPLATE_ENABLED ) profile_ball_template (); } // --------------------------------------------------------------------------- // Modul: Ball Array // Modul Typ: Bestandteil // // Beschreibung: // // - Erstellt ein kreisfoermiges Array von Kugellagern. // - Dies wird sowohl zur Erzeugung der eigentlichen Anordnung von Kugellagern als auch fuer die Zweck der Erstellung eines Schneidwerkzeugs, um Platz fuer die Kugeln im Kaefig zu schaffen. // // Parameter: // // - count // Anzahl der zu erstellenden Kugeln. Beachte, dass dieses Modul nicht auf minimale oder maximale Kugeln ueberprueft. // // - diameter // Der Durchmesser fuer jede Kugel. // // - clearance // Reduzierung des Radius jeder Kugel, um dem Bauteilabstand gerecht zu werden. // Hinweis: Der Abstand reduziert den Radius um den Durchmesser mm, nicht um den Durchmesser. // // --------------------------------------------------------------------------- module component_ball_array ( count, diameter, clearance ) { radial_gauge = m_radial_gauge; bore = m_bore; component_color = ( m_colors_enabled ) ? m_ball_color : m_default_color; // Generiere das Kugel-Array. color ( component_color ) if ( C_EXTRUDE_ENABLED ) { // Berechnen Sie den Kugeldurchmesser, reduziert durch Kugelringspiel. d = diameter - 2.0*clearance; // Berechnen Sie die radiale Translation des Ballarrays. d.h. die Lagersteigung. tx = ( bore + d ) / 2 + radial_gauge + clearance; ty = 0.0; tz = 0.0; // Berechne die Winkelverschiebung zwischen den einzelnen Kugeln relativ zur Ballanzahl. tr = 360 / count; // Generiere das Kugel-Array. for ( i = [ 0 : count ] ) { tri = tr * i; rotate ( [ 0, 0, tri ] ) translate ( [ tx, ty, tz ] ) sphere ( d = d, $fn = m_sphere_resolution ); } } } // ---------------------------------------------------------------------------- // Modul: Inner Ring // Modul Typ: Komponente // // Beschreibung: // // - Erstellt den inneren Ring. // // Parameter: // // - keine // // ---------------------------------------------------------------------------- module component_inner_ring () { if ( C_EXTRUDE_ENABLED ) { component_color = ( m_colors_enabled ) ? m_inner_ring_color : m_default_color; color ( component_color ) difference () { // Extrudiere das 3D-Objekt. rotate_extrude() profile_inner_ring (); // Schneiden der Raendelung. if ( m_inner_ring_knurling_enabled ) { cutting_tool_inner_knurling (); } } } else { // Das Profil fuer Debugging-Zwecke. profile_inner_ring (); } } // --------------------------------------------------------------------------- // Modul: Outer Ring. // Modul Typ: Komponente // // Beschreibung: // // - Erstellt den aeusseren Ring. // // Parameter: // // - keine // // --------------------------------------------------------------------------- module component_outer_ring () { if ( C_EXTRUDE_ENABLED ) { component_color = ( m_colors_enabled ) ? m_outer_ring_color : m_default_color; color ( component_color ) difference () { // Extrudiere das 3D-Objekt. rotate_extrude() profile_outer_ring (); // Schnitt if ( m_outer_ring_knurling_enabled ) { cutting_tool_outer_knurling (); } } } else { // Das Profil fuer Debugging-Zwecke. profile_outer_ring (); } } // ---------------------------------------------------------------------------- // Modul: Cage. // Modul Typ: Komponente // // Beschreibung: // // - Erstellt den Lagerkaefig. // // Parameter: // // - N/A // // --------------------------------------------------------------------------- module component_cage () { ball_count = m_ball_count; ball_diameter = m_ball_diameter; ball_ring_clearance = m_ball_ring_clearance; ball_cage_clearance = m_ball_cage_clearance; component_color = ( m_colors_enabled ) ? m_cage_color : m_default_color; if ( C_EXTRUDE_ENABLED ) { ball_cut_diameter = ball_diameter - ball_ring_clearance; clearance = -ball_cage_clearance; color ( component_color ) difference () { rotate_extrude() profile_cage (); component_ball_array ( ball_count, ball_cut_diameter, clearance ); cutting_tool_access_port_array (); } } else { profile_cage (); } } // --------------------------------------------------------------------------- // Modul: Port-Array-Schneidewerkzeug // Modul Typ: Schneidewerkzeug. // // Beschreibung: // // - Erstellt ein Schneidwerkzeug, das zum Schneiden von Zugangsoeffnungen in den Kaefig verwendet wird. // // Parameter: // // - keine // // --------------------------------------------------------------------------- module cutting_tool_access_port_array () { width = m_width; access_port_diameter = m_access_port_diameter; pitch_radius = m_pitch_radius; ball_count = m_ball_count; bottom_cage_access_ports_enabled = m_bottom_cage_access_ports_enabled; top_cage_access_ports_enabled = m_top_cage_access_ports_enabled; // Konfiguriere die Abmessungen des Zugriffsports. e = C_EXCESS; ah = width / 2.0 + e; ar = access_port_diameter; // Berechne die Komponentenuebersetzungen vom Schneidwerkzeug. tx0 = pitch_radius; ty0 = 0.0; tz0 = -ah; tx1 = pitch_radius; ty1 = 0.0; tz1 = 0.0; // Berechne die Winkelverschiebung zwischen den einzelnen Schneidwerkzeugkomponenten relativ zur Kugelanzahl. tr = 360 / ball_count; // Generieren das Layout der Schneidwerkzeuge. for ( i = [ 0 : ball_count ] ) { tri = tr * i; rotate ( [ 0, 0, tri ] ) { // Generiere die Komponenten fuer das Schneidwerkzeug fuer den unteren Zugriff. if ( bottom_cage_access_ports_enabled ) { translate ( [ tx0, ty0, tz0 ] ) cylinder ( h = ah, r = ar, center = false ); } // Generiere die Top-Access-Port-Schneidwerkzeugkomponenten. if ( top_cage_access_ports_enabled ) { translate ( [ tx1, ty1, tz1 ] ) cylinder ( h = ah, r = ar, center = false ); } } } } // --------------------------------------------------------------------------- // Modul: Inneres Raendelschneidwerkzeug. // Modul Typ: Schneidwerkzeug. // // Beschreibung: // // - Erstellt ein Schneidwerkzeug zum Schneiden von Raendelkerben in den Innenring. // // Parameter: // // - keine // // --------------------------------------------------------------------------- module cutting_tool_inner_knurling () { // Abrufen globaler Parameter. e = C_EXCESS; // Zusaetzliche Laenge, die verwendet wird, um Gleitkommadifferenzfehler waehrend boolescher Operationen zu eliminieren. n = m_inner_knurling_count; // Anzahl der Raendelschnitte. d = m_inner_knurling_depth + e; // Schnitttiefe. k = 360.0 / n; // Bogenlaenge in Grad. p = m_inner_knurling_cut_ratio; // Raendelschnittverhaeltnis. w = m_width + 2.0*e; // Lagerbreite. // Schneidwerkzeug generieren. for ( i = [ 0 : n-1 ] ) { // Berechnen Sie Dreh- und Schnittverhaeltniswinkel. t = i*k; a = p*k; // Berechne die radiale Translation. tx = m_bore/2.0 - e; ty = -w/2.0; // Generieren der Schneidwerkzeugteile. tz = t - a/2.0; rotate ( [ 0.0, 0.0, tz ] ) { cylinder_sector ( inner_radius = tx, outer_radius = tx + d, height = w, angle = a, tessellation = m_resolution, center = true ); } } } // --------------------------------------------------------------------------- // Modul: Aeusseres Raendelschneidwerkzeug. // Modul Typ: Schneidwerkzeug. // // Beschreibung: // // - Erstellt ein Schneidwerkzeug zum Schneiden von Raendelkerben in den Aussenring. // // Parameter: // // - keine // // ---------------------------------------------------------------------------- module cutting_tool_outer_knurling () { e = C_EXCESS; // Zusaetzliche Laenge, die verwendet wird, um schadenfrohe Punktdifferenzfehler waehrend boolescher Operationen zu eliminieren. n = m_outer_knurling_count; // Anzahl der Raendelschnitte. d = m_outer_knurling_depth + e; // Schnitttiefe. k = 360.0 / n; // Bogenlaenge in Grad. p = m_outer_knurling_cut_ratio; // Raendelschnittverhaeltnis. w = m_width + 2.0*e; // Lagerbreite. // Schneidwerkzeug generieren. for ( i = [ 0 : n-1 ] ) { // Berechne den Dreh- und Schnittverhaeltniswinkel. t = i*k; a = p*k; // Berechne die radiale Translation. tx = m_outer_diameter/2.0 - d + e; ty = -w/2.0; // Generiere die Schneidwerkzeugteile. tz = t - a/2.0; rotate ( [ 0.0, 0.0, tz ] ) { cylinder_sector ( inner_radius = tx, outer_radius = tx + d, height = w, angle = a, tessellation = m_resolution, center = true ); } } } // --------------------------------------------------------------------------- // Modul: Innere Ring. // Modul Typ: Profil. // // Beschreibung: // // - Erstellt das 2D-Extrusionsprofil des Innenrings. // // Parameter: // // - keine // // ---------------------------------------------------------------------------- module profile_inner_ring () { bore = m_bore; inner_ring_chamfer_enabled = m_inner_ring_chamfer_enabled; inner_chamfer_size = m_inner_chamfer_size; // Uebersetzung berechnen. tx = bore / 2.0; ty = 0.0; tz = 0.0; // Profil generieren. translate ( [ tx, ty, tz ] ) profile_ring ( inner_ring_chamfer_enabled, inner_chamfer_size ); } // --------------------------------------------------------------------------- // Modul: Aeussere Ring. // Modul Typ: Profil. // // Beschreibung: // // - Erstellt das 2D-Extrusionsprofil des Aussenrings. // // Parameter: // // - keine // // --------------------------------------------------------------------------- module profile_outer_ring () { bore = m_bore; radial_gauge = m_radial_gauge; ball_diameter = m_ball_diameter; outer_ring_chamfer_enabled = m_outer_ring_chamfer_enabled; outer_chamfer_size = m_outer_chamfer_size; // Uebersetzung berechnen. tx = m_outer_diameter/2.0; // Profil generieren. translate ( [ tx, 0.0, 0.0 ] ) rotate ( [ 0.0, 0.0, 180 ] ) profile_ring ( outer_ring_chamfer_enabled, outer_chamfer_size ); } // --------------------------------------------------------------------------- // Modul: Ring. // Modul Typ: Profil. // // Beschreibung: // // - Erstellt das allgemeine 2D-Extrusionsprofil fuer die Innen- und Aussenringe. // // Parameter: // // - chamfer_enabled // Fasenprofil einschliessen, wenn true, sonst Fase ausschliessen. // // - chamfer_size // Gib die orthogonale Groesse der Fase an. Dies wird nur fuer den Fall verwendet, dass chamfer_enabled true ist. // // --------------------------------------------------------------------------- module profile_ring ( chamfer_enabled, chamfer_size ) { radial_gauge = m_radial_gauge; shoulder_height = m_shoulder_height; width = m_width; ball_diameter = m_ball_diameter; // Berechne die Ringgeometrie. rsx = radial_gauge + shoulder_height; rsy = width; // Berechne die Ring-Uebersetzung. rtx = rsx / 2.0; rty = 0.0; rtz = 0.0; // Berechne die Geometrie der Kugellaufbahn. bsd = ball_diameter; // Berechne die Uebersetzung der Kugellaufbahn. btx = bsd / 2.0 + radial_gauge; bty = 0.0; btz = 0.0; // Berechnung der Fasengeometrie; cr = 2*chamfer_size; cs = sqrt ( ( cr * cr ) / 2.0 ); // Berechne die Fasenuebersetzung. ctx = 0.0; cty = width / 2.0; ctz = 0.0; // Profil generieren. difference () { // Ziel = ungeschnittenes Innenringprofil. translate ( [ rtx, rty, rtz ] ) rectangle ( rsx, rsy, center = true ); // Schneide die Laufbahn ab. translate ( [ btx, bty, btz ] ) circle ( d = bsd ); // Schneide die linke und rechte Fase weg. if ( chamfer_enabled ) { translate ( [ ctx, cty, ctz ] ) rotate ( [ 0, 0, 45 ] ) square ( size = cs, center = true ); translate ( [ ctx, -cty, ctz ] ) rotate ( [ 0, 0, 45 ] ) square ( size = cs, center = true ); } } } // --------------------------------------------------------------------------- // Modul: Kaefig. // Modul Typ: Profil. // // Beschreibung: // // - Erstellt das Profil, das zum Extrudieren des Lagerkaefigs verwendet wird. // // Parameter: // // - keine // // --------------------------------------------------------------------------- module profile_cage () { ball_diameter = m_ball_diameter; shoulder_height = m_shoulder_height; cage_ring_clearance = m_cage_ring_clearance; width = m_width; ball_diameter = m_ball_diameter; cage_ring_clearance = m_cage_ring_clearance; pitch_radius = m_pitch_radius; // Berechne die Kaefiggeometrie. csx = ball_diameter - 2.0*( shoulder_height + cage_ring_clearance ); csy = width; // Berechne die Geometrie des Kugelgehaeuses. bd = ball_diameter - 2.0*cage_ring_clearance; // Uebersetzung der Kaefige. tx = pitch_radius; ty = 0.0; tz = 0.0; // Profil generieren. translate ( [ tx, ty, tz ] ) { union () { rectangle ( csx, csy, center = true ); circle ( d = bd ); } } } // ---------------------------------------------------------------------------- // Modul: Debugging- und Design-Ball-Vorlage. // Modul Typ: Profil. // //Beschreibung: // //- Dies ist ein 2D-Profil einer Kugel, das zum Debuggen und Entwerfen der Ringe und des Kaefigs verwendet wird. //- Die Kugelvorlage kann aktiviert werden, indem die globale Konstante C_BALL_TEMPLATE_ENABLED auf C_TRUE gesetzt wird. // // Parameter: // // - keine // // --------------------------------------------------------------------------- module profile_ball_template () { ball_diameter = m_ball_diameter; ball_ring_clearance = m_ball_ring_clearance; bore = m_bore; radial_gauge = m_radial_gauge; ball_ring_clearance = m_ball_ring_clearance; // 2D-Kugelvorlage generieren. d = m_ball_diameter - 2*m_ball_ring_clearance; tx = ( m_bore + d ) / 2 + m_radial_gauge + m_ball_ring_clearance; ty = 0.0; tz = 0.0; translate ( [ tx, ty, tz ] ) circle ( d = d ); } // --------------------------------------------------------------------------- // Modul: Rechteck. // Modul Typ: 2D Form. // // Beschreibung: // // - Erstellt ein 2D-Rechteck. // // Parameter: // // - w // Rechteckbreite. // // - h // Rechteckbhoehe. // // - center // Zentriere das Rechteck um den Ursprung (0,0,0), wenn true, andernfalls platzieren Sie das Rechteck im positiven Quadranten. // // --------------------------------------------------------------------------- module rectangle ( w, h, center ) { scale ( [ w, h ] ) square ( size = 1.0, center = center ); } //----------------------------------------------------------------------------- // Modul: Zylindersektor. // Modul Typ: 2D Form. // // Beschreibung: // // - Erstellt ein zylindrisches Sektorobjekt. // // Parameter: // // - radius: // Radius des Zylindersektors. // // - height: // Hoehe des Zylindersektors. // // - angle: // Der zentrale Winkel (Winkelabstand) des Zylindersektors, gemessen in Grad. // // - tessellation: // Der Tesselierungsfaktor ist die dynamisch angepasste Polygonseitenzahl. // - Zum Beispiel bei einem zentralen Winkel von 360 Grad (d. h. einem vollstaendigen Zylinder) und einer Tesselierung von 8 // Modul erzeugt einen zylindrischen Koerper mit 8 Seiten. // - Bei einem zentralen Winkel von 180 Grad (d. h. einem halben Scheibenzylinder) und wiederum einer Tesselation von 8 ist die // Modul erzeugt einen zylindrischen Koerper mit der Anzahl der Seiten, die dynamisch auf 4 Seiten in um die Tesselierungsaufloesung konsistent zu halten.. // // - center: // Boolesches Flag zum Festlegen des geometrischen Mittelpunkts der object.t. // - Wenn true, befindet sich der geometrische Mittelpunkt des Objekts um den Ursprung (0,0,0). // - Wenn false, befindet sich die Basis des Zylinders um den Ursprung (0,0,0).). // //----------------------------------------------------------------------------- module cylinder_sector ( inner_radius, outer_radius, height, angle, tessellation, center ) { // Lokale Konstanten DEBUG_ENABLED = false; TESSELLATION_MAX = 4; ANGLE_MIN = 0; ANGLE_MAX = 360; HEIGHT_MIN = 0; E = 0.01; // Innere vs. aeussere Radiustoleranz, die verwendet wird, wenn der innere Radius dem aeusseren Radius entspricht. // Schneide die Parameter aus und initialisiere die lokalen Variablen. t = ( angle < ANGLE_MIN ) ? ANGLE_MIN : ( angle > ANGLE_MAX ) ? ANGLE_MAX : angle; h = ( height < HEIGHT_MIN ) ? HEIGHT_MIN : height; ri = ( inner_radius < ANGLE_MIN ) ? ANGLE_MIN : inner_radius; ro = ( outer_radius <= inner_radius ) ? inner_radius + E : outer_radius; tn = ( tessellation < TESSELLATION_MAX ) ? TESSELLATION_MAX : tessellation; // Dynamisch angepasste Tessellation berechnen. n = ceil ( tn * t / ANGLE_MAX ); // 2D-Geometrie generieren i = 0; // Punkteindex. Initialisieren Sie mit Null. v = []; // Leerer Vektor, aus dem rekursiv Ausgabevektoren erstellt werden sollen. points_inner = arc_vector ( ri, t, n, i, v ); points_outer = arc_vector ( ro, t, n, i, v ); points = concat ( points_inner, points_outer ); // Indexsequenz kompilieren. indices_inner = index_vector ( n + 1, i, v ); indices_outer = index_vector ( 2*n + 2, n + 1, v ); indices = [ concat ( indices_inner, vector_reverse ( indices_outer, len ( indices_outer ) ) ) ]; // 3D-Objekt generieren. linear_extrude ( height = h, center = center ) polygon ( points, indices ); // Debug. if ( DEBUG_ENABLED ) { echo ( t = t ); echo ( h = h ); echo ( ri = ri ); echo ( ro = ro ); echo ( tn = tn ); echo ( n = n ); } } //----------------------------------------------------------------------------- // Funktion: Schneiden // // Beschreibung: // // - Schneidet einen Eingabewert auf einen Minimal- und Maximalwert ab. // // x_min <= x <= x_max // // Parameter: // // - x // Eingangsgroesse. // // - x_min // Minimale Werteinschraenkung. Jedes x kleiner als x_min ist auf x_min gesetzt. // // - x_max // Maximale Werteinschraenkung. Jedes x groesser als x_max wird auf x_max gesetzt. // //------------------------------------------------------------------------------ function clip ( x, x_min, x_max ) = ( x < x_min ) ? x_min : ( x > x_max ) ? x_max : x; //----------------------------------------------------------------------------- // Funktion: Berechne die maximale Kugelanzahl. // // Description: // // - Computes the maximum ball count, based on the ball pitch radius and the ball diameter. // // 2*PI*r // n = ------ // d // // - Anmerkung: //Diese Gleichung behandelt das Kugel-Array als lineares Array von Kugeln und passt sich nicht dem tatsaechlichen Winkel an. //Kontaktpunkte zwischen den Kugeln. // // Parameter: // // - r // Radius der Kugel. // // - d // Durchmesser der Kugel. // //----------------------------------------------------------------------------- function max_ball_count ( r, d ) = floor ( 2.0*PI*r/d ); //----------------------------------------------------------------------------- // Funktion: Vektorumkehrung. // // Beschreibung: // // - Rekursive Vektor-Umkehrfunktion. // // Parameter: // // - v // Der umzukehrende Vektor. // // - length // TDie Laenge des umzukehrenden Vektors. Initialize to, len ( v ). // // EBeispiel: // // x = [ 1, 2, 3, 4 ]; // y = reverse ( x, len ( x ) ); // echo ( y = y ); // // ECHO: y = [4, 3, 2, 1] // //----------------------------------------------------------------------------- function vector_reverse ( v, length ) = ( length <= 0 // Rekursive Abschlussbedingung: // Gibt einen leeren Vektor zurueck ? [] // Rekursiver Allgemeinzustand: // Haenge die Rueckseite von allem bis zum letzten Element an. : concat ( v [ length - 1 ], vector_reverse ( v, length - 1 ) ) ); //----------------------------------------------------------------------------- // Funktion: Vektor generieren und indizieren. // // Beschreibung: // // - Rekursive Funktion, die einen n-dimensionalen Vektor ganzer Zahlen im Bereich [0..n-1] erzeugt. // // Parameter: // // - n // Anzahl der Elemente im Vektor. // // - i // Elementindex. Initialisieren Sie mit Null. // // - v // Vektor, der mit der Sequenz gefuellt werden soll. Initialisiere mit einem leeren Vektor, []. // // Beispiel: // // n = 8; // i = 0; // v = []; // x = count_loop ( n, i, v ); // echo ( x = x ); // // ECHO: x = [0, 1, 2, 3, 4, 5, 6, 7 ] // //----------------------------------------------------------------------------- function index_vector ( n, i, v ) = ( i >= n // Rekursive Abschlussbedingung: // Gib einfach den Eingabevektor unveraendert zurueck. ? v // Rekursiver Allgemeinzustand: // Fuege dem Eingabevektor den naechsten Index hinzu. : index_vector ( n, i + 1, concat ( v, [ i ] ) ) ); //----------------------------------------------------------------------------- // Funktion: Generiere ein Bogenvektorpunkt-Array. // // Beschreibung: // // - Rekursive Funktion, um ein Array von 2D-Punkten auf einem Bogen zu erzeugen. // // Parameter: // // - r // Kreisradius der Kuchenscheibe. Initialisiere mit dem Radius des Kreisstuecks. // // - t // Bogenwinkel. // // - n // Tessellationsfaktor. Initialisiere mit der Anzahl der Bogensegmente. // // - i // Punkteindex. Initialisieren mit Null. // // - v // Vektor, der mit Geometriepunkten aufgefuellt wird. Initialisiere mit leerem Vektor, []. // //----------------------------------------------------------------------------- function arc_vector ( r, t, n, i, v ) = ( i>n // Rekursive Abschlussbedingung: // Gibt einen leeren Vektor zurueck ? concat ( v, [] ) // Rekursiver Allgemeinzustand: // Berechnen Sie den naechsten Winkelpunkt des Kreissegments. // x = r*cos(i*t/n), wobei i der Punktindex, t der Bogenwinkel und n der Tesselierungsfaktor ist. // y = r*sin(i*t/n), wobei i der Punktindex, t der Bogenwinkel und n der Tesselierungsfaktor ist. : arc_vector ( r, t, n, i + 1, concat ( v, [ [ r*cos ( i*t/n ), r*sin ( i*t/n ) ] ] ) ) );