Introducción
Esta cosa es sólo un script SCAD que proporciona un API para manipular partes de un modelo colocándolas relativas entre sí.
Cuando escribí los modelos SCAD descubrí que los guiones de los resultados no son legibles. Incluso cuando los leí yo mismo muchos días después no entiendo lo que escribí y por qué los escribí de esta manera.
La razón principal es que utilizo muchos valores constantes computados o medidos en partes en la vida real e incluso con comentarios en código esto es difícil de leer. Además, cuando quiero hacer modificaciones no sé dónde aplicarlas en el código.
Este API simplifica todos mis diseños permitiéndome colocar las partes relacionadas entre sí.
Esta cosa está diseñada usando esta biblioteca: http://www.thingiverse.com/thing:2005142
How it works
Boxes basics
Cada parte elemental del modelo (cubo, cilindro, etc...) puede ser delimitada por una caja que se crea usando el api boxCreate().
Las caras de las cajas siempre están alineadas con los ejes x,y,z. La cajaCrear api sólo toma el tamaño de la caja en [x,y,z] antes de cualquier rotación:
boundingBox = boxCreate ( [1, 1, 1] );
El objeto devuelto es una matriz en la que podemos obtener algunos valores calculados utilizando índices (que están todos listados al principio o el archivo box.scad).
Por ejemplo, estos índices devuelven los elementos de tamaño de la caja. Cuando la caja se crea por primera vez, estos son sólo los valores que dimos:
boundingBox [idx]
boundingBox [idy]
boundingBox [idz]
Los siguientes índices devuelven los valores de posición en x,y,z del centro de la caja. El centro de la caja es el punto que movemos usando transformaciones, puede estar en cualquier lugar de la caja. Cuando se crea la caja por primera vez, el centro es el baricentro de todos sus puntos y se coloca en la coordenada [0,0,0]:
boundingBox [ix]
boundingBox [iy]
boundingBox [iz]
Los siguientes índices devuelven la posición x de la cara izquierda:
boundingBox [ixmin]
boundingBox [ileft]
Las equivalencias se hacen de tal manera que usted es el observador que mira en la dirección del eje Y con Z yendo arriba y X yendo a la derecha:
ixmin = ileft
ixmax = iright
iymin = ifront
iymax = iback
izmin = ibottom
izmax = itop
Transformaciones
La caja puede ser traducida, rotada y redimensionada.
El objeto contiene en realidad 2 cajas: la caja exterior que acabamos de ver (coordenadas globales) y la caja interior (coordenadas locales).
Para acceder a las coordenadas locales, sólo hay que añadir una "l" en los índices:
ilxmin = illeft
ilxmax = ilright
ilymin = ilfront
ilymax = ilback
ilzmin = ilbottom
ilzmax = iltop
Cuando se crea la caja, las coordenadas locales y globales tienen los mismos valores. Pero diferirán cuando se usen transformaciones:
Cuando se traduce la caja usando las funciones "boxTranslatexxx" o "boxMovexxx" sólo se traduce la caja global, la caja local permanece sin modificar,
Cuando rotas la caja usando las funciones "boxRotatexxx" sólo se recalcula la caja global para mantener la parte de rotación de la caja local.
Cuando se cambia el tamaño de la caja usando las funciones "boxResizexxx" o "boxExtrudexxx", la caja local se cambia de tamaño y la caja global se recalcula para mantener la parte giratoria de la caja local.
Otra forma de explicar esto es: La caja global es la caja delimitadora de la caja local después de la traducción/rotación.
Rendering
Las siguientes APIs permiten obtener módulos SCAD con formas elementales delimitadas en una caja:
"boxRenderCube(bbox): este módulo construye un SCADcubo` delimitado en la caja local, girado y traducido,
"boxRenderCylinderX(bbox)`: este módulo construye un "cilindro" SCAD orientado en el eje X de la caja local, girado y trasladado,
"BoxRenderCylinderY(bbox)`: este módulo construye un "cilindro" SCAD orientado en el eje Y de la caja local, girado y trasladado,
"boxRenderCylinderZ(bbox)`: este módulo construye un "cilindro" SCAD orientado en el eje Z de la caja local, girado y trasladado,
"boxRenderConeRight(bbox, sd)`: este módulo construye un "cilindro" SCAD orientado en la X. El pequeño diámetro (sd) del cono se coloca en la cara derecha de la caja local,
"BoxRenderConeLeft(bbox, sd)`: este módulo construye un "cilindro" SCAD orientado en la X. El pequeño diámetro (sd) del cono se coloca en la cara izquierda de la caja local,
"BoxRenderConeBack(bbox, sd)`: este módulo construye un "cilindro" SCAD orientado en la X. El pequeño diámetro (sd) del cono se coloca en la cara posterior de la caja local,
boxRenderConeFront(bbox, sd): este módulo construye un cilindro SCAD orientado en la X. El pequeño diámetro (sd) del cono se coloca en la cara frontal de la caja local,
boxRenderConeTop(bbox, sd): este módulo construye un cilindro SCAD orientado en la X. El pequeño diámetro (sd) del cono se coloca en la cara superior de la caja local,
boxRenderConeBottom(bbox, sd): este módulo construye un cilindro SCAD orientado en la X. El pequeño diámetro (sd) del cono se coloca en la cara inferior de la caja local.
Los diámetros de los cilindros y el diámetro del cono grande se calculan como el valor mínimo de los bordes de la base del cilindro/cono.
Obsérvese que el objeto resultante está delimitado por la caja global.
Ejemplos
Como se puede ver, los únicos valores escalares son las cajas delimitadoras iniciales de los artículos. Estas cajas se mueven y giran con transformaciones de la API de cajas y luego se renderizan utilizando módulos de la API de cajas (boxRenderxxx).
Ejemplo 1
En esta escena queremos que la caja principal esté centrada en [0,0,0], el cilindroX pegado al centro de la cara derecha de la caja principal, entonces el cilindroY es en realidad un cono basado en el centro del cilindroX y girado por 42°.
incluir <box-001.scad>
$fn = 180;
mainBoxSize = [8.4, 9.1, 10.5];
cilindroXSize = [8.5, 1.2, 1.2];
tamaño del cilindro = [0.8, 5.4, 0.8];
Cilindro de rotación = [ 42, 0, 0];
mainBox = boxCreate ( mainBoxSize );
cylinderX = boxMoveLeftTo ( boxCreate ( cylinderXSize ), mainBox [ixmax] );
cilindroY = cajaMoveFrontTo (
boxMoveBottomTo (
boxMoveLeftTo (
boxRotate (
cajaCrear ( cilindroTamaño )
, cylinderYRotation )
, cilindroX[ix] )
, cilindroX[iy] )
, cilindroX[iz]
);
color ("Blanco")
boxRenderCube ( mainBox );
color ("Rojo" )
cajaRenderCylinderX ( cilindroX );
color ("Verde" )
boxRenderConeBack ( cylinderY );
Example 2
Este guión genera estructuras más complejas con un código aún más simple:
// Prueba de algunos módulos
prueba =
boxRotate (
boxMoveTo (
boxRotate (
boxCreate ( [2, 10, 20] )
, [110,30,20]
)
, [10, 20, 30]
)
, [10,0,0]
)
;
testResized = boxResize ( test, 1 );
plano = cajaCrear ( [0.0001, 10, 10] );
diferencia() {
boxRenderCube( testResized );
boxRenderCube( boxResizeX ( test, 1 ) );
boxRenderCube( boxResizeY ( test, 1 ) );
boxRenderCube( boxResizeZ ( test, 1 ) );
}
cajaRenderCylinderX ( cajaResizeX ( prueba, 1 ), $fn=100 );
boxRenderCylinderY ( boxResizeY ( test, 1 ), $fn=100 );
cajaRenderCylinderZ ( cajaResizeZ ( prueba, 1 ), $fn=100 );
// boxRenderCylinderZ( test );
#Traducir( [ testResized [ixmax], testResized [iy], testResized [iz] ] )
rotar( [0,0,0] )
cajaRenderCube( plano );
#Traducir( [ testResized [ixmin], testResized [iy], testResized [iz] ] )
rotar( [0,0,0] )
cajaRenderCube( plano );
#Traducir( [ testResized [ix], testResized [iymax], testResized [iz] ] )
rotar( [0,0,90] )
cajaRenderCube( plano );
#Traducir( [ testResized [ix], testResized [iymin], testResized [iz] ] )
rotar( [0,0,90] )
cajaRenderCube( plano );
#Traducir( [ testResized [ix], testResized [iy], testResized [izmax] ] )
rotar( [0,90,0] )
cajaRenderCube( plano );
#Traducir( [ testResized [ix], testResized [iy], testResized [izmin] ] )
rotar( [0,90,0] ) cajaRenderCube( plano );