Brazo Cilíndrico

El brazo cilíndrico es uno de los más sencillo de calcular. Si conocemos los ejes XYZ, tomamos las variables X e Y para saber el resto de parámetros; el eje Z no interviene en el cálculo porque es en sí mismo un resultado. Necesitamos calcular el ángulo de giro y el módulo (o también llamado radio). Esto nos recuerda al "sistema polar" visto el brazo desde arriba.

El ángulo lo obtendremos de esta manera:

Angulo = Atan2 ( Y, X )

Para conocer el módulo (o también llamado radio) aplicamos el triángulo de Pitágoras:

Modulo = Sqr ( (X*X) + (Y*Y) )

Recuerda que en todos los lenguajes de programación los resultados de las funciones trigonométricas son en radianes. Para saber el ángulo sexagesimal has de multiplicar el resultado por 180/pi.

Cliquea aquí para bajarte el código fuente y el ejecutable en el que se simula en 3D un brazo cilíndrico muy básico.

(Si usas antivirus Avast has de añadir una exclusión para poder ejecutarlo. Para analizar este o cualquier otro archivo puedes hacer clic aquí)

El programa con implementación de OpenGL:

The translation could modify the code. Use the code without translating or download the program by clicking the link above.
Color 14,1
Cls
Print "Pulsa:"
Print 
Print "AD -----> Eje X."
Print "WS -----> Eje Y."
Print "QE -----> Eje Z."
Print
Print "NM -----> Abre/Cierra Mano."
Print
Print "Flechas -> Mueve el Escenario."
Print
Print "Pulsa Esc. para salir"
#Include Once "GL/gl.bi"
#Include Once "GL/glu.bi"
#Include Once "GL/glut.bi"
#Include Once "fbgfx.bi"                   
#Include Once "createtex.bi"
Declare Sub DibujaBrazo
Declare Sub Inversek
Declare Sub Teclas
'-------- Declaración de variables ------------
Dim Shared As String    Tecla
Dim Shared As Double    Pi, Rad, Grad, Pausa
Dim Shared As Integer   LongBrazo, LongAntBr, LongDedos
Dim Shared As Double    Angulo
Dim Shared As Single    MVertical, MHorizont
                       
Dim Shared As Single    LBrazo, LAntBr, LDedos, Dist,_
                        MDedos, Espacio,_
                        EscenaY, EscenaX, EscenaZ
                       
Dim Shared As Integer   EjeX, EjeY, EjeZ, EjeD
'------------Carga de Variables--------------------
Pi   = Atn(1) * 4
Rad  = Pi  / 180
Grad = 180 /  Pi
'-=- Ajustes del Brazo: Dimensiones, EscenaZs, etc. -=-
LongBrazo  = 300     ' Altura del Hombro. (Distancia del suelo hasta la base del hombro.)
LongAntBr  = 300     ' Longitud Brazo.     
LongDedos  =  50     ' Longitud Dedos.
EjeX=( 100)          ' Posición Inicial X.  Aquí damos las coordenadas iniciales de la punta del brazo.
EjeY=(-100)          ' Posición Inicial Y.  Se puede modificar los valores que
                     ' están dentro del paréntesis.
EjeZ=( 100)          ' Procura que esté dentro del área de trabajo.
EjeD=(   0)          ' Pinzas cerradas para comenzar.
'--- No tocar los valores de estas variables ---
LBrazo     = LongBrazo/100
LAntBr     = LongAntBr/100   ' Equivalente en dimensiones de OpenGL. 
LDedos     = LongDedos/100   ' No tocar aquí.
MDedos  = .11 
Dist    = .0
EscenaX=   0
EscenaY=  15
EscenaZ=  -8
'------ Config. de OpenGL -----------------
Screen 12, 16, , 2
WindowTitle "Brazo Cilindrico"
glViewport 0, 0, 640, 480
glMatrixMode GL_PROJECTION
glLoadIdentity
gluPerspective 45.0, 640.0/480.0, 0.1, 255.0
glMatrixMode GL_MODELVIEW
glLoadIdentity
glShadeModel GL_FLAT
glClearColor 0.0, 0.0, 0.0, 0.5
glClearDepth 1.0
glEnable GL_DEPTH_TEST
glDepthFunc GL_LEQUAL
glHint GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST
glBlendFunc GL_SRC_ALPHA, GL_ONE         
glEnable GL_TEXTURE_2D
'-=-=-=- Programa Principal -=-=-=-
While (1)
     Teclas
     Inversek
     DibujaBrazo   
