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,1ClsPrint "Pulsa:"Print Print "AD -----> Eje X."Print "WS -----> Eje Y."Print "QE -----> Eje Z."PrintPrint "NM -----> Abre/Cierra Mano."PrintPrint "Flechas -> Mueve el Escenario."PrintPrint "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 DibujaBrazoDeclare Sub InversekDeclare Sub Teclas'-------- Declaración de variables ------------Dim Shared As String TeclaDim Shared As Double Pi, Rad, Grad, PausaDim Shared As Integer LongBrazo, LongAntBr, LongDedosDim Shared As Double AnguloDim 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) * 4Rad = Pi / 180Grad = 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/100LAntBr = LongAntBr/100 ' Equivalente en dimensiones de OpenGL. LDedos = LongDedos/100 ' No tocar aquí.MDedos = .11 Dist = .0EscenaX= 0EscenaY= 15EscenaZ= -8'------ Config. de OpenGL -----------------Screen 12, 16, , 2WindowTitle "Brazo Cilindrico"glViewport 0, 0, 640, 480glMatrixMode GL_PROJECTIONglLoadIdentitygluPerspective 45.0, 640.0/480.0, 0.1, 255.0glMatrixMode GL_MODELVIEWglLoadIdentityglShadeModel GL_FLATglClearColor 0.0, 0.0, 0.0, 0.5glClearDepth 1.0glEnable GL_DEPTH_TESTglDepthFunc GL_LEQUALglHint GL_PERSPECTIVE_CORRECTION_HINT, GL_NICESTglBlendFunc GL_SRC_ALPHA, GL_ONE glEnable GL_TEXTURE_2D'-=-=-=- Programa Principal -=-=-=-While (1) Teclas Inversek DibujaBrazo WendSub 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 EndIfEnd SubSub Inversek MHorizont = ( Sqr( (EjeX*EjeX) + (EjeY*EjeY) ) /100 ) - LDedos Angulo = ( Atan2(EjeY, EjeX) * Grad ) MVertical = EjeZ/100 MDedos =(EjeD/100)+.057End SubSub 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