Superficies 3D


El programa de dibujo en 3D que proponemos tiene la capacidad de crear diversas superficies a partir de fórmulas matemáticas que dan el valor de la coordenada Z a partir de los valores de las coordenadas X e Y. Las Figuras 1, 2 3 y 4 muestran los resultados de cuatro fórmulas diferentes con distintos valores de resolución (número de valores calculados para filas y columnas).

1. Fórmulas.

Para ello se programarán cuatro funciones con los nombres f1, f2, f3 y f4 que reciban los valores de x e y, y devuelvan el valor de z correspondiente a cada una de las cuatro fórmulas que se muestran en la Figura anterior.

Función f1:

(defun f1 (x y /)
  (cos (sqrt (+ (* x x 2) (* y y)))))

Función f2:

(defun f2 (x y / )
  (sqrt (abs(* x y))))

Función f3:

( defun f3 (x y / )
  (* x y))

Función f4:

(defun f4 (x y / )
  (exp (- (+ (* x x) (* y y)))))

2. Función de CÁLCULO:

Programar una función de nombre calculo que reciba como argumentos:

Variable: Descripción: 
formula Valor devuelto por op-funcion (ver Apartado 3). 
Xmin Valor inicial de X (calculado en la función datos desarrollada en el Apartado 2). 
Ymin Valor inicial de Y (calculado en la función datos desarrollada en el Apartado 2). 
pasoX Incremento de X (calculado en la función datos desarrollada en el Apartado 2). 
pasoY Incremento de Y (calculado en la función datos desarrollada en el Apartado 2). 
res  Número de valores a calcular para las dimensiones X e Y (ver Apartado 2). 
origen Punto que indica la posición del centro de la malla (ver Apartado 2). 

A partir de estos datos se deberá:
  • Calcular los valores de Z para cada punto (Xi,j Yi,j)
  • Incrementar el valor de Xi,j e Yi,j de cada punto por los valores Xo e Yo de origen
  • acumule en una lista los valores XYZ resultantes para cada punto ((X0,0 Y0,0) (X0,1 Y0,1) (X0,2 Y0,3)… (Xi,j Yi,j))

Ejemplo:
Para los valores de

  • Xmin = -1.0
  • Ymin = -1.0
  • pasoX = 0.4
  • pasoY = 0.4
  • res = 5
  • origen = (0.0 0.0 0.0)
  • formula = F4

se obtiene la lista que se muestra a la derecha y que corresponde al modelo que muestra la Figura 5.

Figura 5. modelo con valores de coordenadas.







((-1.0 -1.0 0.135335)

(-1.0 -0.6 0.256661)
(-1.0 -0.2 0.353455)
(-1.0 0.2 0.353455)
(-1.0 0.6 0.256661)
(-0.6 -1.0 0.256661)
(-0.6 -0.6 0.486752)
(-0.6 -0.2 0.67032)
(-0.6 0.2 0.67032)
(-0.6 0.6 0.486752)
(-0.2 -1.0 0.353455)
(-0.2 -0.6 0.67032)
(-0.2 -0.2 0.923116)
(-0.2 0.2 0.923116)
(-0.2 0.6 0.67032)
(0.2 -1.0 0.353455)
(0.2 -0.6 0.67032)
(0.2 -0.2 0.923116)
(0.2 0.2 0.923116)
(0.2 0.6 0.67032)
(0.6 -1.0 0.256661)
(0.6 -0.6 0.486752)
(0.6 -0.2 0.67032)
(0.6 0.2 0.67032)
(0.6 0.6 0.486752))

La función calculo devolverá la lista devalores XYZ en su orden correcto.


(defun calculo  (formula Xmin Ymin pasoX pasoY res origen / lst)
  (setq i 0)
  (while (< i res)
    (setq j 0
          y Ymin)
    (while (< j res)
      (setq lst (cons (list (+ Xmin (nth 0 origen))
                            (+ y (nth 1 origen))
                            (apply formula (list Xmin y)))
                      lst))
      (setq j (1+ j)
            y (+ y pasoY)))
    (setq i    (1+ i)
          Xmin (+ Xmin pasoX)))
  (reverse lst))

3. Solicitud de los Valores de Entrada:

Programar una función de nombre datos que haga al usuario las siguientes preguntas:

Mensaje: Descripción: 
Tipo de Superficie [1/2/3/4]: El usuario tendrá la posibilidad de escoger entre las opciones 1, 2 3 o 4, no permitiéndose otras. El valor seleccionado por el usuario se guardará en una variable de cadena de nombre opcion. 
Dimensión en X: El usuario podrá introducir un número real que se guardará en la variable dimX. 
Dimensión en Y: El usuario podrá introducir un número real que se guardará en la variable dimY. 
Resolución de la malla: El usuario podrá introducir un número entero de valor entre 2 y 256 que se guardará en la variable res. 
Centro de la malla: El usuario podrá seleccionar un punto o teclear sus coordenadas. Este valor se  guardará en la variable origen. 

