Elipse de transición en una leva con OpenSCAD

He diseñado un mecanismo para llevar el teléfono en la bicicleta, en el que una pieza gira alrededor de un eje y abraza al tubo del manillar. En la imagen de abajo, las piezas de color ladrillo giran alrededor del eje cian, y al final del recorrido el círculo resaltado del lado izquierdo encaja en un alojamiento cilíndrico que tiene la pieza fija superior.

[Quizá te interese: Publicaciones sobre OpenSCAD]

portateléfono


Si nos fijamos en la imagen de abajo, durante el giro alrededor de (0, 0) es necesario que el resalte del extremo izquierdo de la pieza inferior entre en contacto con la pieza amarilla en el punto (p, q) de forma natural, sin tensión. Conforme sigue girando, la pieza se deforma y va aumentando su radio de giro. Al rebasar el borde de la hendidura cilíndrica en (r, s) recupera súbitamente su forma haciendo un ¡clac! al caer en (t, u).

exposición del problema

Geométricamente, los puntos (p, q) y (t, u) pertenecen a un círculo con origen en (0, 0). El punto (r, s) está más alejado, por lo que el arco que va de (p, q) a (r, s) forma parte de una elipse que constituye el flanco de subida de una leva.

planteamiento geométrico

Si definimos la elipse con sus semiejes A y B, cualquier punto (x, y) cumplirá x²/A² + y²/B² = 1. Por lo tanto, en el caso que nos ocupa tendremos un sistema de dos ecuaciones con dos incógnitas:
  • p²/A² + q²/B² = 1
  • r²/A² + s²/B² = 1
Despejando A y B tenemos:
  • B = raiz( (p²s² - r²q²) / (p² - r²) )
  • A = raiz( r² / (1 - s²/B²) )

He preparado un ejemplo muy tontorrón: en el círculo de un reloj pondré una leva desde la 1 a las 11. El resultado está en la siguiente imagen, y el código a continuación:

ejemplo de leva hecha con una elipse

$fs=1;

$fa=1;

X=0;

Y=1;


// considerando que el ángulo 0 está a las 3 en un reloj, quiero una leva que empiece a la 1

// vaya incrementando la altura hasta las 11 en sentido antihorario hasta 10mm


radio_principal = 40; // radio del círculo base

excentricidad = 10;   // cuánto se aleja la leva desde el círculo base

angulo_inicio = 60;     // ángulo de la 1

angulo_final = 120;   // ángulo de las 11

espesor = 5;          // altura, por hacerlo en 3D


if ((abs(angulo_final - angulo_inicio) < 90) && excentricidad < radio_principal) {


   // calcularé la elipse con los semiejes A y B paralelos a X e Y respectivamente, y luego la giro

   inicio = [radio_principal, 0];

   final =  [(radio_principal + excentricidad) * cos(angulo_final - angulo_inicio), (radio_principal + excentricidad) * sin(angulo_final - angulo_inicio)];



   B = sqrt( (pow(inicio[X] * final[Y], 2) - pow(inicio[Y] * final[X], 2)) / (pow(inicio[X], 2) - pow(final[X], 2)) );

   A = sqrt( pow(final[X], 2) / (1 - pow(final[Y]/B, 2)) );



   linear_extrude(espesor)

      difference() {

         union() {

            circle(radio_principal);

            rotate([0, 0, angulo_inicio])

               intersection() { // seleccionar sólo el arco de elipse que me interesa

                  resize([A*2, 0])

                     circle(B);

                  square(B);

                  rotate([0, 0, angulo_final - angulo_inicio])

                     translate([0, -B])

                        square(B);

               }

         }

         // ya puestos, pinto las horas

         for(hora= [1:12]) {

            angulo = 90 - hora * 30;

            rotate([0, 0, angulo])

               translate([30, 0])

                  rotate([0, 0, -angulo])

               text(str(hora), 8, halign="center", valign="center");

         }

      }

}

else // para levas >90º es preferible fundir con un círculo o elipse que no sea concéntrico, o mejor usar una clotoide

   echo("PROBLEMA INCONGRUENTE");

Comments