Wend
Sub Teclas
     Tecla=InKey()
  
     If Tecla=Chr(27) or Tecla=Chr(255)+"k" Then End
  
     If MultiKey(SC_LSHIFT) Then 
         
        If LCase(Tecla)="a"   Then EjeX=EjeX-1
        If LCase(Tecla)="d"   Then EjeX=EjeX+1
        If LCase(Tecla)="s"   Then EjeY=EjeY-1
        If LCase(Tecla)="w"   Then EjeY=EjeY+1
        If LCase(Tecla)="e"   Then EjeZ=EjeZ-1
        If LCase(Tecla)="q"   Then EjeZ=EjeZ+1
           
     Else 
                 
        If MultiKey(SC_A)     Then EjeX=EjeX-1
        If MultiKey(SC_D)     Then EjeX=EjeX+1
        If MultiKey(SC_S)     Then EjeY=EjeY-1
        If MultiKey(SC_W)     Then EjeY=EjeY+1
        If MultiKey(SC_E)     Then EjeZ=EjeZ-1
        If MultiKey(SC_Q)     Then EjeZ=EjeZ+1
              
        If LCase(Tecla)="m"   Then 
           If EjeD>0  Then   EjeD=EjeD-1
        EndIf
                  
        If LCase(Tecla)="n"   Then 
           If EjeD<40 Then   EjeD=EjeD+1
        EndIf
               
     EndIf
End Sub

Sub Inversek
        
     MHorizont = ( Sqr( (EjeX*EjeX) + (EjeY*EjeY) ) /100 ) - LDedos

     Angulo    = ( Atan2(EjeY, EjeX) * Grad )

  MVertical = EjeZ/100

  MDedos    =(EjeD/100)+.057
End Sub

