elipse de transición en una leva

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, 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.

porta-teléfono

Si nos fijamos en la imagen lateral, 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).

porta-teléfono en posición abierta

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, y de ahí el título de esta página.

planteamiento geométrico del problema

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 imagen de al lado, y el código a continuación:

ejemplo de leva

$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");