El programa debe impedir que el usuario introduzca valores no numéricos en el caso de valores para dimX, dimY o res. En el caso de res se debe impedir que los valores sean menores que 2 o mayores de 256. 
A partir de los datos aportados por el usuario se realizarán los siguientes cálculos cuyo resultado se asignará a las variables que se indican a la izquierda:

Variable: 

Cálculo: 

pasoX 
 
pasoY 
 
Xmin  
 
Ymin  
 

Todas las variables creadas por la función datos serán de carácter global, es decir que estarán disponibles para cualquier otra función dentro del programa.

(defun datos  (/)
  (initget 1 "1 2 3 4")
  (setq opcion (getkword "\nTipo de Superficie [1/2/3/4]: ")
        dimX   (getreal "\nDimensión en X: ")
        dimY   (getreal "\nDimensión en Y: ")
        res    (getint "\nResolución de la malla: "))
  (while (not (< 1 res 257))
    (prompt "\nEl valor de resolución debe estar entre 2 y 256")
    (setq res (getint "\nResolución de la malla: ")))
  (setq origen (getpoint "\nCentro de la malla: ")
        pasoX  (/ dimX res)
        pasoY  (/ dimY res)
        Xmin   (- (/ dimX 2))
        Ymin   (- (/ dimY 2))))

4. Elección del tipo de fórmula a aplicar:

Programar una función de nombre op-funcion que reciba como argumento el valor asignado a la variable opcion en la pregunta anterior y devuelva una función (dentro de quote). Los valores que serán devueltos son:

Opción: Función Devuelta 
"1" F1 
"2"F2 
"3"  F3 
"4" F4 

(defun op-formula  (opcion /)
  (cond ((= opcion "1") 'f1)
        ((= opcion "2") 'f2)
        ((= opcion "3") 'f3)
        ((= opcion "4") 'f4)))

5. Dibujo de la Malla 3D:

Programar una función que dibuje una 3DMalla (3DMesh) recibiendo como argumentos el valor de la resolución (res) y la lista de coordenadas de los vértices de la malla resultante de la función calculo. Una 3DMALLA se define a partir de una matriz cuyo tamaño viene determinado por los valores M y N. El producto de M por N equivale al número de vértices que el usuario debe especificar.
La ejecución de este comando sigue la siguiente secuencia:

Comando: 3dmalla 
Indique tamaño de la malla en la dirección M: (un valor entre 2 y 256) 
Indique tamaño de la malla en la dirección N: (un valor entre 2 y 256)
Indique la situación del vértice (0, 0): (un valor de punto con coordenadas XYZ)
… y así sucesivamente para cada vértice (i, j)

La situación de cada vértice de la malla se define a partir de los índices i, j, los índices de fila y columna del vértice. Se deben suministrar todos los valores para la fila i antes de especificar los de la fila i+1. La distancia entre vértices puede ser variable y la orientación de la malla depende de la ubicación de los vértices.

(defun dib-malla (res lista-coordenadas / )
  (command "_3dmesh" res res)
  (foreach pto lista-coordenadas (command pto)))

Función Principal C:MALLA:

Programar una función principal de nombre C:MALLA que opere como un comando de AutoCAD en que:
  • Desactive las referencias a objeto al inicio del programa y las restaure al final del mismo.
  • Invoque la función datos (desarrollada en el Apartado 2) para solicitar al usuario la información necesaria para la ejecución del programa.
  • Invoque la función calculo para obtener la lista de coordenadas para todos los vértices.
  • Invoque la función dib-malla que crea el modelo de superficie.
  • Anule todas las variables globales creadas por la función datos (de la Pregunta 2). Al terminar el programa sus valores serán todos nil.

(defun c:malla  (/ dimX dimY res origen pasoX pasoY Xmin Ymin  lista-coordenadas)
  (setq modoant (getvar "osmode"))
  (setvar "osmode" 0)
  (datos)
  (setq lista-coordenadas
         (calculo (op-formula opcion)
                  Xmin
                  Ymin
                  pasoX
                  pasoY
                  res
                  origen))
  (dib-malla res lista-coordenadas)
  (setvar "osmode" modoant))

Ejercicio de examen propuesto el 22 de julio de 2007. Está basado en el programa FPLOT, diseñado e implementado por Kelvin R. Throop en junio de 1988.
Reinaldo Togores Fernández,
21 feb 2011, 20:23
v.8
Reinaldo Togores Fernández,
21 feb 2011, 20:14
v.8