Sub DibujaBrazo
       
        Dim As Single ContX, ContY
 
        If MultiKey(SC_LSHIFT) Then
            If MultiKey (SC_LEFT)     Then EscenaX = EscenaX-.05
            If MultiKey (SC_RIGHT)    Then EscenaX = EscenaX+.05
            If MultiKey (SC_UP)       Then EscenaY = EscenaY+.05
            If MultiKey (SC_DOWN)     Then EscenaY = EscenaY-.05
            If MultiKey (SC_PAGEUP)   Then EscenaZ = EscenaZ+.01
            If MultiKey (SC_PAGEDOWN) Then EscenaZ = EscenaZ-.01
        Else
            If MultiKey (SC_LEFT)     Then EscenaX = EscenaX-.5
            If MultiKey (SC_RIGHT)    Then EscenaX = EscenaX+.5
            If MultiKey (SC_UP)       Then EscenaY = EscenaY+.5
            If MultiKey (SC_DOWN)     Then EscenaY = EscenaY-.5
            If MultiKey (SC_PAGEUP)   Then EscenaZ = EscenaZ+.1
            If MultiKey (SC_PAGEDOWN) Then EscenaZ = EscenaZ-.1
        EndIf
       
        If MultiKey (SC_F7) Then 
            EscenaX =  -0
            EscenaY =  15
            EscenaZ = -11
        EndIf
         ' ----------------------Animación OpenGL--------------------
         glClear(GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT)  
         glLoadIdentity 
         '-------------- Plano Base ---------------
         glTranslatef       0.0, 0.0, EscenaZ              
         glRotatef EscenaX, 0.0, 1.0, 0.0
         glRotatef EscenaY, 1.0, 0.0, 0.0
         For ContY=0 To 4 Step .5
                For ContX=0 To 4 Step .5
                       glColor3f   1.0,   1.0,   1.0
  
                       glBegin(GL_LINE_LOOP)
                             glVertex3f  ContX, 0,  ContY     
                             glVertex3f -ContX, 0,  ContY      
                             glVertex3f -ContX, 0, -ContY      
                             glVertex3f  ContX, 0, -ContY      
                       glEnd
                Next
         Next
      '------ Movimiento Vertical -------
      glTranslatef    0.0, 0.0, 0.0        
      glRotatef Angulo, 0.0, 1.0, 0.0
  
      glBegin(GL_QUADS)
          '  glColor3f   0.1,  0.2,  0.4                       
          '  glVertex3f  0.3,  0.0, -0.3                  
          '  glVertex3f -0.3,  0.0, -0.3                   
          '  glVertex3f -0.3,  0.0,  0.3               
          '  glVertex3f  0.3,  0.0,  0.3                
   
          '  glColor3f   0.2,  0.2,  0.4                
          '  glVertex3f  0.3, LBrazo,  0.3               
          '  glVertex3f -0.3, LBrazo,  0.3                    
          '  glVertex3f -0.3, LBrazo, -0.3                   
          '  glVertex3f  0.3, LBrazo, -0.3                     
   
            glColor3f   0.2,  0.1,  0.4                      
            glVertex3f  0.3,  0.0,  0.3                    
            glVertex3f -0.3,  0.0,  0.3                      
            glVertex3f -0.3, LBrazo,  0.3   
            glVertex3f  0.3, LBrazo,  0.3          
   
            glColor3f   0.2,  0.1,  0.4                 
            glVertex3f  0.3, LBrazo, -0.3             
            glVertex3f -0.3, LBrazo, -0.3             
            glVertex3f -0.3,  0.0, -0.3                 
            glVertex3f  0.3,  0.0, -0.3                 
   
            glColor3f   0.2,  0.2,  0.5                 
            glVertex3f -0.3,  0.0,  0.3                 
            glVertex3f -0.3,  0.0, -0.3                 
            glVertex3f -0.3, LBrazo, -0.3             
            glVertex3f -0.3, LBrazo,  0.3             
   
            glColor3f   0.2,  0.2,  0.5                 
            glVertex3f  0.3,  0.0, -0.3                 
            glVertex3f  0.3,  0.0,  0.3       
            glVertex3f  0.3, LBrazo,  0.3   
            glVertex3f  0.3, LBrazo, -0.3
       glEnd()
      
       '----- Movimiento Horizontal -----
       glTranslatef    MHorizont, MVertical, -Dist
       glBegin(GL_QUADS) 
            glColor3f  0.5,  0.1,  0.2
            glVertex3f -LAntBr,  0.3, -0.3                           
            glVertex3f 0.0,  0.3, -0.3                          
            glVertex3f 0.0,  0.3,  0.3                        
            glVertex3f -LAntBr,  0.3,  0.3       
   
            glColor3f  0.5,  0.1,  0.2        
            glVertex3f -LAntBr, -0.3,  0.3              
            glVertex3f 0.0, -0.3,  0.3                     
            glVertex3f 0.0, -0.3, -0.3                     
            glVertex3f -LAntBr, -0.3, -0.3                   
   
            glColor3f  0.5,  0.2,  0.1                  
            glVertex3f -LAntBr,  0.3,  0.3                
            glVertex3f 0.0,  0.3,  0.3                         
            glVertex3f 0.0, -0.3,  0.3                 
            glVertex3f -LAntBr, -0.3,  0.3           
   
            glColor3f  0.5,  0.2,  0.1           
            glVertex3f -LAntBr, -0.3, -0.3             
            glVertex3f 0.0, -0.3, -0.3            
            glVertex3f 0.0,  0.3, -0.3             
            glVertex3f -LAntBr,  0.3, -0.3            
   
            'glColor3f  0.6,  0.2,  0.2              
            'glVertex3f 0.0,  0.3,  0.3                     
            'glVertex3f 0.0,  0.3, -0.3            
            'glVertex3f 0.0, -0.3, -0.3                
            'glVertex3f 0.0, -0.3,  0.3                   
 
            'glColor3f  0.6,  0.1,  0.3                
            'glVertex3f -LAntBr,  0.3, -0.3                   
            'glVertex3f -LAntBr,  0.3,  0.3          
            'glVertex3f -LAntBr, -0.3,  0.4
            'glVertex3f -LAntBr, -0.3, -0.3  
       glEnd()
'--------------Dedos------------------
       glTranslatef  0.0, 0.0, MDedos
       glBegin(GL_QUADS)
           glColor3f   0.0,  0.6,  0.5
           glVertex3f  LDedos,  0.1, -0.05
           glVertex3f  0.0,     0.1, -0.05
           glVertex3f  0.0,     0.1,  0.05
           glVertex3f  LDedos,  0.1,  0.05
           glColor3f   0.0,  0.8,  0.4
           glVertex3f  LDedos, -0.1,  0.05
           glVertex3f  0.0,    -0.1,  0.05
           glVertex3f  0.0,    -0.1, -0.05
           glVertex3f  LDedos, -0.1, -0.05
           glColor3f   0.0,  0.5,  0.3
           glVertex3f  LDedos,  0.1,  0.05
           glVertex3f  0.0,     0.1,  0.05
           glVertex3f  0.0,    -0.1,  0.05
           glVertex3f  LDedos, -0.1,  0.05
           glColor3f   0.0,  0.4,  0.4
           glVertex3f  LDedos, -0.1, -0.05
           glVertex3f  0.0,    -0.1, -0.05
           glVertex3f  0.0,     0.1, -0.05
           glVertex3f  LDedos,  0.1, -0.05
          'glColor3f   0.0,  0.3,  0.5
          'glVertex3f  0.0,  0.1,  0.05
          'glVertex3f  0.0,  0.1, -0.05
          'glVertex3f  0.0, -0.1, -0.05
          'glVertex3f  0.0, -0.1,  0.05
           glColor3f   0.0,  0.2,  0.6
           glVertex3f  LDedos,  0.1, -0.05
           glVertex3f  LDedos,  0.1,  0.05
           glVertex3f  LDedos, -0.1,  0.05
           glVertex3f  LDedos, -0.1, -0.05
     glEnd()
     
     glTranslatef  0.0, 0.0, MDedos*(-2)  ' En esta posición, 'MDedos*(-2)
                                          ' invierte la posición 'MDedos' de arriba. 
     glBegin(GL_QUADS)
           glColor3f   0.0,  0.6,  0.5
           glVertex3f  LDedos,  0.1, -0.05
           glVertex3f  0.0,     0.1, -0.05
           glVertex3f  0.0,     0.1,  0.05
           glVertex3f  LDedos,  0.1,  0.05
           glColor3f   0.0,  0.8,  0.4
           glVertex3f  LDedos, -0.1,  0.05
           glVertex3f  0.0,    -0.1,  0.05
           glVertex3f  0.0,    -0.1, -0.05
           glVertex3f  LDedos, -0.1, -0.05
           glColor3f   0.0,  0.5,  0.3
           glVertex3f  LDedos,  0.1,  0.05
           glVertex3f  0.0,     0.1,  0.05
           glVertex3f  0.0,    -0.1,  0.05
           glVertex3f  LDedos, -0.1,  0.05
           glColor3f   0.0,  0.4,  0.4
           glVertex3f  LDedos, -0.1, -0.05
           glVertex3f  0.0,    -0.1, -0.05
           glVertex3f  0.0,     0.1, -0.05
           glVertex3f  LDedos,  0.1, -0.05
          'glColor3f   0.0,  0.3,  0.5
          'glVertex3f  0.0,  0.1,  0.05
          'glVertex3f  0.0,  0.1, -0.05
          'glVertex3f  0.0, -0.1, -0.05
          'glVertex3f  0.0, -0.1,  0.05
           glColor3f   0.0,  0.2,  0.6
           glVertex3f  LDedos,  0.1, -0.05
           glVertex3f  LDedos,  0.1,  0.05
           glVertex3f  LDedos, -0.1,  0.05
           glVertex3f  LDedos, -0.1, -0.05
     glEnd()
     Flip    '<----- Muestra el gráfico por pantalla ------<
     
     sleep 5 ' Una pausa de 5 milisegundos para que se mueva a una velocidad adecuada. 
End Sub