You are on page 1of 180

http://www.emagdalena.

es/2012/10/06/
Introduccin a la programacin en AutoCAD
Tabla de contenidos de Introduccin a la programacin en AutoCAD
1. Primeros pasos con AutoLISP
2. Las variables en AutoLISP
3. Operaciones matemticas bsicas
4. Solicitar nmeros al usuario
5. Funciones de usuario y nuevos comandos
6. Introduccin al entorno de Visual LISP
7. Cargar los archivos de AutoLISP
8. Operaciones matemticas en AutoLISP
9. Solicitar textos y puntos al usuario
10. Funciones para manejar listas
11. Ejecutar comandos de AutoCAD
12. Operaciones de comparacin
13. Operaciones lgicas en AutoLISP
14. Estructuras condicionales simples
15. Estructuras condicionales mltiples
16. Mostrar textos al usuario en AutoLisp
17. Las variables de sistema de AutoCAD
18. Funciones de conversin de datos en AutoLISP
19. Obtener distancias y ngulos del usuario
20. El comando deshacer en las rutinas de AutoLISP
21. Funciones de tratamiento de errores en AutoLISP
22. Limitar las respuestas de los usuarios
23. Limitar las respuestas de los usuarios (II)
24. Estructuras repetitivas: Bucles
25. Funciones para manipular cadenas de texto
26. Trabajar con ngulos y distancias
27. Funciones avanzadas para manejar listas
28. Aplicar funciones a los elementos de una lista
29. Literales y otras funciones de utilidad
30. Carga automtica de los archivos de AutoLISP
31. Operaciones con archivos
32. Leer y escribir archivos de texto
Primeros pasos con AutoLISP
Objetivos del curso
Aprovechando que actualmente dispongo de algo ms de tiempo, me he decidido a
desempolvar y re-editar algn curso que he creado hace ya bastante tiempo, tratar de
actualizar el contenido para que funcione con las ltimas versiones de AutoCAD.
Con este curso no se pretende formar a expertos programadores. Ms bien, se pretende
acercar el lenguaje de programacin AutoLISP a los usuarios de AutoCAD, para que
puedan crear utilidades y pequeas aplicaciones que les ahorren tiempo y clculos en sus
trabajos.
Para seguir el curso no son necesarios conocimientos de programacin, tan slo es
preciso tener unas nociones bsicas de AutoCAD y del entorno Windows.
Otro de los objetivos del curso es el de ver a AutoCAD no como un programa de dibujo,
sino como una potente base de datos grficos. Y descubrir como funciona esa base de
datos.
Cdigo de una macro en AutoLISP
Merece la pena aprender a programar
sobre AutoCAD
Desde luego que puede merecer la pena. Puede agilizar y facilitar enormemente el
trabajo con AutoCAD.
Puede que existan en el mercado aplicaciones de diseo mucho ms potentes para
trabajar en 3D de forma paramtrica, como SolidWorks o Catia, pero AutoCAD se sigue
utilizando habitualmente en infinidad de aplicaciones. Para trabajar en 2D sigue siendo
la aplicacin de CAD de referencia y su formato de archivo .DWG es un estndar en la
importacin y exportacin de archivos convirtindose en uno de los formatos de archivo
ms utilizados para intercambiar partes de un diseo con clientes, proveedores y
colaboradores.
AutoLISP es un lenguaje sencillo de aprender y a diferencia de otros lenguajes de
programacin se pueden crear programas interesantes y realmente tiles casi
desde el primer momento.
Muchas veces, la mayora del tiempo empleado en crear una macro o programa se
emplea en depurar el cdigo (corregir errores). La planificacin y el anlisis previo de la
macro es de suma importancia para evitarlo. El primer paso para escribir una macro
consiste en escribir en un papel con un lenguaje simple lo que se desea que realice el
programa, a esto se le denomina pseudocdigo. Un mtodo algo ms avanzado y eficaz
es utilizar diagramas de flujo.
Cuando ya empieces a programar en AutoLISP por ti solo, te ser muy til reunir todas
las anotaciones sobre proyectos de aplicaciones y macros en una libreta o bloc de
notas. Tambin puedes utilizar Evernote o cualquier otro sistema que te permita
almacenar de informacin o gestionar las macros que has creado.
Interfaces de programacin
AutoCAD dispone varios entornos de programacin, la seleccin del tipo de interfaz a
emplear para crear una aplicacin depender de las necesidades de la aplicacin y de la
experiencia o conocimientos del programador/es:
AutoLISP es una adaptacin del lenguaje de programacin CommonLISP para
AutoCAD. Es sencillo de aprender y al mismo tiempo potente. AutoCAD cuenta con
un intrprete interno de LISP que permiteintroducir cdigo desde la lnea de
comandos o cargar programas desde archivos externos. Puedes utilizar AutoLISP
para automatizar tareas repetitivas y crear nuevos comandos de AutoCAD
ActiveX Automation constituye una alternativa moderna al AutoLISP. Puedes
acceder y controlar objetos de AutoCAD desde cualquier aplicacin que utilice un
controlador Automation como Visual Basic y Delphi, o cualquiera de las aplicaciones
que dispongan de Visual Basic for Applications (VBA)
VBA es un entorno de programacin basado en objetos que utiliza ntegramente la
sintaxis del lenguaje Visual Basic y permite usar controles ActiveX. Permite tambin
la integracin con otras aplicaciones que utilizan VBA como MS Office o MS Project.
Las ediciones de desarrollo de MS Visual Basic, que se adquieren por separado,
complementan AutoCAD VBA con componentes adicionales como un dispositivo
externo de base de datos y funcionalidades de escritura de informes
ObjectARX es un entorno de programacin de lenguaje compilado para el
desarrollo de aplicaciones de AutoCAD. El entorno de programacin ObjectARX
incluye varias bibliotecas de vnculos dinmicos (DLL) que ofrecen acceso directo a
las estructuras de la base de datos, el sistema de grficos y los dispositivos de
geometra de AutoCAD
De momento nos centraremos en la programacin sobre AutoCAD utilizando el
interprete interno de AutoLISP para pasar en breve al entorno de Visual LISP y
posteriormente a la programacin en VBA.
Caractersticas de AutoLISP
El LISP fue desarrollado a finales de los aos 50 por John McCarthy, es el segundo
lenguaje de programacin ms antiguo solo precedido por Fortran. Uno de los campos
en los que es ms empleado es en la investigacin en inteligencia artificial. Su nombre
proviene de LISt Procesing (Procesado de listas), pues se basa en el uso de listas en
lugar de datos numricos. Aunque hay quien mantiene en tono jocoso que su nombre
proviene de Lost In Stupid Parenthesis.
AutoLISP aade al LISP algunas funciones especialmente diseadas para la
manipulacin de las entidades de AutoCAD.
AutoLISP es un lenguaje evaluado. El cdigo se convierte a lenguaje mquina (ceros
y unos) y se almacena en la memoria temporal. No es tan lento como los lenguajes
interpretados, ni tan rpido como los compilados:
en los lenguajes interpretados, se va traduciendo el programa a cdigo mquina
(el idioma de los ordenadores) a medida que se ejecuta
en los lenguajes compilados, el cdigo fuente (texto) del programa se traduce a
cdigo mquina generando un archivo ejecutable (.EXE) que es el que ejecutar el
programa
Hay quien dice que AutoLISP es lento comparndolo con otros lenguajes como Pascal o
C, especialmente cuando se utilizan muchas funciones matemticas. Sin embargo,
cuando se utiliza manipulando smbolos los resultados son muy distintos. Esto hace de
AutoLISP un excelente lenguaje para la programacin de sistemas CAD, ya que un
sistema CAD no es ms que un entorno de manipulacin de smbolos grficos.
Una de las caractersticas ms importantes de AutoLISP es la posibilidad de acceder a
la base de datos de los dibujos de AutoCAD. Donde podemos acceder a las capas,
estilos de texto, sistemas de coordenadas personales (SCP) as como a todas las
entidades del dibujo. Esta informacin se puede modificar, extraer e incluso aadir ms
entidades al dibujo o informacin adicional.
La mayora de los primeros lenguajes de programacin de alto nivel como C o Pascal
son lenguajes procedimentales, se ejecutan una serie de instrucciones paso a paso a
partir de unos datos. En AutoLISP en lugar de seguir instrucciones prefijadas, se
puede acceder a la informacin de los objetos de AutoCAD para determinar de que
informacin se dispone, preguntndole a los objetos por ellos mismos.
AutoLISP no es estrictamente un lenguaje orientado al objeto, pero contiene
bastantes caractersticas de estos tipos de lenguajes debido a que puede
interactuar con los objetos contenidos en los dibujos.
AutoLISP permite crear nuevos comandos para AutoCAD, que se ejecuten como
cualquier otra orden. Es posible incluso redefinir los comandos de AutoCAD para que
funcionen de forma distinta, por ejemplo podramos redefinir el comando POLIGONO
para que dibuje polgonos estrellados en lugar de los regulares.
Una mencin especial merece el uso de AutoLISP en la realizacin de programas
paramtricos y en eldiseo semiautomtico, ya que entre el 60% y el 80% del diseo
est dedicado a la modificacin de diseos previos. En los programas paramtricos, el
usuario introduce una serie de datos o parmetros a partir de los cuales el programa
realiza el diseo completo de un elemento u objeto. Esta puede ser sin ninguna duda
una de las mayores aplicaciones de AutoLISP.
AutoLISP se ha mejorado con la creacin de Visual LISP que ofrece un entorno de
desarrollo integrado dentro de AutoCAD.
Visual LISP incluye un compilador, un depurador y diversas utilidades para
facilitar la programacin.
Adems aade nuevos comandos para permitir la interaccin con objetos que
utilizan ActiveX. Otra de las novedades que aporta Visual LISP son los reactores de
objetos que permiten que AutoLISP responda a eventos.
En los dos primeros captulos del curso se trabajar desde la ventana de comandos de
AutoCAD. A partir del tercer captulo ya crearemos nuestras macros en archivos de texto
utilizando el entorno de Visual LISP proporcionado por AutoCAD.
Existen dos inconvenientes al emplear AutoLISP desde la ventana de comandos de
AutoCAD:
en primer lugar el reducido espacio con el que se cuenta en la ventana de
comandos de AutoCAD y la dificultad que supone el no tabular el cdigo, es decir
escribir el cdigo todo seguido. Esto es debido a que cada vez que se pulsa Intro,
AutoCAD evala lo que se ha escrito
en segundo lugar, al terminar la sesin de trabajo en AutoCAD se perdern todos
los datos almacenados en la memoria temporal
Expresiones y procedimientos de
evaluacin
Un programa en AutoLISP consiste en una serie de expresiones del tipo (funcin
argumentos).
Cada expresin comienza con un parntesis de apertura al que sigue el nombre de
una funcin de AutoLISP (o una funcin creada por el usuario) y una serie
de argumentos (a veces opcionales) que dependen de la funcin indicada y
van separados por al menos un espacio en blanco. Cada expresin termina con
un parntesis de cierre, esto es muy importante pues el nmero de parntesis de
apertura debe ser igual al de cierre.
Cada expresin de AutoLISP devuelve un valor.
Un argumento tambin puede ser una expresin, crendose as una estructura
formada por expresiones (listas) anidadas unas dentro de otras; de modo que la ms
interior devolver su resultado como un argumento a la lista exterior.
Cuando existen listas anidadas (unas dentro de otras), primero se evalan las ms
interiores.
Los primeros ejemplos que vamos a ver son sencillos y cortitos, as que puedes
teclearlos directamente en la ventana de comandos de AutoCAD.
Ejemplo:
(+ 1 2) Ejecuta la funcin + que realiza la suma de los argumentos 1 y 2 devuelve el
resultado 3.
(+ 31 22 -3) Ejecuta la funcin + que realiza la suma de los argumentos 31, 22 y -
3 devuelve el resultado 50.
Prueba tambin:
(- 17 2)
(+ 2.5 22.8)
(- 0.25 22.5)
(+ 12 -2 31 -7.5)
Ejemplo:
(+ (* 2 3) 2) devuelve 8. Recuerda que primero evala la lista interior y devuelve su
resultado a la exterior.
(+ 7 (/ 5.0 2) -3) devuelve 6.5.
Qu sucedera si al escribir la expresin (+ 1 (/ 5.0 2)) nos olvidsemos de escribir el
ltimo parntesis? Haz la prueba, veras que AutoCAD te indica que falta 1 parntesis de
cierre.
Si el interprete de comandos de AutoCAD encuentra un parntesis de apertura, supone
que todo lo que vaya a continuacin hasta el parntesis de cierre es una expresin de
AutoLISP. De modo que enva esa expresin al interprete de AutoLISP para que la
evale.
En el siguiente captulo veremos algunas de las operaciones matemticas que se
pueden realizar con AutoLISP.
Tipos de objetos y datos
Los elementos de las expresiones de AutoLISP pueden ser smbolos, valores concretos
y tambin otras expresiones. Se pueden distinguir los siguientes tipos de elementos:
Smbolos: Cualquier elemento que no sea un valor concreto. Por ejemplo una
variable, una funcin
Enteros: Nmeros enteros comprendidos entre -32000 y 32000
Reales: Nmeros reales (180 es un nmero entero, pero 180.0 es un nmero real)
Cadenas de texto: Texto con una longitud mxima de 132 caracteres
Descriptores de archivo: Representan un archivo de texto ASCII abierto
Nombres de entidades de AutoCAD: Nombre en hexadecimal de una entidad del
dibujo
Conjuntos designados por el usuario: Conjuntos de entidades de AutoCAD
Funciones de usuario: Funciones definidas por el usuario
Funciones de AutoLISP: Funciones o comandos predefinidos de AutoLISP
Ejemplo:
(+ 5 2) devuelve 7.
(+ 5 2.0) devuelve 7.0.
En el primer caso todos los argumentos son nmeros enteros, y el resultado de su suma
es un nmero entero. En el segundo caso, tenemos un nmero real, as que el resultado
es un nmero real. Para que comprendas la importancia de esta distincin, realiza el
siguiente ejemplo:
(/ 5 2)
(/ 5 2.0)
Una de las mayores virtudes de AutoLISP es que pueden ejecutarse expresiones en
medio de un comando de AutoCAD.
Ejemplo:
Ejecuta el comando LINEA e indica el primer punto, activa el forzado ortogonal (F8) y
teclea (+ 11 25)Esto devuelve el resultado de la suma al comando que se estaba
ejecutando. Por eso dibuja una lnea de 36 mm de longitud en la direccin que indicaba
el cursor.
Prueba ahora indicando el radio de la circunferencia (- 70 25) al utilizar el comando
llamado CIRCULO (mal llamado, pues debera ser circunferencia).
Podemos emplear tambin la constante PI = 3.14159 para realizar clculos. Por
ejemplo, ejecuta de nuevo el comando CIRCULO y cuando pregunte el radio de la
circunferencia, teclea (/ 6 (* 2 PI)). Obtendremos una circunferencia de permetro 6.
Notacin empleada
Para describir las funciones de AutoLISP que se expliquen a lo largo del curso se
seguir la siguiente notacin:
(FUNCIN Argumentos_necesarios [Argumentos_opcionales] )
Los nombres de las funciones de AutoLISP y el cdigo a teclear se mostrarn en negrita.
Convenciones recomendadas
En este apartado se indicarn una serie de convenciones recomendables a la hora de
programar. Alguna de ellas puede que an no las entiendas, pero no te preocupes
porque las iremos recordando a medida que avancemos en el curso.
para los comentarios incluidos en el cdigo, se recomienda utilizar el siguiente
mtodo:
o ;;; Antes del cdigo de las funciones, explicando su funcionamiento
o ;; En medio del cdigo del programa
o ; Para explicar una lnea de cdigo. A diferencia de las anteriores, esta no
se inserta en la columna 1, se insertar al terminar el cdigo de la lnea que
comenta
es muy recomendable utilizar un formato tabulado para el cdigo
evitar el uso de variables globales innecesarias
utilizar los comandos de AutoCAD y sus opciones en Ingls y precedidos por ._
no abusar de la funcin SETQ
no utilizar T, MIN, MAX, LAST como smbolos (nombres de variables y funciones)
recuperar el valor inicial de las variables de sistema de AutoCAD que han sido
modificadas
aadir unas lneas al final del programa para indicar el nombre del nuevo
comando, autor, etc.
no introducir demasiado cdigo en la funcin principal
incluir una funcin de tratamiento de errores
evitar que el usuario pueda introducir datos errneos
en general es recomendable que, tras ejecutar el nuevo comando, si se ejecuta el
comando DESHACER (H) se deshagan todos los cambios realizados por el
comando
Convenciones utilizadas en el curso
El cdigo en AutoLISP se mostrar en negrita y con los siguientes colores:
o los parntesis de apertura y cierre se mostrarn en rojo ( )
o las funciones de AutoLISP se mostrarn en azul setq
o los nmeros se mostrarn en verde 125.6 12
o los textos se mostrarn en rosa /nDesigne un punto:
o los comentarios se mostrarn en prpura ;Esto es un comentario
o las funciones de usuario se mostrarn en maysculas (GAR 90.0)
Artculo siguiente
Introduccin a la programacin en AutoCAD
Tabla de contenidos de Introduccin a la programacin en AutoCAD
1. Primeros pasos con AutoLISP
2. Las variables en AutoLISP
3. Operaciones matemticas bsicas
4. Solicitar nmeros al usuario
5. Funciones de usuario y nuevos comandos
6. Introduccin al entorno de Visual LISP
7. Cargar los archivos de AutoLISP
8. Operaciones matemticas en AutoLISP
9. Solicitar textos y puntos al usuario
10. Funciones para manejar listas
11. Ejecutar comandos de AutoCAD
12. Operaciones de comparacin
13. Operaciones lgicas en AutoLISP
14. Estructuras condicionales simples
15. Estructuras condicionales mltiples
16. Mostrar textos al usuario en AutoLisp
17. Las variables de sistema de AutoCAD
18. Funciones de conversin de datos en AutoLISP
19. Obtener distancias y ngulos del usuario
20. El comando deshacer en las rutinas de AutoLISP
21. Funciones de tratamiento de errores en AutoLISP
22. Limitar las respuestas de los usuarios
23. Limitar las respuestas de los usuarios (II)
24. Estructuras repetitivas: Bucles
25. Funciones para manipular cadenas de texto
26. Trabajar con ngulos y distancias
27. Funciones avanzadas para manejar listas
28. Aplicar funciones a los elementos de una lista
29. Literales y otras funciones de utilidad
30. Carga automtica de los archivos de AutoLISP
31. Operaciones con archivos
32. Leer y escribir archivos de texto
Las variables en AutoLISP
Qu es una variable?
No sabes qu es una variable? Recuerdas cuando en la escuela te decan Tengo 3
melones, le doy uno a Juan y despus de comprar otros 2, me com uno porque tena
hambre. Pues los melones son una variable. Nosotros hacamos: 1 tengo 3 melones x=3
(x es nuestra variable). Luego le doy uno a Juan x = 3-1=2. Compro otros dos x = 2+2=4 y
me com uno x=4-1. As que x=3. x no es ms que un valor que vara (o puede hacerlo)
a lo largo del tiempo. Pero podamos haber llamado a la variable yo z, y por qu no
melones?
(SETQ Variable1 Valor1 [Variable2
Valor2 ... ] )
En el artculo anterior logramos dibujar una circunferencia de 6 mm de indicando el radio
de la circunferencia a travs de la expresin en AutoLISP (/ 6 (* 2 PI)). Pero que sucede si
queremos utilizar el valor obtenido por(/ 6 (* 2 PI)) para realizar otra operacin, tendremos
que volver a teclear la expresin anterior.
Existe alguna opcin para almacenar en memoria los resultados de una operacin, tal
como hace una calculadora? Desde luego que si, AutoLISP permite almacenar miles de
datos en variables, que se almacenan en la memoria del ordenador.
La funcin de AutoLISP empleada para definir variables y asignarles un valor es SETQ y
permite definir varias variables en una misma expresin. La funcin SETQ devuelve el
valor de la ltima variable definida.
Con respecto a los nombres utilizados para designar a los smbolos creados por el
usuario (variables y funciones):
no son sensibles a las maysculas. Es lo mismo bloque, BLOQUE y Bloque
no pueden contener espacios en blanco, ni los caracteres ( ) . ;
pueden contener nmeros, pero no estar formados nicamente por ellos
no utilizaremos nombres de variables que coincidan con los nombres de las
funciones de AutoLISP ni de las variables de sistema de AutoCAD
no existe lmite en cuanto al nmero de caracteres, pero es recomendable emplear
nombre cortos y descriptivos.
no es necesario declarar previamente las variables, como sucede en otros
lenguajes de programacin. En AutoLISP una misma variable puede contener primero
un nmero entero, luego uno real, despus una cadena de texto, etc.
Ejemplo:
(setq a 3) Esta expresin crea la variable a y le asigna el valor 3. Devuelve el valor de la
variable a.
Que valor crees que devolver (setq b (+ 1 3) melones 23.0)? Fjate que se han
definido dos variables b ymelones de valor 4 y 23.0 respectivamente. Como melones ha
sido la ltima variable evaluada, la expresin anterior devuelve su valor.
Si el interprete de comandos de AutoCAD recibe una palabra precedida por el signo de
exclamacin !, comprobar si ese termino ha sido empleado como un smbolo (nombre
de variable o una funcin de usuario) de AutoLISP. En cuyo caso devolver su valor y en
caso contrario devolver nil, que es lo mismo que nada o vaco. Por ejemplo: !
a devuelve 3.
Prueba tambin las siguientes expresiones y comprueba los valores asignados a las
variables:
(setq c (+ b 3)) Los valores de las variables tambin pueden utilizarse para realizar
operaciones y asignar el resultado de dichas operaciones a una variable.
(setq d b) Se puede definir una variable igual al valor de otra variable.
(setq a 3.5) Se puede modificar el valor asociado a una variable, por eso se llama
variable.
(setq b 2.0) Qu sucede con el valor de la variable d? Tomar el nuevo valor asignado
a la variable b o seguir con el anterior? Al definir la variable d se le asigno el valor que
tena la variable b en ese momento, no se estableci ninguna relacin entre ambas
variables.
Tambin se puede asignar valores no numricos a las variables. Por ejemplo, una cadena
de texto. Las cadenas de texto son secuencias de uno o ms caracteres encerrados entre
comillas. Dentro de una cadena de texto pueden insertarse una serie de carcteres de
control:
\\ representa al smbolo \
\ representa al smbolo
\n representa un cambio de lnea (retorno del carro)
\t representa una tabulacin
(setq a \tBienvenido al Curso Introduccin a la programacin en AutoCAD )
En este caso adems, hay que notar que en la variable a primero se almacenaba un valor
entero, luego uno real y ahora una cadena de texto. La posibilidad de reutilizar variables
con distintos tipos de datos puede ser muy til, pues dota al programador de una gran
flexibilidad al escribir el cdigo. Pero tambin supone que se requiera ms cuidado para
no pasar a una funcin una variable con un tipo de dato incorrecto. Por ejemplo:(+ a b) ya
que ahora la variable a contiene una cadena de texto en lugar de un nmero.
Existen una serie de smbolos predefinidos:
T Representa al valor lgico Cierto o Verdadero.
nil Representa al valor lgico Falso.
(setq b T)
(setq c nil)
En este caso, a la variable a se le ha asignado una cadena de texto, a la variable b el
valor Cierto o Verdadero y a la variable c el valor Vaco o Falso.
Para almacenar el radio de la circunferencia de permetro 6 unidades en una variable
podemos teclear:
(setq rad (/ 6 (* 2 PI)))
Podramos crear una circunferencia e indicar !rad a AutoCAD cuando nos pregunte por el
radio deseado.
Ejemplo: Por qu las siguientes expresiones estn mal?
(setq 157 25)
(setq rad 5 Rad 4)
(setq b Curso de AutoLISP)
Por ltimo veamos porque no debemos emplear para los nombres de las variables los
nombres de las funciones de AutoLISP.
(setq + 23) En este caso asignamos a la variable + el valor 23.
Prueba (+ 5 2.5) Ahora + no representa a la funcin suma, sino a una variable de valor 23.
De modo que el primer termino de la expresin anterior ahora no es una funcin, por lo
que da un error. Para recuperar el modo habitual de trabajo de la funcin + es necesario
cerrar la sesin actual de AutoCAD e iniciar una nueva sesin.
Operaciones matemticas bsicas
En los artculos anteriores ya vimos algn ejemplo de como funcionan las funciones
matemticas bsicas (suma, resta, divisin y multiplicacin). Ahora explicaremos su
funcionamiento con mayor profundidad.
(+ [nmero1 nmero2 ... ] )
Suma los nmeros indicados como argumentos y devuelve el resultado de dicha suma. Si
todos los nmeros de la lista son enteros, el resultado tambin ser entero.
(+ 3 9) devuelve 12
(+ 3.0 9) devuelve 12.0
(setq a (+ 3 9 4)) devuelve 16 y lo almacena en la variable a
(+ 3.5 -1) devuelve 2.5
Prueba ahora la siguiente expresin:
(setq a (+ a 2.5)) devuelve 18.5
Hemos asignado a la variable a el resultado de una operacin en la que usamos el
anterior valor asignado a la variable a como uno de los argumentos de la operacin.
Si le pasamos a la funcin + un nico nmero como argumento, nos devuelve ese
nmero.
(+ 12.5) devuelve 12.5
(+ -7.0) devuelve -7.0
Si ejecutamos la funcin suma sin argumentos, devuelve 0.
(+ ) devuelve 0
La expresin (+ .5 2) nos dar un error. Los nmeros reales siempre deben comenzar por
un nmero entero, incluso si es cero, seguido de la parte decimal.
(+ 0.5 2) devuelve 2.5
(+ 3 -0.6) devuelve 2.4
(- [nmero1 nmero2 ... ] )
Resta al primer nmero todos los siguientes nmeros pasados como argumentos. Si
todos los nmeros de la lista son enteros, el resultado tambin ser entero.
(- 11.0 5) devuelve 6.0
(- 11 5) devuelve 6
(setq a (- 12 5 4)) devuelve 3 y lo almacena en la variable a
(- 3.5 -1) devuelve -4.5
(setq a (- a 2.5)) devuelve 0.5 y lo almacena en la variable a.
Si le pasamos a la funcin - un nico nmero como argumento, nos devuelve ese nmero
cambiado de signo.
(- 12.5) devuelve -12.5
(- -7.0) devuelve 7.0
En la expresin anterior, el primer signo - representa a la funcin resta, mientras que el
segundo representa el signo de un nmero negativo.
Si ejecutamos la funcin resta sin argumentos, devuelve 0.
(- ) devuelve 0
(* [nmero1 nmero2 ... ] )
Multiplica los nmeros indicados como argumentos y devuelve el resultado de dicho
producto. Si todos los nmeros de la lista son enteros, el resultado tambin ser entero.
(* 3 9) devuelve 27
(* 3.0 9) devuelve 27.0
(setq a (* 3 9 4)) devuelve 108 y lo almacena en la variable a
(* 3.5 -1) devuelve -3.5
Prueba ahora la siguiente expresin:
(setq a (* a 2.5)) devuelve 270.0
Si le pasamos a la funcin * un nico nmero como argumento, nos devuelve ese nmero.
(* 12.5) devuelve 12.5
(* -7.0) devuelve -7.0
Si ejecutamos la funcin * sin argumentos, devuelve 0.
(* ) devuelve 0
(/ [nmero1 nmero2 ... ] )
Divide el primer nmero entre el siguiente y devuelve el resultado. Si se pasan ms de
dos nmeros como argumentos, el primer nmero se dividir entre el producto de los
restantes nmeros.
(/ 45 5 3) devuelve 3
(/ 11 5.5) devuelve 2.0
En esta funcin es muy importante recordar que si todos los nmeros de la lista son
enteros, el resultado tambin ser entero.
(/ 7 2) devuelve 3
(/ 7 2.0) devuelve 3.5
(setq a (/ 12.5 4 2)) devuelve 1.5625 y lo almacena en la variable a
(/ 3.5 -1) devuelve -3.5
(setq a (/ a 0.5)) devuelve 3.125 y lo almacena en la variable a
Si le pasamos a la funcin / un nico nmero como argumento, nos devuelve ese nmero.
(/ 12.5) devuelve 12.5
(/ -7.0) devuelve -7.0
Si ejecutamos la funcin / sin argumentos, devuelve 0.
(/ ) devuelve 0
(1+ <nmero> )
Esta funcin incrementa en una unidad el nmero indicado como argumento.
(1+ 5) devuelve 6. Ojo entre 1 y + no debe haber ningn espacio, ya que el nombre de
la funcin es 1+.
(1+ 2.5) devuelve 3.5
(1+ 0) devuelve 1
(1+ -7) devuelve -6
Una aplicacin bastante habitual de esta funcin es la de incrementar ndices o
contadores:
(setq i 1)
(setq i (1+ i)) devuelve 2
(1- <nmero> )
Esta funcin reduce en una unidad el nmero indicado.
(1- 5) devuelve 4. Ojo entre 1 y - no debe haber ningn espacio, ya que el nombre de
la funcin es 1-.
(1- 2.5) devuelve 1.5
(1- 0) devuelve -1
(1- -1) devuelve -2
Solicitar nmeros al usuario
En este artculo veremos dos funciones de AutoLISP que nos permitirn solicitar al
usuario un nmero entero o real. Esto nos permitir interactuar con el usuario y pedirle
informacin.
(GETINT [mensaje] )
Solicita del usuario un nmero entero. En caso de que el usuario introduzca un nmero
real o cualquier otro dato que no sea un nmero entero, AutoCAD recordar mediante un
mensaje que est solicitando un nmero entero y no finalizar la ejecucin de la funcin
hasta que se introduzca un valor entero, o se pulse ESC para cancelar su ejecucin.
(getint)
Puede indicarse un mensaje de solicitud opcional, que facilite al usuario informacin
acerca de lo que se est pidiendo. El mensaje debe ser una cadena de texto y por tanto
debe estar entre comillas.
(getint Cuntos aos tienes?:)
Podemos asignar el valor introducido por el usuario a una variable y as utilizarlo despus.
(setq edad (getint Cuntos aos tienes?:))
(setq edad (+ edad 1)) nos dar la edad que tendrs el prximo ao.
Tambin puedes crear una variable que contenga el mensaje de solicitud de la
funcin GETINT
(setq mens Cuntos aos tienes?:)
(setq edad (getint mens))
En este caso mens es una variable que almacena una cadena de texto, pero no es una
cadena de texto. Por lo tanto, no debe ir entre comillas.
Prueba ahora el siguiente ejemplo:
(setq a 27 mens Cuntos aos tienes?:)
(setq edad (getint mens))
Que pasar si como respuesta a la solicitud de la edad del usuario se introduce !a. Parece
lgico que le estamos indicando el valor de la variable a, que contiene el valor
numrico 27, de modo que la variable edad debera tomar el valor 27, pero observaras
que no es as. Haz la prueba: nos indicar que es Imposible volver a entrar en LISP..
Esto es debido a que al ejecutar la funcin GETINT se est ejecutando el interprete de
LISP, y al indicar !a como respuesta estamos diciendo que ejecute el interprete de LISP
para obtener el valor asociado a la variable a. Como el interprete de LISP ya est en
ejecucin, no puede volver a ejecutarse y nos muestra el mensaje anterior.
(GETREAL [mensaje] )
Solicita del usuario un nmero real. En caso de que el usuario introduzca un nmero
entero, el interprete de AutoLISP lo considerar como un real. Si se introduce cualquier
otro tipo de dato que no sea numrico, recordar mediante un mensaje que est
solicitando un nmero real y no finalizar la ejecucin de la funcin hasta que se
introduzca un valor numrico, o se pulse ESC para cancelar su ejecucin.
(getreal)
Puede indicarse un mensaje de solicitud opcional, que facilite al usuario informacin
acerca de lo que se est pidiendo. El mensaje debe ser una cadena de texto y por tanto
debe estar entre comillas.
(setq peso (getreal Cuntos kilos pesas?:))
(setq peso (- peso 1)) nos dar el peso que tendrs si adelgazas un kilo.
Tambin puedes crear una variable que contenga el mensaje de solicitud de la
funcin GETREAL
(setq mens Cuntos kilos pesas?:)
(setq peso (getreal mens))
Funciones de usuario y nuevos comandos
Definir funciones de usuario
Hemos visto tan solo algunas de las funciones de AutoLISP, pero tambin es posible
crear nuestras propias funciones. Es ms, podemos redefinir las funciones de AutoLISP e
incluso los comandos de AutoCAD. La instruccin de AutoLISP que nos permitir crear
nuestras propias funciones, denominadas funciones de usuario, se llama DEFUN.
(DEFUN <funcin> ( [argumentos] /
[variables_locales] ) [expr1] [expr2] )
El primer argumento representa el nombre de la funcin de usuario que queremos definir.
Hay que tener cuidado de no emplear los nombres de las funciones de AutoLISP, ya que
en dicho caso se redefiniran.
Despus de indicar el nombre de la funcin, se deben indicar entre parntesis los
argumentos y las variables locales, separados por una barra inclinada:
los argumentos son valores que recibir la funcin cuando sea ejecutada por el
usuario, o llamada desde otras funciones
las variables locales son aquellas variables que se emplearn tan solo dentro de
la funcin que queremos definir, de modo que restringimos su uso al entorno de la
funcin
Por ltimo, se aaden las expresiones que ejecutar la funcin. Veamos algunos
ejemplos:
(defun 2+ ( valor ) (+ valor 2))
En este caso hemos definido una nueva funcin llamada 2+, que recibe como argumento
un nmero y realiza la suma de ese nmero y 2. Las funciones de AutoLISP las
ejecutamos escribiendo directamente desde la lnea de comandos, bien pues las
funciones de usuario se ejecutan exactamente igual. Prueba:
(2+ 5) devuelve 7
(2+ 0) devuelve 2
(2+ -2) devuelve 0
Defun devuelve el resultado de la ltima expresin ejecutada, que en el caso anterior
es (+ valor 2).
Que sucede si tratamos de ejecutar la funcin sin pasar ningn argumento, o pasando
un argumento que no sea de tipo numrico?. Veamos:
(2+ ) indica ; error: argumentos insuficientes
(2+ texto) indica ; error: tipo de argumento errneo: numberp: texto
(2+ 1 2) indica ; error: demasiados argumentos
Podras pensar que el nmero indicado se almacena en una variable llamada valor,
pero no es as. Puedes comprobarlo escribiendo !valor en la lnea de comandos, lo que
nos devolver nil.
En la funcin anterior tenemos un argumento y no hay variables locales. La vamos a
modificar un poco:
(defun 2+ ( valor ) (setq valor (+ valor 2)))
Ahora seguro que estas totalmente convencido de que el resultado obtenido se almacena
en la variable valor. Pues comprobemos si tienes razn:
(2+ 5) devuelve 7
!valor devuelve nil
La funcin 2+ recibe como argumento un nmero, que almacena en la variable valor.
Pero el mbito de aplicacin es local, es decir una vez que salgamos de la funcin 2+
la variable valor recupera su valor inicial, que en este caso es nil. Vamos con otra
prueba
(setq valor 5) devuelve 5
(2+ 4) devuelve 6
Que valor crees que tendr la variable valor? Pensemos un poco.
inicialmente valor era nil
al ejecutar (setq valor 5) asignamos a la variable valor el nmero entero 5
cuando llamamos a la funcin 2+ con la expresin (2+ 4) tenemos que valor
es 4
dentro de la funcin 2+ asignamos (setq valor (+ valor 2)) de modo que valor
ser 6
pero como se trata de una variable local, al salir de la funcin 2+ recuperamos el
valor que tena la variable valor antes de llamar a la funcin, de modo
que valor ser 5
por tanto, si tecleamos !valor devolver 5
Pero, que pasa si ejecutamos (setq valor (2+ 4)). Se repiten los puntos 1-4 anteriores,
pero al salir de la funcin 2+ le asignamos a valor el valor devuelto por la funcin, que
es 6. De modo que valor ser 6.
Retoquemos un poco ms la funcin 2+
(defun 2+ ( valor ) (setq inicial valor valor (+ valor 2)))
y borremos el contenido de valor. Para ello simplemente le asignamos nil.
(setq valor nil)
En este caso, dentro de la funcin 2+ declaramos una variable a la que se le asigna el
valor que recibe como argumento la funcin.
(2+ 4)
Que valor tendrn ahora las variables valor e inicial? Vamos a comprobarlo:
!valor devuelve nil tal como suceda en el ejemplo anterior
!inicial devuelve 4
Observa que valor se comporta como una variable local, solo se emplea dentro de la
funcin. Sin embargo inicial es de mbito global, es decir se sigue empleando al salir
de la funcin. Vamos a modificar un poquito ms nuestra funcin:
(defun 2+ ( valor / inicial ) (setq inicial valor valor (+ valor 2)))
Ahora hemos aadido la variable inicial a la lista de variables locales, con lo que su
mbito ser local. Para comprobarlo
!inicial devuelve 4
(setq inicial nil)
!inicial devuelve nil
(2+ 3)
!inicial devuelve nil
Bueno, vamos con la ltima modificacin de la funcin 2+
(defun 2+ ( / valor ) (setq valor (getint Nmero: )) (setq valor (+ valor 2)))
Ahora la funcin 2+ no tiene argumentos, as que para ejecutarla tan solo debemos
poner su nombre entre parntesis:
(2+)
La variable valor es de mbito local y se emplea GETINT para solicitar un nmero al
usuario.
Lo habitual es que se trate de evitar el uso de variables globales innecesarias. De
modo que las variables que no sean globales, se debern aadir a la lista de variables
locales dentro de las definiciones de las funciones de usuario.
Crear nuevos comandos de AutoCAD
La funcin de AutoLISP DEFUN no solo permite crear funciones de usuario, tambin
permite crear nuevos comandos de AutoCAD.
Siguiendo con el ejemplo anterior
(defun C:2+ ( / valor ) (setq valor (getint Nmero: )) (setq valor (+ valor 2)))
Si anteponemos al nombre de la funcin a definir C: en lugar de crear una funcin de
usuario, se crea un nuevo comando de AutoCAD. La funcin seguir funcionando
exactamente igual, la nica diferencia est en el modo de ejecutarse. Ahora no es
necesario poner el nombre de la funcin entre parntesis, sino que se escribe
directamente en la ventana de comandos de AutoCAD.
2+
Tambin se puede ejecutar poniendo el nombre de la funcin precedido de C: entre
parntesis.
(C:2+)
En caso de que el nuevo comando creado necesite algn argumento, tan solo podr
ejecutarse del ltimo modo.
(defun C:2+ ( valor / inicial ) (setq inicial valor valor (+ valor 2)))
(C:2+ 2) devuelve 4
Si escribimos directamente 2+ AutoCAD mostrar el mensaje error: argumentos
insuficientes.
Si tratamos de escribir 2+ 2 en la ventana de comandos de AutoCAD veremos que al
escribir el espacio entre el nombre de la funcin y el argumento, AutoCAD ejecuta lo que
cree que es un comando. Por este motivo ahora slo podramos ejecutar la funcin si la
llamamos escribiendo (C:2+ 2) en la ventana de comandos de AutoCAD.
La funcin que hemos creado solo nos servir para la sesin actual de AutoCAD. Es ms,
tan solo est definida la funcin 2+ en el dibujo actual, de modo que si hay ms dibujos
abiertos, en ellos no estar definida.
En el siguiente tema veremos como guardar nuestras funciones en archivos de texto, a la
vez que comenzamos a trabajar con el entorno de Visual LISP.
Introduccin al entorno de Visual LISP
Archivos de cdigo fuente en
AutoLISP
Ya hemos visto que las funciones de AutoLISP se pueden ejecutar directamente desde la
ventana de comandos de AutoCAD. Pero el escribir el cdigo directamente en AutoCAD
tiene varios inconvenientes, como ya se coment en el primer artculo del curso:
el reducido tamao de la ventana de comandos de AutoCAD
la dificultad de escribir todo el cdigo seguido, sin tabular. Esto es debido a que
cada vez que se pulsa Intro, AutoCAD evala lo que se ha escrito
el cdigo no se almacena en ningn sitio, as que se perder al cerrar el dibujo
actual o AutoCAD
De modo que en la ventana de comandos de AutoCAD tan slo se escribirn pequeas
lneas de cdigo que no interese guardar. Suele emplearse por tanto para hacer pruebas
y depurar cdigo, aunque tambin se puede utilizar como una ayuda ms para el diseo
con AutoCAD.
El cdigo de las funciones de AutoLISP se escribe en un editor de textos ASCII, para que
as se puedan almacenar. Se puede emplear cualquier editor de texto que permita tan
solo cdigos ASCII, por ejemplo el bloc de notas de Windows. Otros editores, como MS
Word, insertan cdigos para diferenciar los estilos de texto, las tabulaciones, etc. y no se
pueden emplear para escribir las rutinas de AutoLISP, ya que el interprete de AutoLISP no
sabe interpretar esos cdigos.
Adems del bloc de notas, existen muchos otros editores de texto que se pueden emplear
para escribir cdigo fuente en AutoLISP. Algunos de estos editores, disponen de
utilidades para la programacin (permitiendo incluso emplearlos para distintos lenguajes
de programacin). Otros editores estn ya enfocados a la programacin en LISP o
AutoLISP.
Desde la versin 14, AutoCAD incorpora un editor para AutoLISP, en el que tenemos
entre otras las siguientes utilidades:
evaluacin de parntesis durante la programacin
posibilidad de compilar el cdigo, consiguiendo as aumentar su velocidad de
ejecucin
depurador de cdigo especfico para AutoLISP con opciones para: Ejecutar el
cdigo paso a paso, indicar puntos de parada, evaluar expresiones y valores de
variables, etc.
diferenciar el cdigo fuente con distintos colores
tabulado automtico del cdigo
utilidades para gestionar proyectos con varios archivos de cdigo
carga de los archivos en AutoCAD
Nosotros seguiremos utilizando la ventana de comandos de AutoCAD para ver como
trabajan las funciones de AutoLISP, y nos iremos al editor de Visual Lisp para crear
nuevas funciones y comandos.
Los archivos de AutoLISP son archivos de texto con extensin LSP.
Nuestra primera funcin de usuario
Antes de comenzar con el editor de Visual LISP, vamos a crear nuestra primera funcin
de usuario: Se trata de una funcin para convertir un ngulo de radianes a grados
decimales, algo que nos ser muy til en muchas de las macros que creemos a lo largo
del curso. El cdigo de la funcin sera el siguiente:
(defun RAG ( ang )
(/ (* ang 180.0) pi)
)
Hay tres reglas bsicas que sigue AutoLISP:
1. el nmero de parntesis de apertura debe ser igual al nmero de parntesis de
cierre
2. primero se evaluan las listas ms interiores
3. toda funcin de AutoLISP devuelve un resultado
El interprete de AutoLISP no evala los retornos de carro (Intros), de modo que el cdigo
se poda haber escrito todo seguido, en una misma lnea:
(defun RAG ( ang ) (/ (* ang 180.0) pi) )
pero as es ms difcil de leer. Esta funcin tiene muy poco cdigo, pero imagina una
funcin mucho mayor escrita toda en la misma lnea.
Fjate en que la segunda lnea se presenta tabulada, de modo que no comienza a la
misma altura que el resto, sino que est desplazada hacia la derecha. Esto nos indica que
est incluida dentro de una lista de nivel superior, la de la funcin defun.
No es necesario tabular el cdigo, pero facilita su lectura y adems nos permite detectar
posibles errores con los parntesis (Regla nmero 1).
Pi es una constante que ya est definida en AutoLISP, pi equivale al nmero 3.141592
En la primera lnea (defun RAG ( ang ) definimos la funcin RAG (Radianes A Grados)
que recibe un argumento ang (el ngulo en radianes).
Veamos como funciona la segunda lnea: Por la Regla nmero 2, primero se evaluar la
lista interior (* ang180.0) que multiplica el ngulo en radianes ang por 180.0 y devuelve
el resultado a la lista de nivel superior (recuerda la Regla nmero 3) que lo divide
entre pi = 3.141592 devolviendo a su vez el resultado de la divisin (el ngulo en
grados decimales) a la lista de nivel superior, defun.
La ltima lnea cierra la lista de la funcin defun, cumpliendo as con la Regla nmero 1.
Recordemos la estructura de la funcin de AutoLISP defun: (DEFUN <funcin>
( [argumentos] / [variables_locales] ) [expresin1] [expresin2] ) . En la
funcin RAG tenemos un argumento y no se han declarado variables locales (por lo que
no es necesario poner el caracter /), adems solo tenemos una
expresin (/ (* ang 180.0) pi) . Como se dijo en el tema anterior, defun devuelve el
resultado de la ltima expresin, que en nuestro caso resulta ser el ngulo ya convertido a
grados decimales.
Nuestra funcin RAG se ejecutara as:
(RAG 1.57)
siendo 1.57 el ngulo en radianes, y devolvera ese ngulo en grados decimales
(aproximadamente 90).
No es necesario poner el nombre de la funcin RAG en maysculas, ya que AutoLISP no
diferencia las maysculas de las minsculas (salvo en contadas excepciones al trabajar
con textos, como ya veremos). A lo largo de los artculos del curso se mostrarn los
nombres de las funciones de usuario en maysculas simplemente para que se diferencien
perfectamente del resto del cdigo.
Los comentarios en el cdigo
Es imprescindible aadir comentarios al cdigo para explicar qu es lo que hace y cmo
se hace.
En AutoLISP todo lo que en una lnea va despus de un punto y coma (como este ;) se
considera un comentario, de modo que no se evala. Da igual poner uno, dos o 45 puntos
y comas seguidos, al poner el primero AutoLISP ya sabe que todo lo que est a
continuacin, en esa lnea, es un comentario.
Tal vez pienses que no es tan importante aadir explicaciones en el cdigo. Pero si tienes
que leer una rutina que creaste hace meses sern muy tiles, por que seguramente no
recordaras muy bien como funciona. Adems, si alguien va a leer alguna de vuestras
rutinas le facilitaras mucho la labor. Al igual que a ti te ser ms sencillo leer y entender
una rutina con abundantes comentarios.
Para los comentarios incluidos en el cdigo, se recomienda utilizar el siguiente mtodo:
;;; Antes del cdigo de las funciones, explicando su funcionamiento
;; En medio del cdigo del programa
; Para explicar una lnea de cdigo. A diferencia de las anteriores, esta no se
inserta en la columna 1, sino al terminar el cdigo de la lnea que comenta
Por ejemplo, la funcin RAG con comentarios podra quedar as:
;;; Esta funcin recibe el valor de un ngulo en radianes y lo devuelve en grados
decimales.
(defun RAG ( ang ) ; Recibe un ngulo en radianes
(/ (* ang 180.0) pi)
;; Multiplica el ngulo en radianes por 180.0 y lo divide por pi.
)
El editor de Visual LISP
El editor de Visual LISP se inicia desde AutoCAD de varias formas:
Ejecutando el comando de AutoCAD VLIDE.
Desde el men desplegable de AutoCAD Herr>AutoLISP>Editor de Visual
LISP
Mostrar algo similar a la siguiente imagen:
El editor de Visual LISP
Al abrir el editor veremos dos ventanas, consola de Visual LISP y Rastreo. De
momento no nos vamos a parar a ver para qu sirven o cmo funcionan estas ventanas.
Estamos ante un editor de textos, como otro cualquiera, pero con utilidades especficas
para la programacin en AutoLISP. De modo que para crear un nuevo archivo hacemos lo
mismo que en cualquier editor de textos: Archivo>Nuevo archivo (o pulsa Control +
N).
Aparece una nueva ventana, tal como puede verse en la siguiente imagen:
Nueva ventana de cdigo en el editor Visual LISP
Es en esta pantalla donde vamos a escribir el cdigo de nuestra rutina RAG, pero antes
un pequeo comentario
Es bastante habitual aadir al principio de los archivos de AutoLISP unas lneas de
comentarios indicando el nombre del autor, fecha, nombre de los comandos y/o funciones
definidas en el archivo, y una breve descripcin de estos. De modo que al cdigo anterior
le aadiremos unas lneas en la cabecera del archivo:
;;;____________________Eduardo Magdalena____________________;;;
;;;_________________________RAG.LSP___________________________;;;
;;;_______________________Versin 1.0_________________________;;;
;;;________________________21/02/2002_________________________;;;
;;; Esta funcin recibe el valor de un ngulo en radianes y lo devuelve en grados
decimales.
(defun RAG ( ang ) ; Recibe un ngulo en radianes
(/ (* ang 180.0) pi)
;; Multiplica el ngulo en radianes por 180.0 y lo divide por pi.
)
El editor de Visual LISP realiza las tabulaciones automticamente. Y aunque se pueden
eliminar o modificar a nuestro gusto (aadiendo o quitando espacios y tabulaciones), lo
recomendable es mantener el formato por defecto para el cdigo. Veamos como queda la
funcin RAG en el editor:
La funcin RAG en el editor de Visual LISP
En primer lugar observamos que el cdigo tiene distintos colores. Esto es simplemente
una ayuda visual para diferenciar los diferentes elementos de nuestras rutinas:
las funciones de AutoLISP se muestran de color azul setq
los comentarios en morado ;Esto es un comentario
los parntesis en color rojo (setq a 2.0)
los nmeros en color verde 2.0
los textos en color rosa (en este ejemplo no aparece ningn texto, pero veremos
algunos ejemplos ms adelante) Soy un texto
el resto de elementos, como los nombres de las funciones y de las variables
utilizadas, se muestran en color negro
Adems, las funciones de usuario se destacarn escribindose en maysculas RAG.
Este formato de colores se utilizar tambin en los artculos de este curso, tal como se
muestra en el cdigo de la funcin RAG anterior.
El formato coloreado del cdigo se puede desactivar, o se pueden modificar los colores
predefinidos para los diferentes elementos. Pero el mantener el formato de colores para el
cdigo, nos puede ayudar a detectar errores.
Por ejemplo, si ponemos (setw radianes 1.57)
SETW aparecer en negro y no en azul, por que la funcin de AutoLISP es SETQ, de
modo que nos indica que hemos escrito mal el nombre de la funcin.
En cuanto a la tabulacin, tal vez llame la atencin el ltimo parntesis (el de cierre de la
funcin defun), ya que no est a la misma altura que su parntesis de apertura. Hay
editores para AutoLISP que insertan los parntesis de cierre a la misma altura que sus
correspondientes parntesis de apertura y hay otros editores que insertan los parntesis
de cierre tabulados, tal como hace (por defecto) el editor de Visual LISP.
Una vez escrito el cdigo de la funcin RAG, tan solo nos queda guardarlo en un archivo.
Es recomendable crear un directorio (carpeta) en el que guardar todas nuestras rutinas.
Veremos ms adelante que se pueden guardar varias funciones y varios comandos en un
mismo archivo de AutoLISP, aunque en este caso slo se ha definido una nueva funcin
de usuario.
Se le suele dar a los archivos de AutoLISP el mismo nombre del comando o funcin que
est definida en l, podemos guardar esta rutina en el archivo klhsduif.lsp pero luego no
la reconoceramos. As que lo mejor ser guardar el cdigo de la funcin RAG en el
archivo RAG.lsp, dentro del directorio que hemos creado para almacenar nuestras
rutinas. As que selecciona Archivo > Guardar como e indica la ruta y el nombre del
archivo.
Ahora puedes intentar crear una funcin llamada GAR que reciba como argumento un
ngulo en grados decimales y que devuelva ese ngulo en radianes.
Es prcticamente igual a la funcin que acabamos de ver. Pero recuerda Antes de
empezar a programar (como antes de hacer casi cualquier cosa) conviene pensar en lo
que se va a hacer y en cmo lo vamos a hacer. Como esta rutina es muy sencilla no es
necesario escribir el pseudocdigo (ni hacer un diagrama de flujo), tan solo hay que
pensar un poco en lo que se va a hacer. Guarda el cdigo de la funcin GAR en un
archivo llamado GAR.lsp en el directorio donde tengas tus rutinas.
Cargar los archivos de AutoLISP
Para que la funcin RAG que creamos en el artculo anterior se pueda ejecutar en
AutoCAD, hay que cargar el archivo de AutoLISP en el que est definida. Existen varias
formas de cargar los archivos de AutoLISP, pero de momento tan solo vamos a ver tres:
1. Cargar un archivo desde el editor de Visual LISP
2. En el men desplegable de AutoCAD Herr>AutoLISP>Cargar aplicacin.
3. Utilizando la funcin de AutoLISP LOAD.
Si estamos en el editor de Visual LISP y tenemos abierto un archivo con una rutina, para
cargarla en AutoCAD podemos:
Seleccionar en los mens desplegables del Visual LISP Herramientas > Cargar
texto en editor.
Pulsando sobre el icono .
Tecleando la combinacin de teclas CTRL+ALT+E.
Al cargar el archivo, aparece la Consola de Visual LISP mostrando un mensaje parecido
al siguiente: ; N formularios cargado de #<editor RUTA/rag.lsp>. En caso de que se
produzca algn error en el proceso de carga del archivo, en la consola de Visual LISP se
nos indicara el tipo de error que se ha producido. De modo que habria que modificar el
cdigo para corregir ese error antes de cargar la rutina.
Una vez cargada la rutina en AutoCAD, podemos probar si funciona. Teclea directamente
en la ventana de comandos de AutoCAD:
(RAG 0)
(RAG pi)
(RAG (/ pi 4))
El segundo mtodo para cargar un archivo de AutoLISP en AutoCAD (seleccionando en el
men de AutoCAD Herr>AutoLISP>Cargar aplicacin) muestra un letrero de
dilogo en el que se selecciona el archivo a cargar y se pulsa el botn Cargar.
Cargar / Descargar aplicaciones
Este mtodo ofrece dos ventajas:
se puede seleccionar ms de un archivo
permite descargar las funciones de AutoLISP definidas en los archivos
seleccionados
(LOAD archivo [resultado_si_falla])
La funcin LOAD permite cargar en AutoCAD el archivo de AutoLISP que se indique. Por
ejemplo para cargar el archivo RAG sera:
(load rag)
No hace falta indicar la extensin del archivo. Escribiendo as el nombre del archivo solo
cargar el archivoRAG.LSP si est en uno de los directorios de soporte de AutoCAD o en
el directorio actual. En caso contrario hay que indicar la ruta completa:
(load c:\rutinas\rag.lsp)
Pero si lo hiciramos as nos dara un error, ya que AutoCAD no reconoce el carcter \,
de modo que hay que escribirlo de forma algo especial. Para AutoLISP el caracter \ hay
que indicarlo de cualquiera de esas 2 formas: \\ o /. Por lo tanto escribiremos:
(load c:\\rutinas\\rag.lsp)
o
(load c:/rutinas/rag.lsp)
En caso de que no se encuentre el archivo, la expresin load puede ejecutar lo que se
indique en [resultado_si_falla]. Por ejemplo:
(load rag (setq test 0))
En este caso, si no se encuentra el archivo RAG.lsp a la variable test se le asigna el valor
cero. Suele emplearse para que, cuando se ejecute LOAD desde dentro de una funcin
de AutoLISP, podamos indicarle al usuario que no se ha encontrado el archivo. Como
indica el siguiente pseudocdigo:
Si test = 0 ==> Mensaje al usuario Archivo no encontrado
Esto es todo, de momento, sobre la carga de archivos de AutoLISP en AutoCAD. Ms
adelante veremos otros mtodos para cargar nuestras rutinas.
Veamos como sera la funcin GAR propuesta en el tema anterior:
;;;_____________________Eduardo Magdalena_____________________;;;
;;;_________________________GAR.LSP___________________________;;;
;;;_______________________Versin 1.0_________________________;;;
;;;________________________21/02/2002_________________________;;;
;;; Esta funcin recibe el valor de un ngulo en grados decimales y lo devuelve en
radianes.
(defun GAR ( ang ) ; Recibe un ngulo en grados decimales
(/ (* ang pi) 180.0)
;; Multiplica el ngulo en grados decimales por Pi y lo divide por 180.0.
)
Es muy muy parecida a la funcin RAG, no?
Crear un directorio para los archivos
de AutoLISP
Supongamos que el directorio que hemos creado para almacenar nuestras rutinas es
C:\Rutinas. Veamos como aadirlo a los directorios de soporte de AutoLISP:
Inicia AutoCAD. En el men desplegable Herr selecciona Opciones. As aparece un
letrero de dilogo que nos permitir configurar AutoCAD. En la primera pestaa
Archivos tenemos una opcin denominada Ruta de bsqueda de archivos de
soporte. Si no est expandida, para ver su contenido pulsamos con el ratn sobre
el + que aparece a la izquierda.
Para aadir un nuevo directorio de soporte pulsamos el botn Aadir que se encuentra
a la derecha del cuadro de dilogo. Esto crear una nueva etiqueta, en la que podemos
escribir la ruta del directorio o pulsar el botn Examinar para seleccionarlo. Ya hemos
aadido C:\Rutinas a los directorios de soporte de AutoCAD.
Opciones de AutoCAD
Tambin podemos subir o bajar el nuevo directorio en la lista de directorios de soporte.
Esto se hace para definir las prioridades, es decir donde buscar primero. De modo que si
subimos nuestro directorio hasta el primer lugar (como en la imagen), este ser el primer
directorio en el que busque AutoCAD.
Operaciones matemticas en AutoLISP
Hemos visto las operaciones matemticas bsicas: suma, resta, multiplicacin y divisin y
las funciones 1+ y1-. Ahora vamos con otras funciones de AutoLISP que nos permitiran
realizar casi cualquier operacin matemtica en nuestras rutinas.
(ABS numero)
Esta funcin devuelve el valor absoluto del nmero que se le pase como argumento. Por
ejemplo:
(abs 23.8) devuelve 23.8
(abs -23.8) tambin devuelve 23.8
Si el nmero que recibe como argumento es entero, devuelve un nmero entero y si es un
nmero real, devuelve un real.
(abs -7) devuelve 7
(abs -7.0) devuelve 7.0
(abs 0) devuelve 0
(FIX numero)
Esta funcin devuelve la parte entera de un nmero. De modo que devuelve un nmero
entero. Ojo! esta funcin no redondea, sino que elimina lo que est detrs del punto
decimal.
(fix 15.8) devuelve 15.
(fix -15.8) devuelve -15
(fix 0.99) devuelve 0
(fix -0.99) devuelve 0
(REM numero1 numero2 [numero3] )
Esta funcin devuelve el resto de la divisin de numero1 entre numero 2.
(rem 2.5 2) devuelve 0.5
(rem 3 2) devuelve 1
Cuando se indican ms de 2 nmeros (rem 1 2 3) es equivalente a (rem (rem 1 2) 3). Es
decir, primero calcula el resto de la divisin entre 1 y 2, que es 1, y despus lo divide
entre 3 y devuelve su resto, que es 1.
Si todos los nmeros que recibe como argumentos son enteros, devuelve un nmero
entero y si alguno de ellos es un nmero real, devuelve un real.
(rem 3 2.0) devuelve 1.0
(SIN angulo)
Devuelve el seno de un ngulo indicado en radianes.
(sin 0) devuelve 0.0
(sin (/ pi 2)) devuelve 1.0
(COS angulo)
Funciona igual que la anterior, pero devuelve el coseno del ngulo, que recibe en
radianes.
(cos 0) devuelve 1.0
(cos pi) devuelve -1.0
(ATAN numero 1 [numero2])
Devuelve el arco cuya tangente sea numero1. Por ejemplo:
(atan 0) devuelve 0.0 ya que el ngulo que tiene tangente 0 es el 0.0
Si se indica un segundo nmero (atan num1 num2) lo que hace es dividir num1 entre
num2 y devuelve el arco cuya tangente sea el resultado de la divisin. Esto se hace para
facilitar lo siguiente
(atan (sin angulo) (cos angulo)) devuelve angulo
(SQRT numero)
Esta funcin devuelve la raiz cuadrada del numero que recibe como argumento. Siempre
devuelve un nmero real, no entero.
(sqrt 4) devuelve 2.0
(sqrt 2.0) devuelve 1.41
(EXPT num exp)
Devuelve el nmero num elevado al exponente exp.
(expt 2 2) devuelve 4
(expt 2 3) devuelve 8
Si todos los nmeros que recibe como argumentos son enteros, devuelve un nmero
entero y si alguno de ellos es un nmero real, devuelve un real.
(expt 3 2.0) devuelve 9.0
(EXP num)
Devuelve el nmero e ( e = 2.71828 ) elevado al nmero num. Siempre devuelve un
nmero real.
(exp 1) devuelve 2.71828
(exp 2) devuelve 7.38906
(LOG numero)
Esta funcin devuelve el logaritmo neperiano del nmero que recibe como argumento.
(log 1) devuelve 0.0
(log 2) devuelve 0.693147
(GCD entero1 entero2)
Esta funcin recibe dos nmeros enteros y devuelve su mximo comn divisor (o
denominador). Siempre devuelve un nmero entero.
(gcd 15 5) devuelve 5
(gcd 9 33) devuelve 3
(MAX num1 num2 )
Devuelve el mayor de los nmeros que recibe como argumentos.
(max 2 4 1 3 6) devuelve 6
(max 8 4 -9) devuelve 8
Si todos los nmeros que recibe como argumentos son enteros, devuelve un nmero
entero y si alguno de ellos es un nmero real, devuelve un real.
(max 8 4.0 -9) devuelve 8.0
(MIN num1 num2 )
Devuelve el menor de los nmeros que recibe como argumentos.
(min 2 3 6) devuelve 2
(min 8 4 -9) devuelve -9
Si todos los nmeros que recibe como argumentos son enteros, devuelve un nmero
entero y si alguno de ellos es un nmero real, devuelve un real.
(min 8 4.0 -9) devuelve -9.0
Pues ya estn vistas todas las funciones matemticas Enhorabuena!!!
Solicitar textos y puntos al usuario
Recuerdas las funciones GETINT y GETREAL? Nos sirven para solicitar al usuario un
nmero entero y real, respectivamente. Pues la funcin que se utiliza para solicitar textos
al usuario es muy parecida.
(GETSTRING [modo] [mensaje])
Se puede ejecutar sin parmetros (getstring) pero no es recomendable. Se suele indicar
un mensaje de texto que explique al usuario lo que se le est solicitando. Por ejemplo:
(getstring Cul es tu nombre?)
Supongamos que te llamas Pepe, a (getstring Cul es tu
nombre?) responderas Pepe y ya est. Incluso se podra asignar el nombre que indique
el usuario a una variable:
(setq nombre (getstring Cul es tu nombre?))
Pero que sucede si te llamas Jos Luis? Pues que en cuanto pulses el espacio es como si
hubieras pulsado Intro. No nos permite insertar textos con espacios. Para que admita
textos con espacios, debemos hacer un pequeo cambio:
(setq nombre (getstring T Cul es tu nombre?))
Le estamos indicando el argumento [modo] = T. Este argumento puede ser cualquier
expresin de AutoLISP, en este caso le pasamos el valor T = Cierto, verdadero. Si no se
indica el modo, o si al evaluarlo devuelvenil = Falso, vaco; entonces no admite espacios.
Y si se pone cualquier expresin que al evaluarse no devuelva nil, permite espacios.
(setq nombre (getstring (+ 1 2) Cul es tu nombre?)) permite responder con
espacios, ya que (+ 1 2)devuelve 3 que es distinto de nil.
(setq nombre (getstring (setq var1 nil) Cul es tu nombre?)) no permite responder
con espacios, ya que (setq var1 nil) devuelve nil.
Para solicitar puntos se utilizan dos funciones que tambin son parecidas a GETINT y
a GETREAL.
(GETPOINT [pto_base] [mensaje])
Esta funcin le pide un punto al usuario y devuelve una lista con las coordenadas del
punto indicado. El usuario puede indicar el punto en pantalla con el ratn o tecleando sus
coordenadas, tal y como se hara al dibujar en AutoCAD.
Se puede ejecutar sin parmetros (getpoint) pero no es recomendable. Se suele indicar
un mensaje de texto que explique al usuario lo que se le est solicitando. Por ejemplo:
(getpoint Punto inicial)
Lo habitual es que adems ese punto se almacene en una variable
(setq pto (getpoint Punto inicial))
As asignamos a la variable pto algo parecido a lo siguiente: (120.56 135.88 0.0)
Veamos ahora para que sirve el argumento opcional [pto_base] aprovechando que
tenemos el punto ptodefinido.
(getpoint pto Siguiente punto:)
Aparece una lnea elstica entre el punto pto y la posicin del cursor.
(GETCORNER pto_base [mensaje])
Esta funcin se utiliza tambin para solicitar puntos al usuario. En este caso el punto base
no es opcional, hay que indicarlo. Veamos la diferencia entre las dos expresiones
siguientes:
(getpoint pto Siguiente punto:)
(getcorner pto Siguiente punto:)
Al utilizar getpoint, se muestra una lnea elstica entre el punto pto y la posicin del
cursor. Si se utilizagetcorner, en lugar de una lnea elstica, aparece un rectngulo.
Fijmonos un momento en lo que devuelven tanto getpoint como getcorner: (125.68
117.68 0.0). Se trata de una lista, una lista con las corrdenadas de un punto. Bien, pues
en el prximo artculo veremos algunas funciones para manejar listas.
Funciones para manejar listas
AutoLISP es un lenguaje de programacin basado en listas as que es lgico que el
tratamiento que reciban las listas de elementos sea muy bueno. Por otra parte, en
AutoCAD nos encontraremos listas continuamente y en todas partes, desde las
coordenadas de los puntos como se indicaba en el artculo anterior, hasta los datos de las
entidades que son almacenados en la base de datos de AutoCAD. As que vamos a
introducir ahora una serie de funciones para manipular listas de elementos.
(CAR lista)
Esta funcin devuelve el primer elemento de la lista que recibe como argumento.
De modo que si (siguiendo con el ejemplo del tema anterior) en la variable pto hemos
asignado el valor devuelto por getpoint, tenemos una lista con las coordenadas X, Y y Z
del punto designado. Supongamos que pto = (10.0 20.0 0.0).
(car pto) devuelve la coordenada X del punto pto. Es decir 10.0
(CDR lista)
Esta funcin devuelve la lista que recibe como argumento pero sin el primer elemento.
(cdr pto) devolver una lista formada por las coordenadas Y y Z del punto pto. Es
decir, (20.0 0.0)
(CADR lista)
Basndonos en las dos funciones anteriores y recordando que podemos ejecutar listas de
instrucciones dentro de otras (a esto le llamamos anidamiento): Cmo se obtendra la
coordenada Y del punto pto? Veamos:
CDR devuelve la lista sin el primer elemento
CAR devuelve el primer elemento de una lista
De modo que (cdr pto) devuelve (Y Z). As que para obtener la coordenada Y podemos
escribir:
(car (cdr pto)) devuelve la coordenada Y del punto pto.
y, cmo obtenemos la coordenada Z? Pues, volviendo a aplicar la funcin CDR para
llegar a la coordenada Z
(cdr pto) devuelve (Y Z)
(cdr (cdr pto)) devuelve (Z)
Podras pensar que escribiendo (cdr (cdr pto)) obtenemos la coordenada Z, sin embargo
no es as. La expresin (cdr (cdr pto)) devuelve una lista con un nico elemento, la
coordenada Z del punto pto. Para obtener la coordenada Z del punto pto tenemos que
escribir:
(car (cdr (cdr pto))) devuelve la coordenada Z del punto pto.
En resumen, las coordenadas del punto pto se obtendrian mediante:
X ==> (car pto)
Y ==> (car (cdr pto))
Z ==> (car (cdr (cdr pto)))
Otras funciones combinando CAR y
CDR
Si en las expresiones indicadas anteriormente para obtener las coordenadas X, Y y Z
ponemos las letras A y D de cAr y cDr en maysculas, lo anterior quedara:
X ==> (cAr pto)
Y ==> (cAr (cDr pto))
Z ==> (cAr (cDr (cDr pto)))
Este ejemplo es simplemente para introducir una simple regla de mnemotecnia ya que las
funciones CAR y CDR se pueden agrupar. Para ello, existen una serie de funciones
que se denominan juntando las Aes y las Des de cAr y cDr respectivamente. El ejemplo
anterior, queda:
X ==> (cAr pto)
Y ==> (cAr (cDr pto)) == (cADr pto)
Z ==> (cAr (cDr (cDr pto))) == (cADDr pto)
Esto nos servir como regla para recordar el nombre de estas funciones. Debes recordar
tambin que tan solo se permiten 4 niveles de anidacin, as que entre la c y la r solo
puede haber 4 letras (Aes o Des).
Supongamos que tenemos la siguiente lista asignada a la variable lst = ((a b) (c
d) (e f)). OJO!! es una lista en la que sus elementos son a su vez listas.
Puedes definir la variable lst escribiendo: (setq lst (list (list a b) (list c
d) (list e f)))
Cmo obtendramos a ??
(car lst) devuelve (a b) que es el primer elemento de lst, y a es el primer
elemento de (a b)as que:
(car (car lst)) devuelve a, o lo que es lo mismo:
(cAAr lst) devuelve a
y el elemento c?
(cDr lst) devuelve la lista sin el primer elemento, es decir ((c d) (e f)).
Ahora si hacemos (cAr (cDr lst)) devuelve el primer elemento de la lista anterior,
es decir (c d).
As que (cAr (cAr (cDr lst))) devuelve c, o lo que es lo mismo:
(cAADr lst) devuelve c
Cmo obtener d ?
(cDr lst) devuelve ((c d) (e f))
(cAr (cDr lst)) devuelve el primer elemento de ((c d) (e f)), es decir
devuelve (c d)
Si ahora hacemos (cDr (cAr (cDr lst))) obtenemos (d), que no es lo mismo
que d. Ya que se trata de una lista cuyo primer elemento es d.
As que (cAr (cDr (cAr (cDr lst)))) devuelve d, o lo que es lo mismo:
(cADADr lst) devuelve d
Y cmo obtener e ?
(cDr lst) devuelve ((c d) (e f))
y (cDr (cDr lst)) devuelve ((e f)). Ojo! se trata de una lista cuyo primer (y
nico) elemento es a su vez otra lista con dos elementos.
As que (cAr (cDr (cDr lst))) devuelve (e f), de modo que
(cAr (cAr (cDr (cDr lst)))) devuelve e, o lo que es lo mismo:
(cAADDr lst) devuelve e
Por ltimo, veamos cmo se obtiene f.
(cAr (cDr (cDr lst))) devuelve (e f) tal como se vio en el ejemplo anterior.
As que (cDr (cAr (cDr (cDr lst)))) devuelve (f), que os recuerdo que se trata de
una lista y que no es lo mismo que f.
Por tanto (cAr (cDr (cAr (cDr (cDr lst))))) devuelve f.
Podramos pensar que (cADADDr lst) tambin devuelve f. Pero al ejecutar esta lnea
AutoCAD nos dice que la funcin cADADDr no est definida.
Ya dijimos antes que se pueden agrupar hasta 4 funciones cAr y cDr,
pero aqu estamos intentando agrupar 5, y lgicamente no podemos. Para
obtener f podramos escribir, por ejemplo:
(cAr (cDADDr lst))
(cADADr (cDr lst))
(LENGTH lista)
En la variable pto tenamos una lista con las coordenadas de un punto, pero si solo
trabajamos en 2D, la coordenada Z no nos interesa. As que muchas veces los puntos tan
slo tendrn 2 coordenadas (X Y). Pero para un programa no es lo mismo que tenga 2
que 3 coordenadas, a lo mejor va a buscar la coordenada Z y no existe producindose un
error en nuestra rutina.
As que necesitamos conocer el nmero de elementos que tienen las listas. Para ello se
utiliza la funcinlength, que devuelve el nmero de elementos de la lista que recibe como
argumento. Por ejemplo:
(length pto) devuelve 3. y si el punto pto estuviera en 2D (X Y) devolvera 2.
Y qu devolvera (length lst) ? siendo lst = ((a b) (c d) (e f)). Pues
devolvera 3, ya que lst es una lista con 3 elementos, que a su vez son listas de dos
elementos cada una.
Qu devolvera (length (car lst)) ? El nmero de elementos del primer elemento de lst, es
decir el nmero de elementos de (a b), que es 2.
(LIST elemento1 elemento2 )
Esta funcin devuelve una lista formada por los elementos indicados. De modo que se
utiliza para crear listas. Por ejemplo:
(list 1 2 3) devuelve (1 2 3)
(list pepe 2 Juan) devuelve (pepe 2 Juan)
Veamos que hace la siguiente expresin:
(list (list a b) c (list d e) f)
Recuerda que en AutoLISP cuando nos encontramos con listas anidadas unas dentro de
otras, siempre se evalan primero las listas interiores.
(list a b) devuelve (a b)
(list d e) devuelve (d e)
As que (list (list a b) c (list d e) f) devuelve la siguiente lista ((a b) c
(d e) f).
Ejecutar comandos de AutoCAD
Una de las mayores ventajas de la programacin en AutoLISP es la posibilidad de
ejecutar directamente comandos de AutoCAD en nuestras rutinas.
(COMMAND comando [datos])
Esta es la funcin que nos permite ejecutar comandos de AutoCAD. Hay dos cosas a
tener en cuenta con esta funcin:
siempre devuelve nil
los nombres de los comandos de AutoCAD, y sus opciones, se indican como
textos por lo que van incluidos entre comillas
(command linea (list 0.0 0.0) (list 100.0 200.0)) Dibujar una lnea desde el origen al
punto 100,200. Pero, nos falta algo: Al dibujar lneas en AutoCAD se van indicando puntos
y siempre pide Siguiente punto: de modo que para terminar el comando LINEA hay
que pulsar INTRO. Pues ese Intro tambin hay que pasrlo a la funcin command:
(command linea (list 0.0 0.0) (list 100.0 200.0) )
Lo realmente potente de COMMAND es que podemos ejecutar casi todos los comandos
de AutoCAD. Cules no? Son muy pocos, por ejemplo Nuevo para empezar un dibujo
nuevo. Pero todos los comandos de dibujo, edicin, etc se pueden ejecutar.
Los datos dependern del comando de AutoCAD indicado. Por ejemplo para el comando
circulo, ser:
(command circulo (list 0.0 0.0) 25.0) Esto dibujar una circunferencia de radio 25 con
centro en el origen.
Los idiomas de AutoCAD
Supongamos que no disponemos de una versin en castellano de AutoCAD, sino que
est en ingls, o en Francs, o Chino Mandarn; qu pasa si ejecutamos esto:
(command linea (list 0.0 0.0) (list 100.0 200.0) )
AutoCAD no conocer el comando linea, as que nos dar un error. Por suerte se puede
solucionar, ya que sino un programa realizado para AutoCAD en Francs slo servira
para las versiones en Francs.
AutoCAD en realidad no habla un nico idioma, sino que es bilingue, dispone de una
lengua que es la que muestra (que corresponde con la versin idiomtica del programa:
Castellano, Francs, etc) y una lengua interna, el Ingls.
De modo que los comandos de AutoCAD (y sus opciones) se pueden escribir en
Castellano o en ingls. Pero para diferenciar unos de otros a los comandos en la lengua
nativa de AutoCAD (Ingls) se les antepone un guin bajo:
(command _circle (list 0.0 0.0) 25.0)
(command _line (list 0.0 0.0) (list 100.0 200.0) )
Las opciones de los comandos tambin se deben indicar en ingls anteponiendo un guin
bajo. Por ejemplo:
(command _circle (list 0.0 0.0) _d 25.0) Esta lnea dibuja una circunferencia
de Dimetro 25 con centro en el origen.
Comandos de AutoCAD originales
Por otra parte, ya se ha dicho anteriormente que los comandos de AutoCAD se podran
redefinir para que funcionen de forma distinta. As se podra cambiar el comando circulo
para que dibuje pentgonos y el comando linea para que dibuje circunferencias.
Si redefinimos el comando lnea para que dibuje circunferencias, entonces deberamos
indicar algo similar a (command linea centro radio) en lugar de (command linea
pt0 pt1 ). Pero cmo haramos entonces para dibujar una lnea?
Para ejecutar los comandos originales de AutoCAD, y no los redefinidos (si lo estn)
debemos anteponer al nombre del comando un punto, por ejemplo:
(command .circulo (list 0.0 0.0) 25.0)
(command .linea (list 0.0 0.0) (list 100.0 200.0) )
Podemos adems indicar los comandos en Ingls anteponiendo un guin bajo as que
tambin los podramos escribir as:
(command ._circle (list 0.0 0.0) 25.0)
(command _.circle (list 0.0 0.0) 25.0)
Da igual si se pone antes el punto o el guin bajo.
Redefinir un comando de AutoCAD
Para redefinir un comando de AutoCAD debemos:
1. Ejecutar el comando ANULADEF (En Ingls undefine) indicando el nombre del
comando a redefinir. De este modo se elimina la definicin del comando de AutoCAD,
y la nica forma de ejecutarlo ser anteponiendo al nombre del comando un punto.
2. Crear y cargar una macro en la que est definido un nuevo comando con el
nombre del comando que acabamos de anular.
Veamos un ejemplo:
1. primero anulamos la definicin del comando lnea.
1. Podemos hacerlo desde AutoCAD con el comando ANULADEF (En
ingls undefine)
2. o desde AutoLISP ejecutando: (command anuladef
linea) o (command _undefine _line)
2. podemos comprobar que el comando lnea ya no funciona
1. Puedes tratar de ejecutarlo en castellano, en ingls, directamente en
AutoCAD o en una expresin de AutoLISP
2. la nica forma de ejecutarlo es anteponiendo a su nombre un punto
.linea.
3. Iniciamos el editor de Visual LISP: Herr. >AutoLISP > Editor de Visual LISP
1. Creamos la macro que se indica a continuacin, la guardamos y la
cargamos en AutoCAD
(defun C:LINEA ( )
(setq pt (getpoint Centro del crculo: ))
(setq rad (getreal Radio del crculo))
(command ._circle pt rad)
)
Ahora el comando linea dibujar crculos.
Para recuperar el valor original del comando podemos hacer dos cosas:
1. cerrar AutoCAD y abrirlo de nuevo, de modo que la macro que hemos creado se
borre de la memoria del ordenador
2. ejecutar el comando de AutoCAD redefine (En Ingls es igual, pero con un guin
bajo delante) e indicarel nombre del comando del que queremos recuperar su
definicin original, es decir linea.
Bueno, por ltimo un ejercicio: Crear una macro que defina un nuevo comando de
Autocad llamadoCIRCPERI que dibuje una circunferencia indicando su centro y la longitud
de su permetro.
Operaciones de comparacin
En este artculo veremos las funciones de AutoLISP que nos permiten realizar
comparaciones, por ejemplo, para ver si algo es mayor que algo, o menor, o si es igual.
(= expr1 expr2 )
Compara si expr1 devuelve el mismo resultado que expr2, en caso afirmativo
devuelve T y en caso contrario devuelve nil.
(= 5 (+ 1 4)) devuelve T porque (+ 1 4) devuelve 5
(= 5 (+ 1 4.0)) devuelve T aunque (+ 1 4.0) devuelve 5.0 y no 5. Pero 5 y 5.0 valen lo
mismo, no?
(= 5 5.0) devuelve T
No solo podemos evaluar nmeros, tambin textos:
(setq txt1 Curso de Lisp)
(= txt1 Curso de Lisp) devuelve T
(= txt1 Curso de LISP) devuelve nil. No es lo mismo un texto en maysculas que en
minsculas.
(= LISP Lisp) devuelve nil
Estamos comparando expresiones, as que:
(= (+ 1 5) (/ 12 2)) devuelve T porque ambas expresiones devuelven como resultado 6.
La funcin = puede aceptar ms de dos expresiones:
(= 6 (+ 1 5) 6.0 (/ 12 2)) devuelve T, pues las cuatro expresiones devuelven 6 o 6.0 (que
vale lo mismo).
(/= expr1 expr2 )
Es muy similar a la anterior. Devuelve T si las expresiones no devuelven el mismo valor y
devuelve nil si todas las expresiones devuelven el mismo valor.
(/= 6 6.0) devuelve nil, porque 6 y 6.0 no son distintos (valen lo mismo).
(/= (+ 5 5) (/ 12 2)) devuelve T, pues la primera expresin devuelve 10 y la segunda 6.
(/= LISP Lisp) devuelve T
(< expr1 expr2 )
Compara si expr1 es menor q expr2
(< 4 5) devuelve T, ya que 4 es menor que 5
(< 4 -5) devuelve nil
(< 5 5.0) devuelve nil
Si se ponen ms de 2 expresiones, se comprueba que estn ordenadas de menor a
mayor y devuelve T si lo estn y nil si no lo estn.
(< 1 2 3) devuelve T
(< 1 2 0) devuelve nil
(< (+ 1 2) (* 2 2.0) (/ 12 2)) devuelve T
Tambin podemos comparar textos. El interprete de AutoLISP evala los cdigos ASCII
de los textos. Es decir los ordena alfabticamente de la a a la z.
(< Albacete Barcelona) devuelve T
(< a c) devuelve T
(< d c) devuelve nil
(< C c) devuelve T, puesto que los cdigos ASCII de la maysculas son inferiores a
los de las letras minsculas.
Los cdigos ASCII, son una serie de nmeros que se asignaron a las letras del alfabeto y
a algunos de los carcteres ms usuales.
El carcter a tiene asociado el cdigo 97, la b el 98, etc. hasta la z.
El carcter A tiene asociado el cdigo 65, la B el 66, etc. hasta la Z.
(> expr1 expr2 )
Supongo que ya os imaginis como funciona, no? Comprueba si las expresiones estn
ordenadas de mayor a menor.
(> 5 3) devuelve T
(> -2 3) devuelve nil
(> 5 2 3) devuelve nil
(> 5 4 3) devuelve T
Y ahora con los textos:
(> a c) devuelve nil, pues el cdigo ASCII de a es menor que el de c.
(<= expr1 expr2 )
Comprueba si las expresiones son menores o iguales que las anteriores.
(<= 1 2 2.0 3) devuelve T
(<= 1 3.0 2 3) devuelve nil
(>= expr1 expr2 )
Comprueba si las expresiones son mayores o iguales que las anteriores
(>= 3 2 2.0 1) devuelve T
(>= 3 1.0 2 1) devuelve nil
(>= 3 3 3 3) devuelve T
Macro de ejemplo
Veamos como se hara el ejercicio propuesto en el artculo anterior: Crear un nuevo
comando llamadoCIRCPERI que dibuje una circunferencia indicando su centro y la
longitud de su permetro.
Qu es lo primero que hay que hacer? Esta respuesta tiene que ser instintiva, como un
acto reflejo: El pseudocdigo.
Siempre comenzaremos nuestras rutinas escribiendo el pseudocdigo (o haciendo un
diagrama de flujo) de lo que se pretende hacer. Bien, cmo podra ser el pseudocdigo de
esta rutina?, vamos a ver:
1. Pedir al usuario el centro de la circunferencia.
2. Pedir al usuario el permetro de la circunferencia.
3. Calcular el radio de la circunferencia a partir de su permetro.
4. Dibujar la circunferencia.
Una vez que terminamos el pseudocdigo, ya tenemos el 80% de la rutina. Si el
pseudocdigo es correcto, el traducirlo a cdigo es de lo ms simple.
Iniciamos en editor de Visual LISP Herr. > AutoLISP > Editor de Visual LISP y
creamos una nueva macro. Primero hay que aadir la definicin del nuevo comando
CIRCPERI:
(defun C:CIRCPERI ( )
Vamos a ver que es lo que nos indica el pseudocdigo:
1) Pedir al usuario el centro de la circunferencia. Podramos escribir (getpoint Centro de
la circunferencia) pero tendramos que almacenar el punto indicado en una variable, as
que aadiremos
(setq pto (getpoint Centro de la circunferencia)) almacena el punto centro de la
circunferencia en la variable pto.
2) Pedir al usuario el permetro de la circunferencia. Por
ejemplo (setq peri (getint Permetro:)) pero al usar getint, solo permite obtener
nmero enteros. As que podramos cambiarlo por:
(setq peri (getreal Permetro:)) almacena el permetro de la circunferencia en la
variable peri
3) Calcular el radio de la circunferencia a partir de su permetro. Peri = 2* pi * rad as que
rad = Peri / ( 2 * pi). Traduciendo esta frmula a cdigo:
(setq rad (/ peri (* pi 2))) calcula el valor del radio de la circunferencia
4) Dibujar la circunferencia
(command _.circle pto rad) dibuja la circunferencia
Slo nos falta una cosa. Recuerda: El nmero de parntesis de apertura tiene que ser
igual al nmero de parntesis de cierre. As que:
)
El cdigo completo de la rutina sera:
(defun C:CIRCPERI ( )
(setq pto (getpoint Centro de la circunferencia))
(setq peri (getreal Permetro:))
(setq rad (/ peri (* pi 2)))
(command _.circle pto rad)
)
Tambin deberas aadir comentarios al cdigo y una cabecera con varias lneas de
comentarios en el archivo .LSP indicando: El nombre de la rutina, fecha, autor, etc.
Te das cuenta de la importancia del pseudocdigo? Al programar nos ha guiado paso a
paso.
Operaciones lgicas en AutoLISP
Existe una serie de funciones de AutoLISP que nos permiten realizar operaciones lgicas.
Suelen emplearse en combinacin con las operaciones de comparacin.
(AND expr1 expr2 )
Esta funcin devuelve T si ninguna de las expresiones que recibe como argumento es
(devuelve) nil. Si una sola de las expresiones devuelve nil, la funcin AND devolver nil.
Es decir, comprueba que se cumplan todas las expresiones que recibe como argumento.
(and (< 3 4) (= 5 5.0)) devuelve T, porque las dos expresiones devuelven T
(and (> 3 4) (= 5 5.0)) devuelve nil, porque (> 3 4) devuelve nil
En el ejemplo anterior, como la primera expresin (> 3 4) devuelve nil, ya no
se continan evaluando el resto de expresiones. Cmo hay una expresin que
devuelve nil, AND devolver nil. De modo que la expresin (=5 5.0) ya no se evala.
Vamos a complicarlo un poco Qu devolver la siguiente expresin?
(and (= 5 5.0) (< 3 4) Soy un texto 5.8)
Preguntando de otra forma: Alguna de las expresiones que recibe AND como
argumentos es nil? No, as que AND devuelve T.
(setq a Soy otro texto b 15 c T d nil)
(and a b) devolver T
(and a d) devolver nil porque d es nil
(and a b c d) devolver nil, porque d es nil
(OR expr1 expr2 )
Devuelve nil si todas las expresiones son nil. En caso de que alguna de las expresiones
no devuelva nil, OR devuelve T. Es decir, comprueba si alguna de las expresiones se
cumple.
(or (/= 5 5.0) (> 3 4)) devuelve nil, porque ambas expresiones son nil
(or (= 5 5.0) (> 3 4)) devuelve T, pues la primera expresin se cumple
En el ejemplo anterior, como la primera expresin (= 5 5.0) devuelve T, ya no
se continan evaluando el resto de expresiones. Cmo hay una expresin que
devuelve T, OR devolver T. De modo que la expresin (> 3 4)ya no se evala.
(setq a Soy otro texto b 15 c T d nil)
(or a b) devuelve T
(or c d) devuelve nil
(or d d) devuelve nil
(EQUAL expr1 expr2 [precision])
En el tema anterior vimos la funcin de comparacin = que nos sirve para determinar si
dos nmeros o textos son iguales. Pero que pasa si queremos comparar otra cosa, por
ejemplo dos listas (como dos puntos).
(setq pt1 (list 10.0 20.0 0.0) pt2 (list 10.0 (* 10.0 2) 0.0) pt3 (list 9.99 20.0
0.0) pt4 (list 9.99 20.02 0.0))
Al comparar estas listas (puntos) con la funcin = siempre nos devuelve nil.
Aunque pt1 y pt2 sean iguales, y muy parecidos a pt3 y pt4. Por tanto, la funcin = no
nos servir para comparar listas. Para comparar dos listas se utilizar la funcin
EQUAL.
(equal 5 5.0) devuelve T, al igual que la funcin =, porque 5 vale lo mismo que 5.0
(equal pt1 pt2) devuelve T
EQUAL adems ofrece un argumento opcional [precisin]. Veamos como funciona :
(equal 4.99 5.0 0.1) devuelve T, porque compara 4.99 y 5 pero con una precisin de 0.1.
As que con esa precisin 4.99 == 5.0
Sin embargo, si subimos la precisin
(equal 4.99 5.0 0.001) devuelve nil
Y qu pasa con las listas? Tambin podemos indicarle una precisin? Veamos..
(equal pt1 pt3 0.1) devuelve T, porque compara los elementos de las listas
(coordenadas) con la precisin que hemos indicado, 0.1
Si subimos la precisin
(equal pt1 pt3 0.001) devuelve nil
(equal pt1 pt4 0.01) devuelve nil
(equal pt1 pt4 0.02) devuelve T, porque la precisin es 0.02 que es exactamente la
diferencia entre 20.02 y20
El utilizar una precisin muy elevada no implica que todas las comparaciones
devuelvan T, todo depender de los valores a comparar:
(equal 15 20 100) devuelve T
(equal 5000 4200 100) devuelve nil
(NOT expr)
A esta funcin le gusta llevarle la contraria a la expresin que recibe como argumento.
si la expresin devuelve nil, entonces NOT devuelve T.
si la expresin devuelve cualquier cosa que no sea nil,
entonces NOT devuelve nil.
(not 5) devuelve nil
(not Texto) devuelve nil
(not (+ 5 1)) devuelve nil
Si hacemos
(setq a 5 b nil c T d Nuevo texto)
(not b) devolver T, porque b es nil
(not c) devolver nil.
Veamos que devuelve la siguiente expresin:
(and (not c) 5)
Como c es T, (not c) devuelve nil. Al no cumplirse la primera expresin de AND, esta
devuelve nil y no contina evaluando.
Estructuras condicionales simples
Hasta ahora nuestro cdigo ha sido completamente lineal, las lneas de cdigo que
escribamos se ejecutaban una tras otra en el mismo orden. En este tema veremos un tipo
de funciones que nos permitirn bifurcar el cdigo, de modo que ya no exista un nico
camino sino dos o ms. Veamos un ejemplo en pseudocdigo:
1. Introducir el lmite inferior
2. Introducir el lmite superior
3. El lmite superior es menor que el inferior?
1. SI> Mensaje El lmite superior debe ser mayor que el inferior
2. NO > intervalo = lmite superior lmite inferior
(IF condicin expr_si_cumple
[expr_no_cumple])
La funcin IF es una de las ms empleadas al programar. Devuelve el valor de la ltima
expresin evaluada. Si condicin es distinto de nil, entonces evala la expr_si_cumple.
Si condicin devuelve nil evala laexpr_no_cumple, si existe y si no existe no hace
nada. Veamos algunos ejemplos:
(if (= 2 2.0) (alert Los nmeros son iguales))
La condicin a evaluar es: (= 2 2.0) en la que tenemos un nmero entero 2 y uno real 2.0,
pero su valor es el mismo. Aunque sean de distinto tipo 2 y 2.0 valen igual. As que la
condicin devuelve T, evalundose la condicin si cumple que muestra un mensaje de
alerta. La funcin IF devuelve el valor de la ltima expresin evaluada, es decir alert, que
es nil.
(if (= 2 3) (alert Los nmeros son iguales))
En este caso la condicin devuelve nil y al no existir expresin no cumple, no hara nada
ms. Qu valor devolvera IF? El de siempre, el valor de la ltima expresin evaluada,
que en este caso ha sido la propia condicin que devuelve nil. De modo
que IF devolver nil.
(if (= 2 3)
(alert Los nmeros son iguales)
(alert Los nmeros son distintos)
)
En este caso el cdigo se ha escrito en varias lneas y tabulado para facilitar su
comprensin. Ahora si tenemos una expresin no cumple, que ser evaluada ya que la
condicin devuelve nil.
Veamos el siguiente ejemplo:
(setq liminf (getint \nLmite inferior:))
(setq limsup (getint \nLmite superior:))
(if (> liminf limsup)
(alert El lmite superior debe ser mayor que el
inferior) (setq limsup (getint \nLmite superior:)) (setq intervalo (- limsup liminf))
(setq intervalo (- limsup liminf))
)
Viendo el cdigo anterior, tal vez pienses que si la condicin (> liminf limsup) se cumple,
entonces se evaluar la lnea siguiente de cdigo completa. Pero no es as, se evala la
expresin si cumple, que es la primera expresin (alert El lmite superior debe ser
mayor que el inferior).
Si la condicin no se cumple, devuelve nil, se evaluar la expresin no cumple, que en
este caso ser (setqlimsup (getint \nLmite superior)).
Tanto la expresin si cumple, como la no cumple solo pueden ser una nica
expresin. El ejemplo de cdigo anterior nos dara un error ya que IF no puede tener ms
que 3 expresiones:
La condicin
La expresin si cumple
La expresin no cumple
(PROGN expr1 expr2 )
Para que se pueda indicar ms de una expresin si cumple, o no cumple, en la
funcin IF se suele emplear la funcin PROGN. El valor devuelto por PROGN es el de la
ltima expresin que recibe como argumento. Esta funcin en realidad no hace nada, tan
solo nos permite agrupar una serie de expresiones.
Cmo quedara el ejemplo anterior?
(setq liminf (getint \nLmite inferior:))
(setq limsup (getint \nLmite superior:))
(if (> liminf limsup)
(progn
(alert El lmite superior debe ser mayor que el inferior)
(setq limsup (getint \nLmite superior:))
(setq intervalo (- limsup liminf))
)
(setq intervalo (- limsup liminf))
)
En este caso la condicin si cumple es todo lo siguiente:
(progn
(alert El lmite superior debe ser mayor que el inferior)
(setq limsup (getint \nLmite superior:))
(setq intervalo (- limsup liminf))
)
Si se cumple la condicin, se evala la condicin si cumple, es decir el progn. De modo
que se van evaluando las expresiones contenidas en la funcin PROGN, que devuelve el
valor de la ltima expresin(setq intervalo (- limsup liminf)), que ser el valor de la
variable intervalo.
En caso de que la condicin no se cumpla, se evala la condicin no
cumple, (setq intervalo (- limsup liminf)) que curiosamente tambin devuelve el valor de
la variable intervalo.
Veamos ahora algunos ejemplos ms de estructuras condicionales:
(if (and (= 2 2.0) (< 2 3))
(alert Las dos condiciones se cumplen)
(alert Al menos una condicin no se cumple)
)
En este caso la condicin es (and (= 2 2.0) (< 2 3)) que en este caso devolvera T, ya que
se verifican las dos expresiones que recibe la funcin AND.
(if (not var1)
(alert Variable no definida)
(alert Variable definida)
)
En este caso si var1 es nil, (not var1) devolver T, indicando que la variable no se ha
definido. En caso contrario, (not var1) devolver nil evalundose la expresin no cumple.
Otro mtodo para hacer lo mismo, sera:
(if var1
(alert Variable definida)
(alert Variable no definida)
)
Si var1 es distinto de nil, se evala la expresin si cumple. En caso de que var1 sea nil,
se evaluara la expresin no cumple.
Estructuras condicionales mltiples
Con la funcin IF tan solo podemos indicar una condicin y dos opciones, si cumple y no
cumple. Veamos ahora como se pueden indicar varias condiciones con sus respectivas
expresiones si cumple.
(COND (condicion1 [expr1_1]
[expr1_2] ) [ (condicion2
[expr2_1] [expr2_2] ) ] )
Esta funcin es similar a IF en cuanto a que se indican condiciones y una serie de
expresiones que se evaluaran si se verifica cada condicin. En este caso no existe la
limitacin de indicar tan slo una nica expresin si cumple, se pueden indicar tantas
como se desee. COND evaluar la primera condicin encontrada, si se verifica evaluar
las expresiones si cumple de dicha condicin. En caso de que no se verifique, evaluar la
siguiente expresin.
Por lo tanto, COND evaluar las expresiones si cumple de la primera condicin que se
verifique. Y devolver el resultado de evaluar la ltima expresin si cumple. Pongamos un
ejemplo:
(cond
((= a b)
(alert A y B son iguales)
(setq b (getreal Introduzca de nuevo B: ))
)
((< a c)
(alert A es menor que C)
)
((< a b))
(T
(alert A no es igual a B)
(alert A no es menor que C)
(alert A no es menor que B)
)
)
Supongamos ahora que antes de la expresin COND, hemos
definido (setq a 2 b 2.0 c 3.5). En este caso, al entrar en COND se evaluar la primera
condicin (= a b) que se verifica, de modo que se evaluaran las expresiones si cumple de
esta condicin: (alert A y B son iguales) y (setq b (getreal Introduzca de nuevo
B: )) finalizando la expresin COND que devuelve el nuevo valor de b.
Aunque la siguiente condicin (< a c) se cumple, no se evala, ya que existe una
condicin anterior que tambin se cumpla.
En caso de que se hubiera definido (setq a 2 b 2.5 c 3.5) la primera condicin (= a b) no
se verifica, de modo que se evala la segunda condicin (< a c) que si se cumple.
Evalundose sus expresiones si cumple (alertA es menor que C) que devuelve nil.
Si fuera (setq a 2 b 2.5 c 1.5) la primera condicin en cumplirse sera la tercera (< a
b) que no tiene expresiones si cumple. Qu devolver entonces la funcin COND? Pues
el valor de la ltima expresin evaluada, es decir el valor devuelto por la condicin (< a
b) que es T.
Por ltimo, si tenemos (setq a 2 b 1.0 c 1.5) ninguna de las tres condiciones anteriores se
verifica, de modo que pasamos a la siguiente condicin T, que lgicamente siempre
devuelve T, as que siempre se verifica. Esto se suele utilizar mucho en la funcin COND,
aadir como ltima condicin una que se verifique siempre. En lugar de T se poda haber
puesto (not nil) o (= 1 1.0) que tambin son expresiones que siempre se cumplen. Para
qu aadir una expresin que siempre se cumple? Muy sencillo, para incluir el cdigo que
se desea ejecutar en caso de que no se verifique ninguna de las condiciones anteriores.
Y qu sucede si se pone la condicin T como primera condicin? Pues sucede que las
que estn a continuacin nunca se evaluarn, ya que T siempre se cumplir. Si en el
ejemplo anterior hubiramos puesto:
(cond
(T
(alert A no es igual a B)
(alert A no es menor que C)
(alert A no es menor que B)
)
((= a b)
(alert A y B son iguales)
(setq b (getreal Introduzca de nuevo B: ))
)
((< a c)
(alert A es menor que C)
)
((< a b))
)
Independientemente de los valores de las variables a b y c siempre nos mostrar los
mensajes de alerta indicando que A no es igual a B, A no es menor que C y A no
es menor que B.
Mostrar textos al usuario en AutoLisp
Hay varias funciones para mostrar textos al usuario en AutoLisp. De momento vamos a
ver un par de ellas, pero habr ms.
(PROMPT mensaje)
Muestra el texto indicado como argumento en pantalla, y siempre devuelve nil.
(prompt Bienvenidos al Curso)
(ALERT mensaje)
Muestra el texto que recibe como argumento en un letrero. Tambin devuelve nil. Se
utiliza principalmente para avisar al usuario en caso de error, o para mostrar alguna
informacin importante.
(alert Error: Dato no vlido)
(TERPRI)
En artculo correspondiente a las Operaciones de comparacin, creamos un nuevo
comando para AutoCAD denominado CIRCPERI. Si has cargado y ejecutado el comando,
habrs observado que los mensajes para solicitar el centro de la circunferencia y su
permetro aparecen en la misma lnea de la ventana de comandos y sin separacin entre
s, estn pegados.
Para que los mensajes aparezcan en lneas distintas, se puede emplear la
funcin TERPRI. Esta funcin mueve el cursor a una nueva lnea en la ventana de
comandos de AutoCAD, y devuelve nil. El cdigo de la rutina quedara as:
(defun C:CIRCPERI ( )
(setq pto (getpoint Centro de la circunferencia)) (terpri)
(setq peri (getreal Permetro:)) (terpri)
(setq rad (/ peri (* pi 2)))
(command _.circle pto rad)
)
As los mensajes de solicitud aparecern en lneas separadas.
Los caracteres de control
Como ya se ha comentado anteriormente, AutoLISP no reconoce una serie de caracteres.
Por ejemplo, al indicar la ruta de un archivo no reconoce el carcter \ y hay que indicarlo
as: \\. Pues existen ms caracteres de control predefinidos:
\\ Equivale al caracter \
\ Equivale al caracter
\e Equivale a ESCape
\n Equivale al retorno de carro
\r Equivale a pulsar Intro
\t Equivale a pulsar la tecla del tabulador
\ nos permite escribir las comillas dentro de un texto. Por ejemplo:
(alert Esto son un par de comillas \ o no?)
La nica comilla que se tiene que ver es la que est escrita as: \ . Las otras nos indican
donde comienza y termina el texto, nada ms.
(alert Texto en lnea 1\nTexto en lnea 2)
Se pone 1\nTexto todo junto. Para qu poner espacios?
(alert Texto en lnea 1\n Texto en lnea 2)
Si lo ponemos as, aade un espacio en blanco al principio de la segunda lnea. Por eso
se pone todo seguido.
(alert Texto en lnea 1\n\tTexto en lnea 2)
En este ejemplo la segunda lnea est tabulada.
Entonces, cmo quedara el cdigo de la rutina CIRCPERI utilizando caracteres de
control, en lugar de la funcin (TERPRI)?
(defun C:CIRCPERI ( )
(setq pto (getpoint \nCentro de la circunferencia))
(setq peri (getreal \nPermetro:))
(setq rad (/ peri (* pi 2)))
(command _.circle pto rad)
)
Un par de cosas ms con respecto a esta rutina Cuando se crea un archivo LISP en el
que est definido un nuevo comando es bastante til aadir al final de todo el cdigo algo
similar a
(prompt \nNuevo comando CIRCPERI cargado)
Esta lnea se pondra despus del parntesis de cierre de defun. Es decir, que cuando se
ejecuta CIRCPERIdesde AutoCAD esta lnea no se evala. Para qu ponerla entonces?
Pues muy sencillo para que cuando se cargue el archivo en AutoCAD muestre en
pantalla: Nuevo comando CIRCPERI cargado. As el usuario sabe cual es el nombre del
comando definido en el archivo que se acaba de cargar. De modo que el mensaje slo se
mostrar al cargar el archivo.
Por otro lado si recordamos la estructura de la funcin DEFUN: (DEFUN
nombre_funcin ( argumentos / variables_locales ) expr1 expr2 )
Veremos que en la rutina CIRCPERI no hemos indicado variables locales, as que todas
las variables sern globales. Es decir que al ejecutar CIRCPERI y dibujar un crculo, luego
nos quedan accesibles los valores de las variables pto, peri y rad desde AutoCAD,
ocupando y malgastando memoria. As que vamos a ponerlas como locales. Slo habra
que cambiar la siguiente lnea
(defun C:CIRCPERI ( / pto peri rad )
OJO! la barra inclinada / hay que ponerla, sino seran argumentos y no variables locales.
El cdigo completo de la rutina es el siguiente:
;;;____________________Eduardo Magdalena____________________;;;
;;;______________________CIRCPERI.LSP_________________________;;;
;;;_______________________Versin 1.1_________________________;;;
;;;________________________26/02/2002_________________________;;;
;;; Comando para dibujar una circunferencia indicando su centro y la longitud
;;; de su permetro.
(defun C:CIRCPERI ( / pto peri rad )
(setq pto (getpoint \nCentro de la circunferencia))
(setq peri (getreal \nPermetro:))
(setq rad (/ peri (* pi 2)))
(command _.circle pto rad)
)
(prompt \nNuevo comando CIRCPERI cargado)
Las variables de sistema de AutoCAD
El modo en que funciona el entorno de AutoCAD, y la forma de trabajar de muchos de sus
comandos, se ven afectados por los valores asignados a las variables de sistema. Podra
decirse que controlan como trabaja AutoCAD. Por lo tanto, se pueden modificar los
valores asignados a las variables de sistema para personalizar AutoCAD para un usuario
en concreto, para un tipo de trabajo determinado, e incluso para un archivo de dibujo. De
modo que nos facilite el trabajo.
Tipos de variables de sistema
Las variables de sistema pueden almacenar distintos tipos de datos, en funcin de la
informacin que contengan. Podran clasificarse del siguiente modo:
Activada / Desactivada. Muchas variables de sistema slo admiten dos opciones:
Activada y Desactivada. Normalmente tienen asignado el valor 0 cuando estn
desactivadas, y 1 cuando estn activadas. Un ejemplo de este tipo de variables es
blipmode.
Nmeros enteros. Otras variables tienen ms de dos posibilidades, para lo que
asignan un nmero entero para cada opcin. Normalmente emplean nmeros
correlativos, empezando desde el cero. Una variable que utiliza este tipo de datos es
coords.
Cdigos binarios. Algunas variables pueden emplear varias opciones a la vez,
para lo que suelen emplear cdigos binarios. A cada opcin se le asigna el nmero
resultante de elevar 2 a n. Asignando an nmeros enteros correlativos a partir del
cero. Es decir, los valores para las distintas opciones sern: 1,2,4,8,16,32,etc. De
modo que para seleccionar la primera y cuarta opciones, hay que asignar a la variable
la suma de sus valores: 1+8 = 9. Un ejemplo muy interesante de este tipo de variables
es osmode.
Nmeros reales. Las variables que almacenan valores de ngulos o distancias,
por ejemplo, utilizan este tipo de valores. Un ejemplo de este tipo es la variable
chamfera.
Puntos. Este tipo de entidades almacenan las coordenadas de un punto, un buen
ejemplo es ucsorg.
Cadenas de texto. Hay bastantes variables que almacenan cadenas de texto,
como nombres de archivos o rutas de directorios. Ejemplos de este tipo de variables
son acadver y acadprefix.
Modificar los valores de las variables
de sistema
Podramos clasificar las variables de sistema en funcin del lugar en el que se guardan:
No guardadas. La informacin asignada a este tipo de entidades no se guarda.
Un ejemplo de este tipo de variables es acadver.
En el dibujo. La mayora de las variables de sistema son de este tipo, de modo
que cada dibujo trabajar con unos valores determinados para las variables de
sistema. Esto hace sumamente importante la definicin de los valores de las variables
de sistema en las plantillas utilizadas para crear nuevos dibujos. Un ejemplo de
variable guardada en el dibujo es luprec.
En el registro. Algunas variables de sistema se guardan en el registro de
Windows. Por ejemplo attdia.
La mayora de las variables de sistema de AutoCAD pueden editarse, modificando el valor
que tengan asignado. Pero algunas variables son de solo lectura, de modo que no se
pueden modificar, tan solo leer. Un ejemplo de variable de solo lectura es cdate.
Hay varios mtodos para modificar los valores asignados a las variables de sistema de
AutoCAD:
Tecleando el nombre de la variable, como si fuese un comando ms de AutoCAD.
Ejecutando el comando MODIVAR e indicando la variable a modificar.
Algunos comandos de AutoCAD permiten modificar los valores asignados a
algunas variables de sistema. Por ejemplo el comando MARCAAUX permite
modificar el valor asignado a la variable blipmode.
Algunas variables se modifican al ejecutar algn comando de AutoCAD. Por
ejemplo circlerad almacena el radio de la ltima circunferencia creada con el
comando crculo.
Las variables de sistema en los
programas de AutoLISP
Los programadores suelen leer y modificar el contenido de algunas variables de sistema
de AutoCAD, ya que esto les permite definir el modo en el que desean que se comporte
AutoCAD o algunos comandos de AutoCAD.
Esto puede ocasionar cambios en los valores asignados a algunas de las variables de
sistema. Al programar deberas seguir los siguientes consejos para que esto no suceda:
Deberas guardar los valores iniciales de las variables de sistema que se necesite
modificar, y asignarles sus valores iniciales al terminar el programa.
Crear una funcin de tratamiento de errores, de modo que si se produce algn
error al ejecutar el programa se restablezcan los valores iniciales de las variables de
sistema. La creacin de funciones de tratamiento de errores la trataremos ms
adelante.
(GETVAR variable)
Esta funcin devuelve el valor asociado a la variable que recibe como argumento. Por
ejemplo:
(getvar osmode)
(getvar blipmode)
(getvar acadver)
(SETVAR variable nuevo_valor)
Asigna a la variable indicada un nuevo valor, y devuelve dicho valor.
(setvar blipmode 0)
(setvar osmode 32)
Veamos un ejemplo combinando las funciones GETVAR y SETVAR. Escribe lo siguiente
en la lnea de comandos de AutoCAD:
(getvar luprec)
(setvar luprec 2)
(getvar luprec)
Funciones de conversin de datos en AutoLISP
Vamos a ver una serie de funciones que nos permitirn pasar un entero a real, a un texto
o al revs
(ITOA entero)
Convierte un entero en un texto. Integer TO Atom.
(itoa 24) devuelve 24
(ATOI texto)
Hace justo lo contrario que la funcin anterior. Convierte un texto en un nmero. Atom TO
Integer
(atoi 24) devuelve 24
(atoi -7) devuelve -7
Y que pasa si hacemos (atoi soy un texto) pues que devuelve 0. Siempre que
escribes algo que no sea un nmero devuelve cero.
(atoi 15.3) devuelve 15
(atoi 15.99999) devuelve 15
(FLOAT numero)
Convierte un nmero en real, as que lo lgico es que reciba un entero como argumento.
(float 5) devuelve 5.0
pero tambin podemos pasar un nmero real como argumento (float 5.36) que
devuelve 5.36 lo cual sera una tontera porque en ese caso la funcin float no hace nada.
(ATOF texto)
Convierte un texto en real.
(atof 15.7) devuelve 15.7
(atof 15) devuelve 15.0
(atof -15.7) devuelve -15.7
(atof soy un texto) devuelve 0.0
(RTOS numero [modo [precision]])
La ltima funcin de este tipo que vamos a ver es algo ms complicada, pero no mucho.
Convierte un real en texto. Real TO String.
(rtos 2.5) devuelve 2.5
(rtos 2) devuelve 2 y no 2.0
Veamos para qu sirven los argumentos opcionales [modo [precisin]]. Modo, permite
indicar un tipo para expresar los nmeros, es decir, permite seleccionar el formato
utilizado para los nmeros. Hay 5 opciones:
Formato cientfico.
Decimal. Es el que se usa habitualmente.
Pies y pulgadas.
Pies y pulgadas en fracciones.
Fracciones.
Por ejemplo
(rtos 2.5 5) devuelve 2 1/2
(rtos 2.5 1) devuelve 2.5000E+00
Precisin nos permite definir el nmero de decimales que deseamos, por ejemplo:
(rtos 1.23456789 2 3) devuelve 1.235 as que redondea el nmero para que tenga 3
decimales.
(rtos 9.99 2 0) devuelve 10
Obtener distancias y ngulos del usuario
Hemos visto como se obtienen nmeros, puntos y textos del usuario. Ahora le vamos a
solicitar directamente una distancia o un ngulo.
(GETDIST [pto_base] [mensaje])
Solicita una distancia y devuelve esa distancia como un nmero real. El usuario podr
indicar la distancia por medio de un nmero o indicando 2 puntos en pantalla.
(getdist Distancia de desplazamiento:)
El mensaje es opcional, pero casi siempre se utiliza. Tambin podemos asignar el
resultado a una variable:
(setq dist1 (getdist Distancia de desplazamiento:))
En muchas ocasiones se puede reemplazar a la funcin GETREAL por GETDIST si lo
que se pide se puede relacionar con alguna distancia del dibujo. Por ejemplo, en nuestra
rutina CIRCPERI podramos dibujar una circunferencia de permetro la longitud de una
recta.
El argumento opcional [pto_base] funciona de modo similar a como lo hace
en GETPOINT permitiendo indicar la distancia a partir de un punto de origen ya
predefinido:
(setq pto (getpoint Punto base))
(setq dist1 (getdist pto Distancia de desplazamiento:))
(GETANGLE [pto_base] [mensaje])
Solicita un ngulo al usuario que puede escribirlo o designarlo por medio de dos puntos.
Devuelve el ngulo en radianes, aunque el usuario lo escribira en las unidades actuales
(generalmente grados decimales). Por ejemplo, a la expresin:
(getangle ngulo: )
el usuario responde 180.0
y getangle, devuelve pi.
Esta funcin toma como origen de ngulos el actual, que suele coincidir con el sentido
positivo del eje X delSCU (Sistema de Coordenadas Universal). Pero siempre
considerar como sentido positivo de los ngulos el antihorario.
El parmetro opcional [pto_base] permite indicar un punto a partir del cual indicar el
ngulo.
(GETORIENT [pto_base] [mensaje])
Es casi igual a GETANGLE, y tambin se utiliza para solicitar un ngulo al usuario. La
nica diferencia es que el origen de ngulos siempre es el del sentido positivo del eje X
del SCU (Sistema de Coordenadas Universal).
(getangle ngulo: )
Aadir algunos cambios a nuestra
macro CIRCPERI
Vamos ahora a modificar un poco la macro CIRCPERI. Tenamos el siguiente cdigo:
(defun C:CIRCPERI ( / pto peri rad )
(setq pto (getpoint \nCentro de la circunferencia: ))
(setq peri (getreal \nPermetro: ))
(setq rad (/ peri (* pi 2)))
(command _.circle pto rad)
)
(prompt \nNuevo comando CIRCPERI cargado)
Si sustituimos la funcin getreal por getdist adems de poder escribir un permetro
directamente, tambin podremos indicarlo mediante dos puntos.
Eco de mensajes en las macros de AutoLISP
Por otra parte, Si habis ejecutado el comando CIRCPERI veris que lo de los mensajes
queda mejor que al principio pero tampoco es perfecto ya que aparecen unos textos en la
ventana de comandos que no se sabe de dnde salen:
Centro de la circunferencia:
Permetro: Designe segundo punto: _.circle Precise punto central para crculo o
[3P/2P/Ttr (tangente tangente radio)]:
Precise radio de crculo o [Dimetro]: 23.00636765228087
Esto queda bastante feo y como hay que ser profesionales, vamos a ponerlo bien. Hemos
visto las funcionesGETVAR y SETVAR que nos permiten acceder a las variables de
sistema de AutoCAD. Pues hay una variable que controla el eco de mensajes, es decir,
el que aparezcan esos mensajes en pantalla. La variable se llama CMDECHO y solo
admite dos valores posibles:
0 Desactivada
1 Activada
Por defecto debera estar activada (1) as que se veran los mensajes raros de antes.
Cmo evitamos que aparezcan estos mensajes? Pues desactivando la variable.
Pero no conviene modificar los valores de las variables de sistema, porque tal vez el
usuario los quiera mantener como estaban. De modo que se
desactivar momentneamente el valor de la variable en medio de la macro y al terminar
la rutina se dejar con su valor inicial, es decir tal como estaba.
Esto es ms bien una filosofa de vida: Si al entrar en un sitio, la puerta estaba
cerrada, vuelve a cerrarla
As que nuestro cdigo quedara
(defun C:CIRCPERI ( / pto peri rad )
(setvar cmdecho 0) ; Desactiva el eco de mensajes
(setq pto (getpoint \nCentro de la circunferencia: ))
(setq peri (getdist \nPermetro: ))
(setq rad (/ peri (* pi 2)))
(command _.circle pto rad)
(setvar cmdecho 1) ; Vuelve a activar el eco de mensajes
)
(prompt \nNuevo comando CIRCPERI cargado)
Efectivamente los mensajes raros desaparecen, pero Qu pasa si al entrar en una
habitacin, la puerta ya estaba abierta? la cerramos o la dejamos abierta de nuevo?. Lo
mejor es que todo quede tal como lo encontramos. As nadie nos dir Por qu
cerraste la puerta?. Y si lo dice, le respondes: Perdona, pero mi macro, deja las cosas
tal y como estaban, as que o ya estaba cerrada antes o la cerraron despus.
Si cmdecho est inicialmente desactivada nuestra rutina la desactiva, o lo intenta, y luego
la activa al final de la macro. Quedando por lo tanto cmdecho activada. As que vamos a
modificar el cdigo para que cmdechoquede con el valor que tena antes de ejecutar la
macro
Lo primero que tenemos que saber es si la puerta est cerrada, si est cerrada la abrimos
y si ya est abierta no hacemos nada, simplemente pasamos.
(getvar cmdecho) me dir si cmdecho est activada o desactivada. Veamos que es lo
que hay que hacer:
1. Si la puerta est cerrada, la abro. Es decir, si cmdecho est activada, la
desactivo.
2. Aqu metemos el cdigo de la macro CIRCPERI
3. Si antes de entrar la puerta estaba cerrada, entonces la cierro. Es decir,
si cmdecho estaba activada, entonces la vuelvo a activar.
El punto 1 suena claramente a una estructura condicional simple, as que emplearemos la
funcin IF:
(if (= (getvar cmdecho) 1)
(setvar cmdecho 0)
)
Y cmo haramos al final de la rutina en el punto 3? Sera otro condicional, pero
necesitamos conocer el valor que tena inicialmente la variable cmdecho para saber si
estaba activada o desactivada. De modo que hay que modificar el cdigo anterior para
que en el punto 1 se almacene el valor de cmdecho.
(if (= (setq cmd0 (getvar cmdecho)) 1)
(setvar cmdecho 0)
)
De este modo la variable cmd0 almacena el valor inicial de cmdecho. Es bastante
habitual almacenar los valores iniciales en variables cuyo nombre sea del tipo cmd0,
osm0 o blip0 pues el 0 nos indica que almacena el valor inicial.
Ahora ya podemos poner el cdigo del punto 3. Podramos hacerlo de dos formas:
(setvar cmdecho cmd0)
Esta lnea de cdigo asignara a cmdecho el valor que tena inicialmente.
(if (= cmd0 1)
(setvar cmdecho 1)
)
En este caso, si cmdecho estaba inicialmente activada entonces la activa. Si no estaba
inicialmente activada, es decir estaba desactivada, entonces no hace nada
porque cmdecho ya est desactivada, al igual que al principio.
El cdigo quedara as:
(defun C:CIRCPERI ( / pto peri rad cmd0 )
(if (= (setq cmd0 (getvar cmdecho)) 1)
(setvar cmdecho 0)
)
(setq pto (getpoint \nCentro de la circunferencia: ))
(setq peri (getdist \nPermetro: ))
(setq rad (/ peri (* pi 2)))
(command _.circle pto rad)
(if (= cmd0 1)
(setvar cmdecho 1)
)
)
(prompt \nNuevo comando CIRCPERI cargado)
Salida limpia de las macros de AutoLISP
Al ejecutar ahora la rutina los mensajes son ms limpios. Sin embargo al final muestra el
valor devuelto por la ltima expresin evaluada de la funcin:
Si la variable cmdecho inicialmente es 0. La condicin del if devuelve nil, se
termina la funcin y se muestra en la pantalla nil
Si la variable cmdecho inicialmente es 1. La condicin del if devuelve T, se evala
la condicin-si-cumple del if (setvar cmdecho 1) que devuelve 1, se termina la
funcin y se muestra en la pantalla 1
Para que la salida de nuestras macros sea limpia aadiremos al final del cdigo una
funcin que devuelvauna cadena de texto vaca, as no escribir nada.
Podramos pensar en utilizar la expresin (prompt ) al terminar nuestras macros. Sin
embargo la expresin anterior no devuelve una cadena de texto vaca sino que
devuelve nil.
Suelen emplearse las funciones (princ) o (prin1) que an no hemos visto, pero
que devuelven una cadena de texto vaca.
Finalmente el cdigo resultante ser:
(defun C:CIRCPERI ( / pto peri rad cmd0 )
(if (= (setq cmd0 (getvar cmdecho)) 1)
(setvar cmdecho 0)
)
(setq pto (getpoint \nCentro de la circunferencia: ))
(setq peri (getdist \nPermetro: ))
(setq rad (/ peri (* pi 2)))
(command _.circle pto rad)
(if (= cmd0 1)
(setvar cmdecho 1)
)
(prin1)
)
(prompt \nNuevo comando CIRCPERI cargado)
El comando deshacer en las rutinas de AutoLISP
En este artculo no vamos a ver ninguna funcin de AutoLISP. Vamos a crear un nuevo
comando y a repasar un poco la macro de CIRCPERI.
Comenzaremos creando un nuevo comando para dibujar arandelas en 2D:
El programa solicitar al usuario el centro de la arandela, el dimetro interior y el
exterior
Se dibujarn dos circunferencias concncricas con los dimetros indicados
Recuerda, antes de ponerse a escribir cdigo hay que: escribir el pseudocdigo.
Veamos, podamos hacer algo as:
1. Obtener el centro de la circunferencia
2. Obtener el radio de la circunferencia interior
3. Dibujar la circunferencia interior
4. Obtener el radio de la circunferencia exterior
5. Dibujar la circunferencia exterior
AutoCAD ya tiene un comando que se llama arandela (en ingls donuts) as que
buscaremos otro nombre para nuestra rutina, por ejemplo ARAND. Es mejor utilizar
nombres ms bien cortos y que evoquen a la funcin que tiene el comando.
La primera lnea de cdigo es la definicin de la funcin:
(defun C:ARAND ( )
Ms adelante podremos aadir las variables locales, si es que existen.
1) Obtener el centro de la circunferencia. Podra ser algo as:
(setq pto (getpoint \nCentro de la arandela: ))
2) Obtener el radio de la circunferencia interior:
(setq radi (getreal \nRadio interior: ))
3) Dibujar el circulo interior
(command _.circle pto radi)
4) Obtener el radio del crculo exterior:
(setq rade (getreal \nRadio exterior: ))
5) Dibujar el circulo exterior
(command _.circle pto rade)
Y por ltimo cerramos el parntesis de la funcin defun
)
El cdigo completo queda as:
(defun C:ARAND ( )
(setq pto (getpoint \nCentro de la arandela: ))
(setq radi (getreal \nRadio interior: ))
(command _.circle pto radi)
(setq rade (getreal \nRadio exterior: ))
(command _.circle pto rade)
)
Ahora vamos a retocar un poco el comando, le aadiremos las siguientes mejoras:
Desactivar el eco de mensajes, es decir desactivar la variable cmdecho al iniciar
la rutina.
Recuperar el valor inicial de cmdecho al terminar la macro.
Aadir una lnea al final del cdigo para que muestre un mensaje indicando el
nombre del nuevo comando al cargar la funcin.
Poner las variables como locales.
En lugar de utilizar GETREAL para obtener el radio, usaremos GETDIST con el
centro de las circunferencias como punto base.
Aadir una lnea al final de la funcin para que la salida del programa sea limpia.
El cdigo despus de realizar las mejoras anteriores sera:
(defun C:ARAND ( / pto rad cmd0 )
(if (= (setq cmd0 (getvar cmdecho)) 1)
(setvar cmdecho 0)
)
(setq pto (getpoint \nCentro de la arandela: ))
(setq rad (getdist pto \nRadio interior: ))
(command _.circle pto rad)
(setq rad (getdist pto \nRadio exterior: ))
(command _.circle pto rad)
(if (= cmd0 1)
(setvar cmdecho 1)
)
(princ)
)
(prompt \nNuevo comando ARAND cargado)
Adems de las mejoras indicadas anteriormente, ahora la variable rad se utiliza tanto para
almacenar el radio de la circunferencia interior como el de la exterior. Puede dar lugar
esto a algn problema? Veamos:
En primer lugar obtenemos el centro de la circunferencia y la asignamos a la variable pto.
(setq pto (getpoint \nCentro de la arandela: ))
Solicitamos el radio de la circunferencia interior y lo asignamos a la variable rad.
(setq rad (getdist pto \nRadio interior: ))
y dibujamos la circunferencia interior
(command _.circle pto rad)
El radio de la circunferencia interior no lo vamos a volver a utilizar en nuestra rutina, de
modo que podemos reutilizar esa variable y asignarle otro valor, el radio de la
circunferencia exterior.
(setq rad (getdist pto \nRadio exterior: ))
Ahora la variable rad almacena el radio de la circunferencia exterior y pto el centro de las
dos circunferencias, de modo que dibujamos la circunferencia exterior.
(command _.circle pto rad)
De este modo ahorramos una variable. As que recuerda:
Si es posible, conviene reutilizar las variables.
Si cargamos la macro y ejecutamos el comando ARAND dibujaremos una arandela
formada por dos circunferencias. Pero qu pasa si despus de dibujar la circunferencia
ejecutamos el comando H (deshacer) de AutoCAD? Pues que deshace el ltimo
comando ejecutado que no es ARAND sino(command _.circle pto rad) de modo
que deshace la circunferencia exterior. Pero la interior no.
Control de deshacer comandos
El comando DESHACER de AutoCAD es distinto al comando H. En realidad, H es
una opcin de DESHACER. Al ejecutar este comando, AutoCAD muestra el siguiente
mensaje: Indique el nmero de operaciones a deshacer o
[Auto/Control/Inicio/Fin/Marca/Retorno] <1>:. Veamos como funcionan estas
opciones:
Nmero de operaciones a deshacer
La opcin por defecto es indicar el nmero de operaciones a deshacer, que por defecto
tiene el valor 1. Esta opcin funciona exactamente igual que el comando H. Pero,
podemos indicarle un nmero de operaciones superior a 1 (cualquier nmero entero entre
1 y 32.767). Esta opcin es til para deshacer los cambios realizados por los ltimos n
comandos.
Control
Al seleccionar Control nos ofrece las siguientes posibilidades: Indique una opcin de
control DESHACER [Todas/Ninguna/Una] <Todas>:
Con la opcin Todas seleccionada (es la opcin por defecto), AutoCAD
almacena en el archivo temporal UNDO.ac$ la informacin sobre los comandos
ejecutados en el dibujo actual y por tanto que se pueden deshacer. Tambin
almacena en el archivo temporal REDO.ac$ la informacin sobre los comandos del
dibujo actual que se han deshecho. Estos archivos se almacenan en el directorio
temporal del sistema operativo. Esta opcin permite deshacer todos los comandos
realizados en el dibujo durante la sesin actual.
Si se selecciona la opcin Una, tan slo se podr deshacer el ltimo comando
ejecutado. Quedando desactivadas todas las opciones del comando DESHACER
excepto Control e Indique el nmero de operaciones a deshacer <1>:
Seleccionando la opcin Ninguna se elimina la capacidad de revocar de los
comandos H y DESHACER, quedando estos desactivados. Y ya no se utilizan los
archivos temporales anteriormente citados.
Lo recomendable es tener siempre activada la opcin Todas.
Marca y Retorno
Estas dos opciones funcionan en pareja. Supongamos que vamos a ejecutar una serie de
comandos en el dibujo actual, pero no sabemos si el resultado obtenido ser el deseado.
En este caso, antes de comenzar puedes ejecutar el comando DESHACER y
seleccionar la opcin Marca. De este modo activas una marca, a la que podrs volver en
cualquier momento ejecutando DESHACER con la opcin Retorno. Al encontrar una
marca AutoCAD mostrar el mensaje Marca encontrada.
Si en lugar de volver a la marca lo que quieres es deshacer un nmero determinado de
comandos, puedes ejecutar el comando H o DESHACER indicando el nmero de
comandos a deshacer.
Adems, puedes definir tantas marcas como desees, y cada vez que ejecutes
DESHACER con la opcin Retorno volvers a la marca anterior. Si no existen ms
marcas, o si no se ha definido ninguna marca, AutoCAD preguntar si se desea deshacer
todo.
Auto
Algunos comandos de AutoCAD, estn formadas por un grupo de rdenes. De modo que
el comando H no anulara todo el grupo de comandos ejecutados, sino slo el ltimo.
Activando esta opcin se agrupan estos comandos en uno slo, a efectos de la aplicacin
de los comandos H y DESHACER.
Inicio y Fin
Estas dos opciones tambin funcionan juntas. Con ellas podemos agrupar una serie de
comandos, de modo que sean tratados como uno solo al ejecutar H o DESHACER.
Si DESHACER con la opcin Auto est activada, AutoCAD coloca
automticamente un DESHACER Inicio y un DESHACER Fin al principio y final
de las opciones de los mens, y deja inutilizadas estas opciones de forma manual.
Con la opcin Auto desactivada, las opciones Inicio y Fin se ejecutan de
forma anloga a como se hace con Marca y Retorno. Si se vuelve a ejecutar la
opcin Inicio sin haber ejecutado la opcin Fin para cerrar un grupo anterior,
AutoCAD entiende que se quiere cerrar el grupo anterior y abrir uno nuevo.
El comando deshacer en las rutinas
de AutoLISP
Utilizando las opciones anteriores del comando deshacer, se puede lograr que todo el
cdigo de nuestras rutinas funcione como si se tratase de un nico comando.
Aadiremos al inicio de nuestra rutina deshacer inicio y al final de la rutina deshacer
fin. Veamos:
(defun C:ARAND ( / pto rad cmd0 )
(command _.undo _begin)
(if (= (setq cmd0 (getvar cmdecho)) 1)
(setvar cmdecho 0)
)
(setq pto (getpoint \nCentro de la arandela: ))
(setq rad (getdist pto \nRadio interior: ))
(command _.circle pto rad)
(setq rad (getdist pto \nRadio exterior: ))
(command _.circle pto rad)
(if (= cmd0 1)
(setvar cmdecho 1)
)
(command _undo _end)
(princ)
)
(prompt \nNuevo comando ARAND cargado)
Deberamos aadir estas dos lneas en la macro CIRCPERI? Pues no es necesario,
puesto que enCIRCPERI tan solo utilizamos un comando. As que el comando de
AutoCAD H va a deshacer ese comando. En cambio en ARAND se dibujan dos
circunferencias con dos comandos de AutoCAD.
Funciones de tratamiento de errores en AutoLISP
Las rutinas que hemos creado (CIRCPERI y ARAND) no estn terminadas todava. Para
terminarlas debemos realizar dos modificaciones:
Controlar lo que hace la rutina en caso de que se produzca un error durante su
ejecucin.
Impedir que el usuario introduzca datos errneos. Por ejemplo, que indique cero
como radio de una circunferencia.
En este artculo se tratar el primero de los dos puntos anteriores, y en el siguiente se
ver el segundo punto.
Si nos fijamos en el cdigo de la macro ARAND: Qu sucede si el usuario como
respuesta a la peticin del radio interior pulsa Intro? Pues que se asigna a la
variable rad el valor nil. De modo que se producir un error al evaluar la siguiente lnea
de cdigo: (command _.circle pto rad). En el siguiente tema veremos cmo se puede
evitar que el usuario introduzca datos errneos. Por ejemplo, evitar que como respuesta a
la peticin del radio interior se introduzca Intro.
Pero una cosa est clara, no siempre vamos a poder controlar todos los posibles errores
en nuestras macros. De modo que necesitamos una funcin de tratamiento de errores que
informe al usuario del tipo de error que se produce. Por ejemplo, indicarle al usuario que
ha introducido un dato incorrecto. AutoCAD en este caso nos dice: ; error: tipo de
argumento errneo: numberp: nil
AutoLISP dispone de una funcin de tratamiento de errores por defecto. Dicha funcin se
llama *error* y recibe como argumento una cadena de texto con la descripcin del error
que se ha producido.
Podemos redefinir la funcin de tratamiento de errores que ofrece AutoLISP, de modo que
se puede personalizar a nuestro gusto en funcin de nuestros intereses. As pues, vamos
a crear una funcin de tratamiento de errores a la que llamaremos ERRORES:
(defun ERRORES ( mens )
(if (= mens quitar / salir abandonar)
(princ)
(princ (strcat \nError: mens ))
)
(princ)
)
No nos paremos demasiado aqu ya lo veremos bien ms adelante. Hemos creado una
funcin llamadaERRORES para el tratamiento de errores en nuestras rutinas. Ahora
habra que decirle al comando ARANDque utilice esta nueva funcin de tratamiento de
errores.
Pero antes, conviene explicar cmo se pueden redefinir las funciones de AutoLISP. Hay
dos mtodos:
1. Crear una funcin con el mismo nombre. Por ejemplo, (defun SIN Esto
redefinir la funcin SIN de AutoLISP.
2. Asignarle un valor distinto mediante setq. Por ejemplo, si hacemos (setq sin
cos) la funcin SIN de AutoLISP pasar a funcionar como la funcin COS,
devolviendo el coseno de un ngulo en lugar de el seno. (sin 0.0) ahora
devolvera 1.0 en lugar de 0.
Veamos ahora el cdigo de la funcin ARAND ya modificada:
(defun C:ARAND ( / pto rad cmd0 error0 )
(command _.undo _begin)
(if (= (setq cmd0 (getvar cmdecho)) 1)
(setvar cmdecho 0)
)
(setq error0 *error* *error* ERRORES)
(setq pto (getpoint \nCentro de la arandela: ))
(setq rad (getdist pto \nRadio interior: ))
(command _.circle pto rad)
(setq rad (getdist pto \nRadio exterior: ))
(command _.circle pto rad)
(setq *error* error0)
(if (= cmd0 1)
(setvar cmdecho 1)
)
(command _.undo _end)
(princ)
)
(prompt \nNuevo comando ARAND cargado)
En la lnea (setq error0 *error* *error* ERRORES) se asigna a la variable error0 la
antigua funcin de tratamiento de errores, *error*. Y se define la funcin de tratamiento de
errores como nuestra funcinERRORES.
Por supuesto, le decimos que use nuestra funcin de tratamiento de errores al principio
del cdigo. Pero siempre despus de desactivar el eco de mensajes.
Hemos redefinido la funcin de tratamiento de errores, pero al terminar la rutina debemos
dejarlo todo como estaba antes. As que recuperamos la funcin de tratamiento de errores
inicial, la que ofrece AutoLISP por defecto. Lo haramos con la siguiente
lnea: (setq *error* erro0) que se debe poner antes de volver a activar el eco de
mensajes.
Para probar la funcin de tratamiento de errores debemos cargarla en AutoCAD.
En la rutina CIRCPERI haramos exactamente lo mismo:
(defun C:CIRCPERI ( / pto peri rad cmd0 error0 )
(if (= (setq cmd0 (getvar cmdecho)) 1)
(setvar cmdecho 0)
)
(setq error0 *error* *error* ERRORES)
(setq pto (getpoint \nCentro de la circunferencia: ))
(setq peri (getdist \nPermetro: ))
(setq rad (/ peri (* pi 2)))
(command _.circle pto rad)
(setq *error* error0)
(if (= cmd0 1)
(setvar cmdecho 1)
)
(princ)
)
(prompt \nNuevo comando CIRCPERI cargado)
Repasemos un poco el funcionamiento de la rutina CIRCPERI: Lo primero que hacemos
es desactivar el eco de mensajes, a continuacin redefinimos la funcin de tratamiento de
errores, despus viene el cdigo de la funcin, se restituye la funcin de tratamiento de
errores de AutoLISP y se recupera el valor inicial de cmdecho (que controla el eco de
mensajes).
Qu diferencia existe entre nuestra funcin de tratamiento de errores y la ofrecida por
defecto por AutoLISP?
Pues casi ninguna, de momento tan slo se diferencia en que si el error que se ha
producido tiene por descripcin quitar / salir abandonar, que equivale a pulsar la tecla
de ESCape, no hace nada. Si el error no se ha producido por pulsar ESC, sino por otra
causa, entonces mostrar un mensaje indicando: Error: Descripcin del error. Un
gran cambio, no? Bueno los cambios vamos a hacerlos ahora que ya sabemos como
funciona la funcin ERRORES.
Cada tipo de error ofrece una descripcin especfica y adems existe un cdigo numrico
asociado a la variable de sistema ERRNO en la que se almacena el cdigo
correspondiente al ltimo error que se ha producido. Puedes ver en este enlace una lista
de los cdigos y mensajes de error de AutoLISP.
Qu sucede si el usuario introduce un dato incorrecto al solicitarle el permetro? En ese
caso, en la siguiente lnea (setq rad (/ peri (* pi 2))) se producira un error, inicindose la
funcin de tratamiento de errores. Cuando se produce el error, ya se ha evaluado la
lnea (setq error0 *error* *error* ERRORES) enCIRCPERI, de modo que hemos
redefinido la funcin de tratamiento de errores. As que se ejecuta la funcinERRORES,
que muestra la descripcin del error que se produjo. Pero, salimos de la
funcin ERRORES y no hemos recuperado el valor de la funcin de tratamiento de
errores que nos ofrece por defecto AutoLISP. Y tambin se ha desactivado el eco de
mensajes, pero no recuperamos su valor inicial.
De modo que vamos a modificar la funcin ERRORES para aadir estos pequeos
cambios:
(defun ERRORES ( mens )
(setq *error* error0)
(if (= mens quitar / salir abandonar)
(princ)
(princ (strcat \nError: mens ))
)
(if (= cmd0 1)
(setvar cmdecho 1)
)
(princ)
)
Ahora nuestra funcin ERRORES restituye el valor inicial del eco de mensajes y la funcin
de tratamiento de errores inicial. Puede extraar que se utilicen las
variables cmd0 y error0 dentro de la funcin ERRORES, ya que estaban definidas como
variables locales en CIRCPERI.
Cuando definimos una variable local en una funcin, esta variable se puede utilizar slo
dentro de esa funcin. Pero, si desde CIRCPERI llamamos a otra funcin, por
ejemplo ERRORES, en realidad estamos dentro de ERRORES, que est dentro
de CIRCPERI. As que seguimos dentro de CIRCPERI.
Otra de las principales aplicaciones de redefinir la funcin de tratamiento de errores tiene
que ver con el tema anterior, los comandos deshacer en las rutinas de AutoLISP.
Si nos fijamos en el cdigo de la rutina ARAND, vemos que la primera lnea
es (command _.undo _begin) Qu sucedera si se produce un error despus de
dibujar el segundo crculo? Dara un error, y terminara el comando sin ejecutar la
lnea (command _.undo _end). Con lo cual para deshacer la
arandela deberamos ejecutar el comando H (deshacer) dos veces, una por cada crculo.
Es ms, imagina que nuestra rutina no dibuja 2 circunferencias sino 120 y que el error se
produce al dibujar la circunferencia ensima
Podramos entonces modificar la funcin de tratamiento de errores y aadir la lnea de
cdigo:
(command _.undo _end)
Ahora, bastara con ejecutar el comando deshacer una nica vez para que se deshaga
todo lo que hizo el comando ARAND.
Podemos incluso decirle a la funcin ERRORES que si se produce un error, ejecute el
comando deshacer directamente:
(defun ERRORES ( mens )
(setq *error* error0)
(if (= mens quitar / salir abandonar)
(princ)
(princ (strcat \nError: mens ))
)
(command _.undo _end)
(command _.undo )
(if (= cmd0 1)
(setvar cmdecho 1)
)
(princ)
)
En este caso si se produce un error ni siquiera hace falta ejecutar el comando deshacer,
la funcinERRORES ya lo hace por nosotros.
Para terminar este artculo, vamos a aadir una nueva opcin a CIRCPERI. Se trata de
que ofrezca por defecto el permetro de la ltima circunferencia dibujada. Podramos
hacer lo siguiente:
(defun C:CIRCPERI ( / pto peri cmd0 )
(if (= (setq cmd0 (getvar cmdecho)) 1)
(setvar cmdecho 0)
)
(setq pto (getpoint \nCentro de la circunferencia: ))
(if (not rad)
(prompt \nPermetro: )
(progn
(prompt \nPermetro <)
(prompt (rtos (* rad 2 pi) 2 2))
(prompt >: )
)
)
(if (setq peri (getdist))
(setq rad (/ peri (* 2 pi)))
)
(command _.circle pto rad)
(if (= cmd0 1)
(setvar cmdecho 1)
)
(princ)
)
(prompt \nNuevo comando CIRCPERI cargado)
Ponemos la variable rad como global, as se puede recuperar el valor que tena en la
anterior ejecucin deCIRCPERI. Veamos ahora cmo funciona el siguiente trozo de
cdigo:
(if (not rad)
(prompt \nPermetro: )
(progn
(prompt \nPermetro <)
(prompt (rtos (* rad 2 pi) 2 2))
(prompt >: )
)
)
Si rad es igual a nil, no se ha definido, significa que es la primera vez que se ejecuta el
comando CIRCPERIen el dibujo actual. En este caso se muestra un mensaje solicitando
el permetro del crculo.
Si no es la primera vez que se ejecuta CIRCPERI, la variable rad tendr asociado un
valor, correspondiente al radio del circulo creado en la ltima ejecucin de CIRCPERI.
Tambin muestra un mensaje solicitando el permetro, pero entre los caracteres < y >
se indica adems el valor de la variable global rad.
(if (setq peri (getdist))
(setq rad (/ peri (* 2 pi)))
)
A continuacin se solicita una distancia. No se ha indicado ningn mensaje en la
funcin getdist, ya que el mensaje de solicitud se muestra en las lneas anteriores. Si se
indica un permetro, ya sea por medio de dos puntos o escribindolo directamente,
entonces se calcula su radio. Si como respuesta a getdist se pulsa Intro, a la
variable peri se asigna el valor nil, que es devuelto por setq. De modo que en este caso
no hace nada, por lo tanto la variable rad sigue almacenando el radio del ltimo crculo
creado con CIRCPERI.
(command _.circle pto rad)
Por ltimo dibuja el crculo.
AutoCAD dispone de una variable de sistema llamada CIRCLERAD en la que almacena
el valor del ltimo circulo dibujado. As que podemos utilizar esta variable de sistema para
obtener el radio del ltimo crculo, en lugar de utilizar la variable rad como global. El
cdigo sera el siguiente:
(defun C:CIRCPERI ( / pto rad peri cmd0 )
(if (= (setq cmd0 (getvar cmdecho)) 1)
(setvar cmdecho 0)
)
(setq pto (getpoint \nCentro de la circunferencia: ))
(if (= (getvar circlerad) 0.0)
(prompt \nPermetro: )
(progn
(prompt \nPermetro <)
(prompt (rtos (* (getvar circlerad) 2 pi) 2 2))
(prompt >: )
)
)
(if (setq peri (getdist))
(setq rad (/ peri (* 2 pi)))
(setq rad (getvar circlerad))
)
(command _.circle pto rad)
(if (= cmd0 1)
(setvar cmdecho 1)
)
(princ)
)
(prompt \nNuevo comando CIRCPERI cargado)
Ahora ofrecer por defecto el permetro del ltimo crculo dibujado en AutoCAD,
independientemente de si dicho crculo se creo con la rutina CIRCPERI, con el
comando CIRCULO o por cualquier otro medio. Veamos como funcionan los cambios que
hemos realizado:
(if (= (getvar circlerad) 0.0)
(prompt \nPermetro: )
(progn
(prompt \nPermetro <)
(prompt (rtos (* (getvar circlerad) 2 pi) 2 2))
(prompt >: )
)
)
Si an no se ha creado ningn crculo en el dibujo, la variable circlerad tendr asociado
el valor 0.0. En este caso solicita el permetro sin ofrecer ningn valor por defecto, y en
caso contrario ofrece por defecto el permetro del ltimo crculo creado.
(if (setq peri (getdist))
(setq rad (/ peri (* 2 pi)))
(setq rad (getvar circlerad))
)
Si se introduce un permetro, por medio de dos puntos o escribindolo se calcula el radio
correspondiente. En caso de que se pulse Intro, se asocia a la variable rad el radio del
ltimo crculo dibujado.
Limitar las respuestas de los usuarios
En el artculo anterior vimos las funciones de tratamiento de errores, que nos permiten
controlar lo que sucede cuando se produce un error en nuestras macros. En esta ocasin
intentaremos que no se produzcan alguno de los posibles errores en las macros.
Los errores pueden deberse a que el cdigo no funciona bien por que se ha empleado
mal alguna funcin de AutoLISP o se ha ejecutado incorrectamente un comando de
AutoCAD, por ejemplo, pero estos no son los tipos de errores que corregiremos en este
tema. Ms adelante veremos mtodos de depuracin de nuestras rutinas y corregiremos
los errores debidos a un cdigo fuente incorrecto.
Ahora trataremos otro tipo de errores, los que se producen cuando el usuario introduce
datos errneos Por ejemplo, cuando se solicita un nmero positivo y el usuario indica
cero o un nmero negativo.
(INITGET [modo] [palabras_clave])
Esta funcin se utiliza para modificar el funcionamiento de otras funciones de AutoLISP,
en concreto aquellas funciones en las que se solicitan datos al usuario. Por
ejemplo: GETpoint, GETreal, GETint, casi todas comienzan por GET as que se
suelen denominar funciones de tipo GET.
Initget siempre devuelve nil. Y si se indica solo, sin argumentos, no hace nada. Tan solo
devuelve nil. As que vamos a ver para que sirven los argumentos de Initget:
modo
Es un nmero entero que nos permitir limitar los datos que se puedan introducir en la
siguiente solicitud de datos al usuario. Initget NUNCA funciona por si sola, siempre se
utiliza para modificar el funcionamiento de otra funcin.
El argumento modo es en realidad un cdigo binario, que puede tener los siguientes
valores:
1 > No admite valores nulos, es decir que se indique Intro como respuesta
2 > No admite el 0 como respuesta
4 > No admite valores negativos como respuesta
8 > Permite indicar un punto fuera de los lmites del dibujo. An cuando estos
estn activados.
16 > Este valor no se utiliza actualmente
32 > Dibuja la lnea o rectngulo elsticos con lneas discontnuas en lugar de
contnuas
64 > Hace que GETdist devuelva la distancia en 2D. Es como si proyectase la
distancia real sobre el plano XY.
128 > Permite introducir como respuesta una expresin de AutoLISP.
Bien, veamos como se utiliza initget. Por ejemplo, si queremos que el usuario introduzca
un nmero entero y que no pueda pulsar Intro como respuesta, haramos lo siguiente:
(initget 1)
(setq numero (getint \nNmero entero: ))
Initget modifica a la siguiente funcin de solicitud de datos, es decir, getint.
Si adems queremos que no pueda indicar 0 como respuesta, entonces sumamos sus
respectivos cdigos, el1 para que no se pueda indicar Intro como respuesta y el 2 para
que no se pueda indicar 0.
(initget (+ 1 2))
(setq numero (getint \nNmero entero: ))
Tambin podemos indicar directamente (initget 3) en lugar de (initget (+ 1 2)). Si el
usuario indica como respuesta 0 o Intro, AutoCAD le dir que ese dato no es vlido y que
introduzca un dato correcto.
Si queremos que adems se indique un nmero positivo, entonces deberamos poner:
(initget 7)
(setq numero (getint \nNmero entero: ))
Ya que 7 = 1 + 2 + 4
Veamos ahora como funciona el cdigo 8 como argumento modo de Initget.
8 > Permite indicar un punto fuera de los lmites del dibujo. An cuando estos
estn activados.
Supongamos que tenemos los lmites del dibujo de AutoCAD activados
(comando LIMITES) en ese caso no podemos indicar puntos fuera de esos lmites. De
modo que si se solicita un punto al usuario conGETPOINT deber indicarlo dentro de los
lmites del dibujo. Pero si antes de solicitar el punto se ejecuta(initget 8) entonces si nos
dejara.
El cdigo 16 no se utiliza.
El cdigo 32 se utiliza en funciones de solicitud en las que se indica un punto
base, por ejemplo:
(getpoint pto \nIndicar punto:)
(getcorner pto \nIndicar punto:)
En estos casos aparece una lnea, o un rectngulo, elstico con origen en el punto
base pto. Estas lneas y rectngulos elsticos se muestran con lnea continua. Pero si
antes de la funcin de solicitud se aade(initget 32) se mostraran con
lneas discontinuas. Por ejemplo:
(setq pt1 (getpoint \nPunto base: ))
(initget 32)
(setq pt2 (getpoint pt1 \nSegundo punto: ))
En este ejemplo aparece una lnea discontinua. Y en el siguiente un rectngulo con lneas
discontinuas.
(setq pt1 (getpoint \nPunto base: ))
(initget 32)
(setq pt2 (getcorner pt1 \nSegundo punto: ))
Veamos ahora como funciona el cdigo 64
64> Hace que GETdist devuelva la distancia en 2D. Es como si proyectase la
distancia real sobre el plano XY.
Getdist solicita una distancia, que se puede escribir directamente, o se pueden indicar
dos puntos en pantalla. En este caso, getdist devolver la distancia real entre esos dos
puntos. Si lo que nos interesa obtener es la distancia de sus proyecciones sobre el plano
XY actual se aadir (initget 64) antes de la ejecutar getdist. Por ejemplo:
(setq pt1 (getpoint \nPunto base: ))
(initget 64)
(setq dist12 (getdist pt1 \nSegundo punto: ))
Por ltimo, el cdigo 128 permite indicar una expresin de AutoLISP como respuesta. Por
ejemplo, podemos utilizar nuestra rutina RAG (Radianes A Grados decimales) para
indicar un ngulo en grados decimales cuando nosotros lo tenemos en radianes.
(initget 128)
(setq ang (getreal \nIntroducir ngulo: ))
En este caso el usuario podra indicar como respuesta a la solicitud del ngulo: (RAG (/
pi 4)) Es decir, un ngulo de 45.
Pues llegados a este punto, antes de ver el segundo argumento de (INITGET [modo]
[palabras_clave]), es decir, las palabras clave. Vamos a modificar nuestras
rutinas ARAND y CIRCPERI.
Si revisamos el cdigo de la macro CIRCPERI encontraremos la siguiente lnea:
(setq pto (getpoint \nCentro de la circunferencia: ))
deberamos aadir alguna limitacin como respuesta del usuario? Veamos:
Si el usuario pulsa Intro como respuesta a la variable pto se le asocia el valor nil,
que es lo que devolvera Getpoint. Despus al intentar dibujar el
crculo (command _.circle pto rad) se producira un error. As que debemos
impedir que el usuario introduzca Intro como respuesta, de modo que
aadiramos (initget 1) antes de la funcin getpoint.
Como estamos solicitando un punto, el cdigo 2 no tiene sentido y lo mismo
sucede con el 4.
El cdigo 8 permite indicar un punto fuera de los lmites del dibujo, an cuando
estos estn activados. Este cdigo si podramos utilizarlo, aunque si el usuario trabaja
con los lmites activados, estn activados y ya est. Si quiere que los desactive l, no?
Porque supongo que los tendr activados por algn motivo. As que no le aadimos
a initget el cdigo 8.
El cdigo 32 no tiene sentido aqu, pues no aparece la lnea base.
Y el cdigo 64 tampoco ya que estamos solicitando un punto, no una distancia.
El cdigo 128 permite introducir como respuesta una expresin de AutoLISP. Este
cdigo tambin se podra indicar, pero lo habitual es no hacerlo. Se podra utilizar en
casos en los que el usuario pudiera utilizar una expresin de AutoLISP para calcular el
dato. Como en el ejemplo que vimos antes, si tiene un ngulo en radianes y lo tiene
que indicar en grados decimales. Aqu nos pide un punto, as que no tiene demasiado
sentido.
Definitivamente el cdigo quedara:
(initget 1)
(setq pto (getpoint \nCentro de la circunferencia: ))
Sigamos modificando la rutina CIRCPERI: Unas lneas despus de la solicitud del centro
de la circunferencia, se solicita su permetro:
(if (setq peri (getdist))
(setq rad (/ peri (* 2 pi)))
(setq rad (getvar circlerad))
)
Deberamos aadir la funcin initget con el cdigo 1 antes de la funcin getdist?
Veamos como funciona esta parte del cdigo: Si el usuario introduce una distancia, se
evala la condicin si cumple del IF es decir:
(setq rad (/ peri (* 2 pi)))
Y si el usuario pulsa Intro, se asigna a peri el valor nil y evala la condicin no cumple
del IF, es decir:
(setq rad (getvar circlerad))
Si aadimos antes del getdist la expresin (initget 1), el usuario no podr
indicar Intro, as que nunca se ejecutara la expresin no cumple. Por tanto no
aadimos el cdigo 1 a Initget.
El permetro del crculo no puede ser ni cero ni un nmero negativo, de modo que
podemos aadir ainitget los cdigos 2 y 4.
Tambin podramos aadir el cdigo 64 para que GETdist devuelva la distancia
en 2D. Pero normalmente no conviene aadir este cdigo, excepto cuando la
distancia deba ser siempre ser en 2D.
Una ltima nota sobre CIRCPERI: Cuando ejecutamos la macro por primera vez en un
dibujo en el que no se ha dibujado ningn crculo, la variable de sistema circlerad tiene
el valor 0.0. En este caso, no ofrecemos la opcin de seleccionar el radio del ltimo
crculo dibujado pulsando Intro, ya que no existe ningn crculo dibujado previamente. En
este caso, no deberamos indicar el modo 6 a Initget, sino el 7 para que tampoco permita
al usuario indicar Intro como respuesta. Veamos como se soluciona en el cdigo completo
de la rutina:
(defun C:CIRCPERI ( / pto rad peri cmd0 )
(if (= (setq cmd0 (getvar cmdecho)) 1)
(setvar cmdecho 0)
)
(initget 1)
(setq pto (getpoint \nCentro de la circunferencia: ))
(if (= (getvar circlerad) 0.0)
(progn
(prompt \nPermetro: )
(initget 7)
)
(progn
(prompt \nPermetro <)
(prompt (rtos (* (getvar circlerad) 2 pi) 2 2))
(prompt >: )
(initget 6)
)
)
(if (setq peri (getdist))
(setq rad (/ peri (* 2 pi)))
(setq rad (getvar circlerad))
)
(command _.circle pto rad)
(if (= cmd0 1)
(setvar cmdecho 1)
)
(princ)
)
(prompt \nNuevo comando CIRCPERI cargado)
Vamos ahora a modificar la rutina ARAND. La primera solicitud que tenemos
en ARAND es la del centro de la arandela. Prcticamente es igual que la solicitud del
centro del crculo en CIRCPERI, as que le aadimos tambin el cdigo 1 a Initget:
(initget 1)
(setq pto (getpoint \nCentro de la arandela: ))
A continuacin solicita los radios interior y exterior de la arandela. En los que podemos
evitar que el usuario indique como respuesta Intro, 0 o un nmero negativo. Por lo tanto
aadiremos Initget con el modo 7. Veamos el cdigo completo:
(defun C:ARAND ( / pto rad cmd0 )
(command _.undo _begin)
(if (= (setq cmd0 (getvar cmdecho)) 1)
(setvar cmdecho 0)
)
(initget 1)
(setq pto (getpoint \nCentro de la arandela: ))
(initget 7)
(setq rad (getdist pto \nRadio interior: ))
(command _.circle pto rad)
(initget 7)
(setq rad (getdist pto \nRadio exterior: ))
(command _.circle pto rad)
(if (= cmd0 1)
(setvar cmdecho 1)
)
(command _undo _end)
(princ)
)
(prompt \nNuevo comando ARAND cargado)
Limitar las respuestas de los usuarios (II)
(initget [modo] [palabras_clave])
En el ltimo artculo del curso comenzamos a ver la funcin INITGET y vimos como
funcionaba el argumento[modo] ahora vamos con [palabras_clave]:
[palabras_clave] nos permite indicar una serie de textos (palabras) que tambin sern
aceptados como respuesta en la siguiente funcin de solicitud de datos. Por ejemplo:
(initget 7 Dimetro Permetro)
(setq rad (getdist \nRadio del circulo / Dimetro / Permetro :))
como respuesta a getdist podemos indicar una distancia, ya sea escribiendo un valor
numrico o mediante dos puntos, pero ahora tambin aceptar como respuesta
Dimetro y Permetro. El modo 7 impide que se indique como respuesta Intro, cero o
un nmero negativo.
Si indicamos como respuesta una distancia, asocia esa distancia a la varible rad.
Si indicamos como respuesta Dimetro, asocia a la variable rad la cadena de
texto Dimetro.
Si indicamos como respuesta Permetro, asocia a la variable rad la cadena de
texto Permetro.
En [palabras_clave] indicamos una serie de palabras, separadas por espacios, que
servirn como respuesta a la siguiente funcin de solicitud de datos.
No hace falta escribir el nombre completo de la palabra, como hicimos antes, basta con
que el usuario introduzca como respuesta las letras que aparecen en maysculas. Es
decir, la D o la P.
En el siguiente ejemplo:
(initget 7 Dimetro desHacer)
(setq rad (getdist \nRadio del circulo / Dimetro / desHacer: ))
Para seleccionar la opcin Dimetro habr que escribir al menos la D. Pero para
seleccionar desHacer al menos habr que escribir H. Tambin aceptara di para el
dimetro y desh para deshacer.
Sin embargo no aceptar de ni des para seleccionar desHacer. Fjate que al menos
deben indicarse las letras en maysculas.
Por otra parte, aceptar tanto di como dia sin tilde para seleccionar Dimetro.
Supongamos que tenemos el siguiente cdigo:
(initget 7 Dimetro desHacer)
(setq rad (getdist \nRadio del circulo: ))
En este caso getdist aceptar como respuestas a la peticin del radio de la circunferencia
Dimetro y desHacer. Pero al no indicar estas opciones en el mensaje de getdist, el
usuario no sabr que existen. De modo que es recomendable indicar al usuario las
opciones que puede seleccionar:
(initget 7 Dimetro desHacer)
(setq rad (getdist \nRadio del circulo / Dimetro / desHacer :))
Como mejor se ve es con un ejemplo as que, vamos a modificar la
rutina ARAND aadiendo una opcin para indicar el dimetro en lugar del radio. Tenemos
que modificar las siguientes lneas:
(initget 7)
(setq rad (getreal \nRadio interior: ))
Primero aadimos Dimetro a la lista de palabras clave de initget:
(initget 7 Dimetro)
Y a continuacin le decimos al usuario que existe una opcin llamada Dimetro que
puede seleccionar como respuesta:
(setq rad (getreal \nRadio interior / Diametro: ))
De esta forma ya hemos aadido la opcin Dimetro
Pero, qu sucede si el usuario indica como respuesta la opcin Dimetro? Pues que
asignamos a la variable rad la cadena de texto Dimetro y en la siguiente
lnea (command _.circle pto rad) al intentar dibujar la circunferencia, nos da un error.
As que hay que modificar la rutina aadiendo a continuacin algo parecido a:
Si el usuario selecciona la opcin Dimetro > Preguntamos por el dimetro.
Pues esto en AutoLISP, sera:
(if (= rad Dimetro)
(setq rad (getreal \nDimetro interior: ))
)
Hay que tener especial cuidado con la condicin del IF (= rad Dimetro) ya que hay
que indicar la palabra clave tal y como aparece en la lista de palabras clave de initget.
Es decir, no funcionara si ponemos (= rad dimetro) o (= rad Diametro) ya que en
el primer caso no ponemos la D en maysculas y en el segundo no hemos tildado la a.
Fjate en lo que hace el cdigo anterior:
Si el usuario indica una distancia la asigna a la variable rad y luego (if (= rad
Dimetro) devuelvenil, puesto que rad es distinto de Dimetro.
Si el usuario indica D o Diam, o dimetro, entonces asigna a la variable rad la
cadena de texto Dimetro. Luego al entrar en el IF, (= rad
Diametro) devuelve T as que evala la expresin si
cumple (setq rad (getreal \nDimetro interior: )) que pide un dimetro al usuario y
lo asigna a la variable rad.
Pero rad viene de radio, porque en esta variable almacenamos el radio de la
circunferencia y no el dimetro. As que al dibujar la
circunferencia (command _.circle pto rad) dibujara una circunferencia del doble
del dimetro de lo que ha dicho el usuario.
El cdigo debera ser:
(initget 7 Dimetro)
(setq rad (getreal \nRadio interior / Dimetro: ))
(if (= rad Dimetro)
(setq rad (/ (getreal \nDimetro interior: ) 2.0))
)
Pero, Qu pasa si el usuario hace lo siguiente?
Indica D como respuesta al radio interior.
Indica -50 o 0 como dimetro.
Pues que asignara a la variable rad el resultado de dividir -50 o 0 entre 2.0. Por tanto
tendramos una circunferencia con radio negativo o cero.
Recuerda que initget solo tiene efecto sobre la siguiente funcin de solicitud de datos, de
modo que tenemos que aadir de nuevo la funcin Initget antes de preguntar por el
dimetro:
(initget 7 Dimetro)
(setq rad (getreal \nRadio interior / Dimetro: ))
(if (= rad Dimetro)
(progn
(initget 7)
(setq rad (/ (getreal \nDimetro interior: ) 2.0))
)
)
Se ha aadido la funcin Progn ya que sino, solo se puede ejecutar una expresin como
condicin si-cumple del IF.
Para el radio o dimetro exterior se hara exactamente lo mismo. Por tanto el cdigo
completo ser:
(defun C:ARAND ( / pto rad cmd0 )
(command _.undo _begin)
(if (= (setq cmd0 (getvar cmdecho)) 1)
(setvar cmdecho 0)
)
(initget 1)
(setq pto (getpoint \nCentro de la arandela: ))
(initget 7 Dimetro)
(setq rad (getdist pto\nRadio interior / Dimetro: ))
(if (= rad Dimetro)
(progn
(initget 7)
(setq rad (/ (getreal \nDimetro interior: ) 2.0))
)
)
(command _.circle pto rad)
(initget 7 Dimetro)
(setq rad (getdist pto \nRadio exterior / Dimetro: ))
(if (= rad Dimetro)
(progn
(initget 7)
(setq rad (/ (getreal \nDimetro exterior: ) 2.0))
)
)
(command _.circle pto rad)
(if (= cmd0 1)
(setvar cmdecho 1)
)
(command _undo _end)
(princ)
)
(prompt \nNuevo comando ARAND cargado)
(GETKWORD [mensaje])
Esta funcin de AutoLISP se utiliza para obtener una opcin indicada por el usuario. Se
utiliza en combinacin con INITGET, por ejemplo:
(initget DEShacer Nuevo Repetir)
(setq opc (getkword \nDEShacer / Nuevo / Repetir: ))
En este caso el usuario tan slo podr indicar como respuesta una de las palabras clave
de la funcin Initgety se la asigna a la variable opc.
No hemos indicado el modo en Initget, tal solo las palabras clave. En la
rutina ARAND nos interesaba que apareciera el modo 7 para que no se indique como
respuesta Intro, 0 o un nmero negativo. Pero no es obligatorio indicar siempre un modo.
Un ejemplo bastante habitual en las macros es el siguiente:
(initget DEShacer Nuevo Repetir)
(setq opc (getkword \nDEShacer / Nuevo / Repetir: ))
(cond
((= opc DEShacer)
(alert Has seleccionado la opcin DEShacer)
)
((= opc Nuevo)
(alert Has seleccionado la opcin Nuevo)
)
(T
(alert Has seleccionado la opcin Repetir)
)
)
As en funcin de la opcin que indique el usuario se hace una cosa u otra.
Estructuras repetitivas: Bucles
Hasta hace poco tan slo podamos crear programas cuya ejecucin fuera lineal:
Haz esto
Ahora esto otro

Luego vimos las estructuras condicionales IF y COND que ya nos permiten jugar un poco
ms y hacer que nuestros programas no fueran tan lineales. Ahora vamos a ver funciones
que nos permitir crear repeticiones de cdigo y algo que tal vez te suene, los bucles, que
se utilizan mucho en programacin.
(WHILE condicin [expr1] [expr2] )
La funcin while ejecuta las expresiones indicadas MIENTRAS se cumpla la condicin, y
devuelve el valor de la ltima expresin evaluada. Por ejemplo:
(setq i 0)
(while (< i 10)
(prompt \n)
(prompt (itoa i))
(setq i (1+ i))
)
Mientras i sea menor que 10, ejecuta las expresiones. Es decir, escribir en la ventana de
comandos de AutoCAD los nmeros del 0 al 9. Cuando (setq i (1+ i)) asigna a la
variable i el valor 10, la condicin del bucle ya no se verifica, de modo que termina el
bucle. La funcin While devolver el valor de la ltima expresin evaluada, es decir 10.
Este es un tpico ejemplo de bucle, una estructura repetitiva con un ndice o contador,
en este caso i, que puede ir aumentando o disminuyendo.
Fjate que una de las expresiones que se ejecutan dentro del bucle es (setq i (1+ i)) es
decir, movemos el contador. Si no lo hiciramos i siempre sera menor que 10 y se
entrara en un bucle sin fin, que da lugar a un error.
Veamos el siguiente ejemplo:
(setq i 10)
(while (< i 10)
(prompt \n)
(prompt (itoa i))
(setq i (1+ i))
)
En este caso i tiene asignado el valor 10 antes de entrar en el bucle, de modo que la
condicin (< i 10) no se cumplira y por tanto no se ejecutarn las expresiones
siguientes. While devuelve el valor de la ltima expresin evaluada, que en este caso es
la condicin as que devuelve nil.
Las expresiones en While son opcionales, de modo que podemos crear un bucle en el
que solo se indique la condicin:
(while (not (setq pt (getpoint \nPunto inicial: ))))
En este caso la condicin es (not (setq pt (getpoint \nPunto inicial: ))) es decir, pide
un punto al usuario y lo almacena en la variable pt.
Si el usuario indica un punto, pt = (X Y Z) que es distinto
de nil, (not (setq pt (getpoint \nPunto inicial: ))) devolver nil y saldr de la
funcin While.
Si el usuario indica Intro, getpoint devolver nil y lo almacenar en la variable pt,
de modo que (not(setq pt (getpoint \nPunto inicial: ))) devolver T, y preguntar
de nuevo por un punto.
Por lo tanto, mientras no se indica un punto, sigue preguntando.
Otro ejemplo tpico de bucles es en el que se utilizan algunas variables como flags
(banderas o banderillas)para indicar si algo est activado o desactivado o para controlar
distintos valores. Veamos un ejemplo, supongamos que a y b son dos variables que
almacenan dos nmeros reales:
(if (< a b)
(setq flag1 nil)
(setq flag1 T)
)
(while flag1
(prompt \na NO es menor que b)
(setq b (getreal \nIntroduzca un nmero: ))
(if (< a b)
(setq flag1 nil)
)
)
En este caso:
Si a es menor que b > flag1 = nil
Si a NO es menor que b > flag1 = T
Luego la funcin While evala la condicin flag1 que devolver su valor nil o T.
Si es flag1 = nil (a es menor que b) no evala las expresiones pues no se verifica
la condicin.
Si es flag1 = T (a NO es menor que b) se verifica la condicin as que se ejecutan
las expresiones. Primero nos dice que a no es menor que b, nos vuelve a pedir el
valor de b y comprueba si a es menor que el nuevo valor de b en cuyo caso asigna a
la banderilla flag1 el valor nil para salir del bucle.
Es decir, mientas a NO sea menor que b, nos pedir un nuevo valor de b.
En la funcin While, al igual que vimos con IF y COND, como condicin podemos utilizar
expresiones lgicas. Por ejemplo:
(while (or (< a b) (< b 0.0))
(prompt \na NO es menor que b, o b es negativo)
(setq b (getreal \nIntroduzca un nmero positivo: ))
)
En este ejemplo, el bucle se ejecutar hasta que se indique un valor para b positivo y
mayor que a.
(REPEAT cantidad [expr1] [expr2])
La funcin repeat ejecuta las expresiones indicadas el nmero de veces que se indique
en cantidad y devuelve el resultado de la ltima expresin evaluada.
(repeat 10 (prompt \nEste curso es demasiado fcil para mi))
Tambin podramos asignar la cantidad a repetir a una variable:
(setq Bart_Simpson (getint \nNmero de repeticiones para Bart: ))
(repeat Bart_Simpson (prompt \nNo hace falta fuego en un simulacro de
incendio))
En este caso escribira en la pizarra, es decir la ventana de comandos de AutoCAD, esa
frase tantas veces como le indiquemos.
Tambin podemos obtener la cantidad por medio de una funcin de AutoLISP, como
resultado de una operacin:
(repeat (+ 4 5) (prompt Este curso me parece muy sencillo))
o suponiendo que las variables a y b tengan asignados dos nmeros enteros:
(prompt Inspector Gadget, este mensaje se autodestruir en)
(setq i 0)
(repeat (+ a b)
(prompt \t)
(prompt (itoa i))
(setq i (1+ i))
)
Pero qu sucede si a o b son un nmero real y no un entero? repetir las expresiones
2.5 veces? Pues no, nos dar un error. Por eso hay que estar bien seguros de que la
cantidad indicada es un nmero entero y no un real. Incluso si como cantidad indicamos
un nmero entero sin decimales, como 2.0, dar un error.
Vamos a modificar la rutina ARAND para hacer que el segundo radio siempre sea mayor
que el primero. El cdigo correspondiente al crculo exterior era el siguiente:
(initget 7 Dimetro)
(setq rad (getdist pto \nRadio exterior / Dimetro: ))
(if (= rad Dimetro)
(progn
(initget 7)
(setq rad (/ (getreal \nDimetro exterior: ) 2.0))
)
)
(command _.circle pto rad)
Lo primero que vamos a cambiar es el nombre de las variables. En lugar de utilizar la
variable rad tanto para el radio interior como para el exterior, vamos a utilizar la
variable radi para el radio interior y la variable radepara el exterior. As podremos
comparar si rade es mayor que radi.
Podramos sustituir el cdigo anterior por el siguiente:
(while (or (not rade) (not (< radi rade)))
(initget 7 Dimetro)
(setq rade (getreal \nRadio exterior / Dimetro: ))
(if (= rade Dimetro)
(progn
(initget 7)
(setq rade (/ (getreal \nDimetro exterior: ) 2.0))
)
)
)
(command _.circle pto rade)
La primera vez que se evala la condicin del bucle, no se ha asignado an ningn valor
al radio exterior. De modo que rade = nil y (not rade) devolver T.
Como (or (not rade) (not (< radi rade))) comprueba que al menos se verifique una de las
dos condiciones, al verificarse la primera condicin (not rade) la segunda ni siquiera se
evala (por suerte, puesto que al no estar definida rade nos dara un error). La condicin
se verifica y ejecuta las expresiones que estn a continuacin, que nos piden un valor
para el radio exterior.
Es decir, mientras no se indique el radio exterior o este sea menor que el radio interior se
ejecuta el bucle, que nos pide un nuevo valor para el radio exterior. Al salir del bucle ya
tenemos un radio exterior vlido as que dibujamos la circunferencia exterior. El cdigo
completo sera:
(defun C:ARAND ( / pto radi rade cmd0 )
(command _.undo _begin)
(if (= (setq cmd0 (getvar cmdecho)) 1)
(setvar cmdecho 0)
)
(initget 1)
(setq pto (getpoint \nCentro de la arandela: ))
(initget 7 Dimetro)
(setq radi (getdist pto \nRadio interior / Dimetro: ))
(if (= radi Dimetro)
(progn
(initget 7)
(setq radi (/ (getreal \nDimetro interior: ) 2.0))
)
)
(command _.circle pto radi)
(while (or (not rade) (not (< radi rade)))
(initget 7 Dimetro)
(setq rade (getdist pto \nRadio exterior / Dimetro: ))
(if (= rade Dimetro)
(progn
(initget 7)
(setq rade (/ (getreal \nDimetro exterior: ) 2.0))
)
)
)
(command _.circle pto rade)
(if (= cmd0 1)
(setvar cmdecho 1)
)
(command _.undo _end)
(princ)
)
(prompt \nNuevo comando ARAND cargado)
Funciones para manipular cadenas de texto
En este artculo veremos las funciones que incorpora AutoLISP para manipular cadenas
de texto.
(CHR entero)
Esta funcin devuelve el carcter al que le corresponde el cdigo ASCII indicado. Por
ejemplo:
(chr 65) devuelve A
(chr 97) devuelve a
(ASCII texto)
Devuelve el cdigo ASCII (un nmero entero) correspondiente al primer carcter de la
cadena de texto indicada.
(ascii Abcde) devuelve 65
(ascii A) tambin devuelve 65 porque lo nico que importa es el primer carcter de la
cadena de texto.
(STRLEN texto1 [texto2] )
Esta funcin devuelve la longitud (nmero de caracteres) de la cadena de texto que recibe
como argumento.
(strlen AutoLISP) devuelve 8
Tambin podemos asignar una cadena de texto a una variable y comprobar despus su
longitud con strlen:
(setq txt1 AutoLISP)
(strlen txt1)
Si se indica ms de una cadena de texto, devolver la suma de sus longitudes:
(strlen AutoLISP AutoCAD) devuelve 15
(STRCASE texto [modo])
Se utiliza para convertir un texto en maysculas o minsculas. Por ejemplo:
(strcase AutoLISP) devuelve AUTOLISP
Si se indica el argumento opcional [modo] con un valor distinto de nil, entonces devuelve
el texto en minsculas.
(strcase AutoLISP T) devuelve autolisp
(STRCAT texto1 [texto2] )
Esta funcin concatena (une) varias cadenas de texto.
(strcat Hola Mundo) devolvera HolaMundo
Para que las dos palabras anteriores aparezcan separadas se pueden hacer dos cosas:
Aadir el espacio en una de las palabras: (strcat Hola Mundo)
Aadir el espacio como otra cadena de texto: (strcat Hola Mundo)
Esta funcin se utiliza mucho para concatenar los mensajes que se muestran al usuario.
Por ejemplo:
(setq i 10)
(setq rad (getreal (strcat \nRadio < (itoa i) >: )))
Pedir un nmero real al usuario y mostrar el siguiente mensaje en la ventana de
AutoCAD: Radio <10>:
(SUBSTR texto pos_inicial [longitud])
Esta funcin devuelve parte de la cadena de texto que recibe como argumento, a partir de
la posicin inicial que se indique.
(substr AutoLISP 5) devuelve el texto a partir del quinto carcter, es decir LISP.
(substr AutoLISP 1) devuelve el texto entero AutoLISP.
(substr AutoLISP 15) devuelve es decir, una cadena de texto vaca puesto que el
texto indicado tiene menos de 15 caracteres.
Tambin se puede indicar la longitud, es decir el nmero de caracteres que se desean
obtener.
(substr AutoLISP 5 2) devuelve LI. A partir del quinto carcter devuelve 2 caracteres.
(substr AutoLISP 5 10) devolver LISP, porque tan slo tenemos 4 caracteres ms, a
partir del quinto, y no diez.
(WCMATCH cadena patrn)
Esta funcin se utiliza para comparar si una cadena de texto verifica o cumple un patrn,
en caso de que lo verifique devuelve T y si no lo verifica devuelve nil.
(wcmatch AutoLISP A*) devolver T ya que comprueba si AutoLISP comienza por
A.
(wcmatch AutoLISP a*) devolver nil, puesto que A es distinto de a.
Los patrones son cadenas de texto en las que se pueden emplear determinados smbolos
comodn:
# Equivale a un dgito.
@ Equivale a una letra.
. Equivale a un carcter que no sea alfanumrico (ni letras ni nmeros).
* Equivale a una cadena de caracteres.
? Equivale a un carcter cualquiera.
~ Equivale a una negacin.
o Por ejemplo (wcmatch AutoLISP ~B*) comprueba que el texto no
empieza por B.
[...] Nos permite indicar varios caracteres.
o Por ejemplo (wcmatch AutoLISP [AB]*) comprueba si el texto
comienza por A o por B.
o Tambin podramos indicar un rango: (wcmatch AutoLISP [A-
F]*) comprueba si el texto comienza por A, B, C, hasta la F.
Incluso podemos comprobar con dos patrones distintos, separados por una
coma: (wcmatch AutoLISP A*,*LISP) devolvera T.
Pero cmo hacemos entonces para saber si un texto tiene una coma? no podemos
hacer los siguiente:(wcmatch Curso, de AutoLISP *,*) ya que en este caso le
estamos indicando dos patrones, como en el ejemplo anterior.
Tendremos que hacerlo as: (wcmatch Curso, de AutoLISP *,*) al anteponer el
apstrofo delante de uno de los caracteres comodines de los patrones, le estamos
diciendo que queremos usar el literal, es decir, lo que ponemos a continuacin tal cual
est.
Pues tema visto. As que podemos ahora modificar la macro CIRCPERI. Tenamos las
siguientes lneas en la macro:
(prompt \nPermetro <)
(prompt (rtos (* (getvar circlerad)2 pi) 2 2))
(prompt >: )
Podramos concatenar las cadenas de texto y ejecutar una nica vez la funcin prompt:
(prompt (strcat \nPermetro < (rtos (* (getvar circlerad) 2 pi) 2 2) >: ))
Vamos ahora a crear un nuevo comando llamado CIRCULOM que nos permitir dibujar
mltiples circunferencias concntricas. Y comenzaremos como siempre por el
pseudocdigo. Podra ser algo as:
1. Pedir el centro de las circunferencias.
2. Mientras se indique un punto o radio.
1. Dibujar un crculo.
Al escribir el cdigo, lo primero es definir el nuevo comando:
(defun C:CIRCULOM ( / )
De momento no ponemos las variables locales, porque an no tenemos ni variables ni
nada. Las aadiremos al terminar la macro.
1. Pedir el centro de los crculos. Por ejemplo as:
(setq pto (getpoint \nCentro: ))
Tal vez pienses no deberamos poner antes un INITGET? Pues seguramente, pero no
nos paremos ahora con eso. Primero a ver si hacemos que funcione la rutina, despus ya
nos preocuparemos de que funcione bien.
2. Mientras se indique un punto o radio. Esto lo podemos hacer con While:
(while (setq rad (getdist pto \nRadio [Intro para terminar]: ))
Pide puntos o distancias, para usarlas como radio, hasta que se pulse Intro. Fjate que no
se ha cerrado elwhile, porque an tenemos que aadir las expresiones que van dentro.
Y nos falta solo dibujar la circunferencia. As de sencillo:
(command _.circle pto rad)
nos faltan dos cosas para terminar: El parntesis de cierre de While y el de la funcin. El
cdigo completo queda as:
(defun C:CIRCULOM ( / )
(setq pto (getpoint \nCentro: ))
(while (setq rad (getdist pto \nRadio [Intro para terminar]: ))
(command _.circle pto rad)
)
)
Ahora es cuando vamos a introducir las mejoras y a retocar el cdigo. Vamos a comenzar
limitando las posibles respuestas de los usuarios con Initget:
Aadimos (initget 1) antes de la solicitud Getpoint, para que el usuario no pueda
indicar Intro como respuesta.
Y aadimos (initget 6) antes de getdistpara que no permita ni cero ni un nmero
negativo.
o Observa que (initget 6) se vuelve a poner otra vez dentro del bucle While.
Si no lo hiciramos al indicar el primer radio no permitira responder con cero ni
con un nmero negativo. Sin embargo, para el segundo radio y todos los
siguientes si que nos dejara. Para que no lo permita, hay que incluir la
funcin Initget antes de que se ejecute de nuevo Getdist, de modo que se aade
dentro del bucle While.
Otras mejoras seran:
Aadir las variables a la lista de variables locales de la funcin.
Desactivar el eco de mensajes.
Aadir una salida limpia a la funcin.
Aadir una lnea fuera de la funcin para que indique el nombre del comando al
cargar la macro.
Aadir el comando Deshacer Inicio al principio de la rutina y Deshacer Fin al
terminarla.
El cdigo de la macro queda as:
(defun C:CIRCULOM ( / pto rad cmd0 )
(command _.undo _begin)
(if (= (setq cmd0 (getvar cmdecho)) 1)
(setvar cmdecho 0)
)
(initget 1)
(setq pto (getpoint \nCentro: ))
(initget 6)
(while (setq rad (getdist pto \nRadio [Intro para terminar]: ))
(command _.circle pto rad)
(initget 6)
)
(if (= cmd0 1)
(setvar cmdecho 1)
)
(command _.undo _end)
(princ)
)
(prompt \nNuevo comando CIRCULOM cargado)
Trabajar con ngulos y distancias
AutoLISP proporciona una serie de funciones para trabajar con ngulos y distancias,
comenzaremos viendo los ngulos:
(ANGLE pt1 pt2)
Esta funcin devuelve el ngulo formado por la lnea que va desde pt1 hasta pt2. El
origen de ngulos ser el eje X y el sentido antihorario se considera positivo. Por ejemplo:
(setq pt1 (getpoint \nPunto1: ))
(setq pt2 (getpoint pt1 \nPunto2: ))
(setq ang (angle pt1 pt2))
Hay que fijarse en cual es el punto que se indica primero en la funcin angle, porque si
hacemos:
(setq ang2 (angle pt2 pt1))
Obtendremos un ngulo distinto, el anterior ms pi o menos pi. Por lo tanto: No es lo
mismo el ngulo de pt1a pt2 que el ngulo de pt2 a pt1.
Si los puntos estn en 3D, los proyecta sobre el plano XY y devuelve el ngulo formado
por sus proyecciones
(DISTANCE pt1 pt2)
Devuelve la distancia en 3D entre los puntos pt1 y pt2. Si uno de los puntos est en 2D,
es decir no tiene coordenada Z, se ignora la coordenada Z del otro punto devolviendo la
distancia en 2D.
(setq pt1 (getpoint \nPunto1: ))
(setq pt2 (getpoint pt1 \nPunto2: ))
(setq dist12 (distance pt1 pt2))
En este caso, (setq dist21 (distance pt2 pt1)) sera igual a dist12. Ya que la distancia
del punto pt1 al pt2es igual que la distancia del punto pt2 al pt1.
(POLAR ptobase ang dist)
Esta funcin se utiliza para obtener un punto por medio de coordenadas polares a partir
de un punto base. Por ejemplo:
(setq pt1 (getpoint \nPunto1: ))
(setq pt2 (polar pt1 0.0 50.0))
Esto asignara a la variable pt2 un punto que est a 50 unidades en la direccin del eje X
a partir del punto base pt1. Si hiciramos:
(command _.line pt1 pt2 )
Dibujaramos una lnea horizontal de 50 unidades, desde pt1 hasta pt2.
Hay que observar que en (polar pt1 0.0 50.0) se indica primero el punto base, luego un
ngulo en radianes y por ltimo una distancia. De modo que:
(setq pt2 (polar pt1 (/ pi 2.0) 50.0))
Devolver un punto que est a 50 unidades en la direccin del eje Y a partir del punto
base pt1. Ya que en este caso se ha indicado un ngulo de (/ pi 2.0) es decir, 90.
Funciones avanzadas para manejar listas
Ya hemos visto algunas funciones para manejar listas: CAR, CDR, LIST pero hay muchas
ms. En este tema veremos algunas de las que nos faltan.
(LAST lista)
Esta funcin devuelve el ltimo elemento de la lista que recibe como argumento. De modo
que si hacemos:
(setq pto (getpoint \nPunto de insercin: ))
(setq z (last pto))
En la variable z almacenamos la coordenada Z del punto pto, siempre que el punto est
en 3D porque si est en 2D almacenara la coordenada Y. Los puntos son listas del
tipo (10.0 20.0 0.0).
(NTH numero lista)
El ejemplo anterior no sera muy til para obtener la coordenada Y, ya que si indicamos
un punto en 3D devolver la coordenada Z. Entonces, cmo podemos obtener la
coordenada Y? ya vimos un mtodo:
(CADR pto)
Pero supongamos que tenemos una lista de 27 elementos, y queremos obtener el
elemento 22. Cmo lo haramos? No podemos utilizar (cADDD..DDDr pto) ya que slo
nos permite agrupar 4 funciones cAr y cDr. De modo que tendramos que hacer (cADDD
(cDDDD (cDDDDr .. pto). Pero hacerlo as es bastante engorroso.
Devuelve el elemento cuyo nmero de orden se indica de la lista.
(nth 2 pto) devolver la coordenada Y, no? Pues no!. Los elementos de una lista se
empiezan a numerar desde cero.
Por ejemplo:
(nth 0 pto) devolver la coordenada X del punto pto.
(nth 1 pto) devolver la coordenada Y del punto pto.
(nth 2 pto) devolver la coordenada Z del punto pto, si existe y si no existe
devolver nil.
(MEMBER elemento lista)
Supongamos que tenemos una lista como la siguiente:
(setq lst (list peras melones sandias perros pltanos))
para comprobar si perros pertenece a la lista lst se utiliza la funcin MEMBER.
Con esta funcin, si el elemento indicado pertenece a la lista devolver la lista a partir de
ese elemento. Por ejemplo:
(member perros lst) devolver (perros pltanos)
Si el elemento no pertenece a la lista, devolver nil.
(member gatos lst) devuelve nil
(SUBST elem_nuevo elem_antiguo
lista)
Esta funcin reemplaza un elemento de una lista por su nuevo valor. Por ejemplo, para
reemplazar perros por naranjas:
(subst naranjas perros lst) devuelve la lista con el elemento que se ha
modificado (peras melones sandias naranjas pltanos). Pero la
variable lst sigue almacenando la lista anterior(peras melones sandias perros
pltanos).
Para modificar la lista almacenada en la variable lst tenemos que asignarle el valor
devuelto por SUBST:
(setq lst (subst naranjas perros lst))
(CONS elemento lista)
Supongamos que queremos aadir un nuevo elemento limones a la siguiente lista:
(setq lst (list peras naranjas manzanas))
Podramos hacerlo con list, pero sera algo complicado:
(setq lst (list limones (car lst) (cadr lst) (caddr lst)))
Para una lista de 3 elementos se puede hacer, pero Y si tenemos 30 elementos?
La funcin cons aade un elemento a la lista indicada. El nuevo elemento se sita en el
primer lugar. Es decir:
(cons limones lst) devolver (limones peras naranjas manzanas)
Y al igual que suceda con SUBST, si slo hacemos (cons limones lst) no estamos
asignando la lista resultante a la variable lst. Deberamos hacerlo as:
(setq lst (cons limones lst))
Pero y si lo que queremos es aadir un elemento al final de la lista? Antes de ver como
sera, veamos otra funcin:
(REVERSE lista)
Devuelve la lista que recibe como argumento pero en orden inverso.
(reverse lst) devolver (manzanas naranjas peras limones)
Bien, pues para aadir un elemento al final de una lista podemos utilizar cons y reverse:
(setq lst (reverse (cons pltanos (reverse lst))))
Veamos como funciona la lnea de cdigo anterior:
(reverse lst) devuelve la lista en orden inverso
(cons pltanos (reverse lst)) aade pltanos como primer elemento de la
lista invertida
por ltimo volvemos a invertir el orden de la lista y lo asignamos a la
variable lst: (setq lst (reverse(cons platanos (reverse lst))))
(ACAD_STRLSORT lista)
Esta funcin devuelve una lista con sus elementos, que debern ser cadenas de texto,
ordenados alfabticamente. Por ejemplo:
(acad_strlsort lst) devolver (limones manzanas naranjas peras pltanos)
(APPEND lista1 [lista2] )
Esta funcin une dos o ms listas y devuelve la lista resultante. Si tenemos dos listas:
(setq lst1 (list peras naranjas manzanas))
(setq lst2 (list fresas limones))
y que queremos unirlas
(append lst1 lst2) devolver (peras naranjas manzanas fresas limones)
Aplicar funciones a los elementos de una lista
Supongamos que tenemos una lista de puntos:
(setq lstptos (list (list 0.0 0.0) (list 10.0 0.0) (list 10.0 10.0) (list 0.0 10.0)))
Es decir, lstptos es una lista con cuatro elementos correspondientes a los vrtices de un
cuadrado de lado 10. Supongamos que queremos dibujar un crculo en cada uno de los
puntos de lstptos. Hasta ahora podamos hacerlo as:
(setq i 0 nent (length lstptos))
(while (< i nent)
(setq pt (nth i lstptos))
(command _.circle pt 1.0)
(setq i (1+ i))
)
La variable i nos servir como ndice o contador en el bucle While, por eso le asignamos
inicialmente el valor inicial 0, porque los elementos de una lista se numeran empezando
desde cero. Es bastante habitual que los nombres de las variables utilizadas como
contadores sean i j k Tambin asignamos a nent el nmero de elementos de la
lista lstptos, porque sino no sabremos como salir del bucle ni hasta que elemento llegar.
El bucle se ejecutar mientras el contador sea menor que nent es decir, se ejecutar para
cada elemento delstptos. La primera lnea de cdigo dentro del bucle (setq pt (nth i
lstptos)) obtiene el elemento nmero i delstptos, que es un punto, y a continuacin
dibuja una circunferencia en l de radio 1.0. Finalmente aumentamos el contador para que
pase al siguiente punto (setq i (1+ i)). Esta ltima lnea es muy importante, si no estuviera
la variable i sera siempre igual a cero y el bucle no tendra fin. Por lo que dibujara
infinitos crculos en el primer punto de lstptos y dara lugar a un error.
Veamos otro mtodo para dibujar los crculos en los vrtices de lstptos:
(while lstptos
(setq pt (car lstptos))
(command _.circle pt 1.0)
(setq lstptos (cdr lstptos))
)
En este caso, el bucle se ejecutar mientras tengamos puntos en la lista es decir,
mientras lstptos sea distinto de nil. Se define pt como el primer punto de la lista lstptos,
se dibuja una circunferencia de radio 1.0 con centro en pt y por ltimo se mueve el
contador. Pero, qu contador? Si no existe!
Pues, (setq lstptos(cdr lstptos)) eliminamos el primer elemento de la lista lstptos. De
modo que lstptos va perdiendo un elemento (punto) cada vez que se ejecuta el bucle.
Llega un momento en el que lstptos = ((0.0 10.0)) y al
evaluarse (setq lstptos (cdr lstptos)) se asignar a lstptos el valor devuelto por CDR, es
decir nil. Con lo cual deja de ejecutarse el bucle.
El inconveniente de este segundo mtodo es que se vara el valor asignado a la
variable lstptos, que finalmente valdr nil. Por lo que la lista de puntos inicial se perder.
Bien, pero AutoLISP es un excelente lenguaje de programacin para trabajar con listas.
De modo que tenemos algunos mtodos que son mejores, y eso es lo que vamos a ver en
este artculo.
(FOREACH variable lista expresion)
Esta funcin permite aplicar una expresin para cada elemento de la lista que recibe
como argumento. La variable simboliza a un elemento de dicha lista, por lo que se suele
utilizar en la expresin. Por ejemplo:
(foreach p lstptos (command _.circle p 1.0))
La lnea de cdigo anterior representa el tercer mtodo para dibujar los crculos en los
puntos de lstptos. A la variable la llamamos p y la expresin a ejecutar para cada
elemento de la lista es: (command _.circle p1.0) dnde p es un elemento de la lista.
En caso de tener una lista de cadenas de texto, podria hacerse lo siguiente:
(setq lsttxt (list Curso de AutoLISP))
(foreach p lsttxt (prompt p))
Con lo cual, escribira todos los textos en la ventana de comandos de AutoCAD. Se ha
utilizado el mismo nombre de variable p, pero podra haberse cambiado:
(foreach pepe lsttxt (princ pepe))
Supongamos ahora que tenemos una lista de nmeros:
(setq lst (list 5.0 -1.5 2.6 3.8 9.7))
Para sumar los nmeros podramos hacer lo siguiente:
(setq i 0 nent (length lst) total 0.0)
(while (< i nent)
(setq num (nth i lst))
(setq total (+ total num))
(setq i (1+ i))
)
Inicialmente definimos la variable total como 0.0, el bucle se ejecutar para cada
elemento de lst y se definenum como el nmero que est en la posicin i. Sumamos
a total ese nmero y movemos el contador. Cuando se entra por primera vez en el
bucle, num = 5.0 de modo que total = 0.0 + 5.0. Al volver a entrar en el bucle num = -1.5
de modo que total = 5.0 + (-1.5) y as hasta que se llega al ltimo elemento de lst.
Tambin podra hacerse sin emplear contadores, como hicimos antes. Y tambin
podemos hacerlo conFOREACH, veamos:
(foreach p lst (setq total (+ total p)))
Todo lo que antes ponamos en un bucle se pone ahora en una sola lnea de cdigo.
(APPLY nombre_funcin lista)
Aplica la funcin que recibe como argumento a todos los elementos de la lista. El nombre
de la funcin a utilizar en APPLY se indicar precedida por el smbolo para que
AutoCAD interprete que le estamos pasando ese texto tal cual. El ejemplo anterior sera:
(setq total (apply + lst))
En (apply + lst) estamos aplicando la funcin + a todos los elemento de lst, equivale
a (+ 5.0 -1.5 2.6 3.8 9.7), y el resultado se lo asignamos a la variable total.
Digamos que + es el nombre que utilizamos en AutoLISP para hacer referencia a la
funcin +, ya que + es la funcin propiamente y no su nombre. Prueba lo siguiente en la
ventana de comando de AutoCAD:
(list pepe + 5.0) y fjate en lo que devuelve (pepe #<SUBR @0244f5a8 +> 5.0)
Y ahora prueba con el literal, es decir con el carcter delante del +
(list pepe + 5.0) devuelve (pepe + 5.0)
Entiendes ahora porque ponemos +? Para que no evale la funcin, ya
que devolvera #<SUBR @0244f5a8 y nos dara un error.
Veamos un par de ejemplos ms:
(apply max lst) devolver el mayor nmero de lst
(apply min lst) devolver el menor nmero de lst
Si tuviramos una lista cuyos elementos fueran textos:
(setq lsttxt (list Curso de AutoLISP))
para unir los textos:
(setq txt (apply strcat lsttxt))
De modo que txt = CursodeAutoLISP todo junto.
(MAPCAR nombre_funcin lista1
[lista2])
Esta funcin aplica la funcin de AutoLISP que recibe como argumento a los elementos
de las listas. Como as no se va a entender veamos algunos ejemplos:
Supongamos que tenemos dos puntos:
(setq pt1 (getpoint \nPunto 1: ))
(setq pt2 (getpoint pt1 \nPunto 2: ))
Los puntos son listas con 2 o 3 elementos, en funcin de si tienen 2 o 3 coordenadas.
Vamos a determinar el vector con origen en pt1 y final en pt2. Tenemos que calcular las
coordenadas X Y Z del vector, que son el resultado de restar las respectivas coordenadas
X Y Z de pt1 a las de pt2. Podemos obtener el vector as:
(setq vector
(list (- (car pt2) (car pt1))
(- (cadr pt2) (cadr pt1))
(- (caddr pt2) (caddr pt1))
)
)
Siendo:
la coordenada X (- (car pt2) (car pt1))
la coordenada Y (- (cadr pt2) (cadr pt1))
la coordenada Z (- (caddr pt2) (caddr pt1))
Bien, pues esto mismo lo podemos hacer con MAPCAR
(setq vector (mapcar - pt2 pt1))
La funcin que recibe mapcar es - y lo que hace es aplicarla a los elementos
de pt2 y pt1, de modo que resta sus coordenadas X, las Y y las Z.
APPLY devuelve un elemento y MAPCAR una lista.
Clculo del mdulo de un vector
Vamos a complicar un poco el tema. Si quisiramos obtener el mdulo de un
vector tendramos que calcular la raz cuadrada de la suma de sus coordenadas al
cuadrado:
1. (mapcar * vector vector) devolver una lista con las coordenadas del vector al
cuadrado, ya que las estamos multiplicando por si mismas.
2. Para sumarlas utilizamos APPLY (apply + (mapcar * vector vector))
3. Para terminar solo nos falta hacer la raz cuadrada de lo anterior
(setq modulo (sqrt (apply + (mapcar * vector vector))))
Clculo del producto escalar de dos
vectores
Veamos otro ejemplo en el que se combinan APPLY y MAPCAR. Sean v1 y v2 dos
vectores vamos a calcular su producto escalar.
(setq v1 (list 10.0 10.0 0.0))
(setq v2 (list 5.0 0.0 0.0))
El producto escalar de los vectores v1 y v2 es la suma de los productos de las
coordenadas de v1 por las dev2. Podramos hacerlo as:
(setq pescalar
(+
(* (car v1) (car v2))
(* (cadr v1) (cadr v2))
(* (cadr v1) (cadr v2))
)
)
Pero resulta ms sencillo utilizando MAPCAR y APPLY:
1. Primero multiplicamos las coordenadas de ambos vectores (mapcar * v1 v2)
2. y luego las sumamos, de modo que
(setq pescalar (apply + (mapcar * v1 v2)))
(LAMBDA (lista_argumentos /
variables_locales) expresin1
[expresin2] )
Tal vez el formato de la funcin LAMBDA recuerde algo a DEFUN.
LAMBDA tambin se utiliza para definir una funcin, pero a diferencia de DEFUN la
funcin no se almacena en ningn lugar, en este caso es temporal. Por tanto solo se
puede ejecutar donde se defina. Adems la funcin creada no tiene nombre, por lo que
tampoco podramos llamarla desde otra parte de nuestro cdigo.
Utilizarla sola sin APPLY o MAPCAR no tiene sentido.
Supongamos que queremos obtener el punto medio de dos puntos:
(setq pt1 (getpoint \nPunto 1: ))
(setq pt2 (getpoint pt1 \nPunto 2: ))
Las coordenadas del punto medio sern las coordenadas de pt1 ms las de pt2 divididas
por 2.0.
Para sumar sus coordenadas: (mapcar + pt1 pt2)
Bien pero ahora, Cmo las dividimos por 2.0? Podemos hacer lo siguiente:
(mapcar / (mapcar + pt1 pt2) (list 2.0 2.0 2.0))
Donde creamos una lista (list 2.0 2.0 2.0) y dividimos los elementos de (mapcar + pt1
pt2) entre los elementos de la lista anterior (2.0 2.0 2.0).
Recordemos (mapcar + pt1 pt2) devuelve la suma de las coordenadas de pt1 y pt2. Si
necesitamos dividirla por 2.0. podemos crear una funcin que reciba un nmero y lo divida
por 2.0 devolviendo el resultado:
(defun 2/ ( num ) (/ num 2.0))
Y ahora pasar a MAPCAR la nueva funcin 2/ para que divida cada elemento
de (mapcar + pt1 pt2) por 2.0
(mapcar 2/ (mapcar + pt1 pt2))
Pero tambin podemos hacerlo de otra forma, utilizando la funcin LAMBDA en lugar
de DEFUN. Primero veamos como sera nuestra funcin definida mediante LAMDA:
(lambda ( num ) (/ num 2.0))
Es muy parecido a lo que hicimos con DEFUN. Pero la funcin definida mediante
LAMBDA no tiene nombre y no se almacena en ningn sitio, es temporal, de modo que no
podemos llamarla. Dnde debemos utilizar LAMBDA? Pues directamente en MAPCAR,
donde hay que indicar el nombre de la funcin:
(mapcar (lambda ( num ) (/ num 2.0)) (mapcar + pt1 pt2))
Por tanto, cuando queremos aplicar APPLY o MAPCAR a una o varias listas y ejecutar
una funcin que no existe en AutoLISP, podemos crearla previamente con DEFUN o
utilizar la funcin LAMBDA para definirla in situ.
Literales y otras funciones de utilidad
(VER)
Esta funcin devuelve una cadena de texto con la versin de AutoLISP que se est
ejecutando. Por ejemplo: Visual LISP 2000 (es). Entre parntesis indica la versin
idiomtica, en este caso Espaol.
Pantalla de texto y pantalla grfica
En AutoCAD podemos pasar de pantalla grfica a la pantalla de texto, y al revs,
pulsando la tecla de funcinF2. En AutoLISP tambin existen algunas funciones para
hacerlo directamente desde el cdigo de nuestras rutinas.
(TEXTSCR)
Se utiliza para pasar a pantalla de texto y siempre devuelve nil. Se suele emplear cuando
se quiere mostrar mucha informacin en pantalla de texto.
(GRAPHSCR)
Pasa a pantalla grfica y tambin devuelve nil. Se utiliza para asegurarnos que el usuario
est viendo la pantalla grfica, por ejemplo para indicar un punto. Especialmente se
utilizar si antes se ha pasado a pantalla de texto.
(TEXTPAGE)
Esta funcin es anloga a TEXTSCR. Pasa a pantalla de texto y tambin devuelve nil.
Tal vez te ests preguntando Cuntas funciones nos quedan an? Pues entre otras
cosas, la siguiente funcin nos servir para ver las funciones de AutoLISP que hemos
visto y las que nos quedan.
(ATOMS-FAMILY formato
[lista_simbolos])
Esta funcin devuelve una lista con los smbolos que se han definido en el dibujo actual.
Qu es un smbolo? Pues un nombre de variable de AutoLISP, el nombre de una funcin
de usuario que hemos creado y tambin todos los nombres de las funciones propias de
AutoLISP.
El argumento formato puede tener dos valores:
0 para que devuelva una lista con los nombres de los smbolos.
1 para que devuelva una lista, pero siendo sus elementos cadenas de texto.
Veamos ahora algn ejemplo. Al escribir la lnea siguiente sabrs cuantas funciones
faltan:
(atoms-family 0) esto mostrar una lista con los nombres de todos los smbolos
definidos en el dibujo actual.
(atoms-family 1) as los elementos de la lista anterior sern cadenas de texto.
En las listas anteriores es difcil encontrar algo. Recuerdas la funcin acad_strlsort?
Permita organizar alfabticamente una lista de cadenas de texto.
(acad_strlsort (atoms-family 1)) devolver la lista anterior ordenada alfabticamente
Estn todas las funciones de AutoLISP, pero hay otras muchas funciones que aparecen
en la lista y no son funciones de AutoLISP. As que no te asustes, que no son tantas.
Recordemos el formato de esta funcin: (ATOMS-FAMILY formato [lista_simbolos]) y
veamos que es eso de la lista de smbolos
Para saber si unas funciones determinadas existen, es decir si estn definidas, creamos
una lista con sus nombres y se lo pasamos como argumento a atoms-family
(atoms-family 1 (list car cdr)) devolver una lista con sus nombres (CAR CDR)
Aunque lo habitual no es emplear esta funcin para detectar si estn definidas las
funciones de AutoLISP, sino para detectar nuestras propias funciones y variables:
(atoms-family 1 (list car cdr variable)) devuelve (CAR CDR nil) ya que el
smbolo variable no tiene asociado ninguna funcin, ni variable de AutoLISP.
Si definimos:
(setq variable 12.5)
(atoms-family 1 (list car cdr variable)) devolver (CAR CDR
VARIABLE) devuelve el nombre de la variable, no su valor.
Si definimos una funcin de usuario:
(defun 2+ ( numero / ) (+ numero 2.0))
La funcin 2+ recibe un nmero y le suma 2.0.
(atoms-family 1 (list car cdr 2+)) devolver (CAR CDR 2+)
(QUOTE expresin)
Esta funcin recibe una expresin y devuelve su literal, es decir devuelve la expresin tal
cual, sin evaluar.
(quote +) devolver +
Esto es lo mismo que hacamos en APPLY y MAPCAR:
(apply + (list 2.0 3.5 6.8))
pues el apstrofo es el diminutivo o el alias de la funcin QUOTE.
(quote (setq a texto b 10.0)) devolver (SETQ A texto B 10.0)
sera lo mismo escribir:
(setq a texto b 10.0)
Pero no podremos escribir esta ltima lnea en la ventana de comandos de AutoCAD, por
que el interprete de comandos no detecta el parntesis en primer lugar y piensa que no es
una expresin de AutoLISP sino un comando de AutoCAD. Podemos utilizar un truco para
evaluar la expresin desde la ventana de comandos:
(progn (setq a texto b 10.0))
PROGN en realidad no hace nada, simplemente nos serva para salvar la limitacin de IF
de indicar ms de 1 expresin, ya que evala las expresiones que contiene y devuelve el
resultado de la ltima expresin evaluada. En este caso nos sirve para contener la
expresin de AutoLISP anterior.
Ahora si devolver (setq A pepe B 10.0). Pero no hemos asignado valores a las
variables, ya que (setq A pepe B 10.0) no se ha evaluado.Puedes hacer la prueba
escribiendo !a o !b en la ventana de comandos de AutoCAD.
(quote (15.0 10.6 9.2)) devolver (15.0 10.6 9.2) es decir, devuelve una lista. Tambin
funcionara con (15.0 10.6 9.2)
Por tanto en lugar de:
(apply + (list 2.0 3.5 6.8))
podemos poner:
(apply + (quote (2.0 3.5 6.8)))
y tambin:
(apply + (2.0 3.5 6.8))
De modo que podemos usar QUOTE y para crear listas. Pero con excepciones, ya que si
hacemos:
(setq a 2.0)
(apply + (a 3.5 6.8)) indicar: ; error: tipo de argumento errneo: numberp: A
a es el nombre de una variable, es un smbolo, cuya variable tiene asociado el valor 2.0
(apply + (list a 3.5 6.8)) esto si funcionar porque (list a 3.5 6.8) devolver (2.0 3.5
6.8), LIST se evala pero QUOTE no evala la expresin que recibe.
Resumiendo: Podemos crear listas con QUOTE o con pero siempre que conozcamos los
elementos de dichas listas, y que estos sean valores concretos no determinados a partir
de expresiones o almacenados en variables.
Algunos ejemplos ms:
(setq maximo (apply (quote max) (quote (10.5 15.2 9.3))))
(setq minimo (apply min (10.5 15.2 9.3)))
(foreach p ((0.0 0.0 0.0) (10.0 10.0 0.0)) (command _.circle p 1.0))
(setq vector (mapcar - (10.0 10.0 0.0) (5.0 0.0 0.0)))
(setq ptomed (mapcar (lambda ( num ) (/ num 2.0)) (mapcar + (10.0 10.0 0.0) (5.0
0.0 0.0))))
(EVAL expresin)
Esta funcin evala la expresin que recibe.
(eval 2.5) devuelve el resultado de evaluar 2.5, es decir devuelve 2.5
(eval Soy una cadena de texto) devolver Soy una cadena de texto
Pero veamos un ejemplo algo ms complicado:
(setq a 15.5)
(setq b (quote a))
Qu valor tendr asignado b?
(quote a) es el nombre de la variable a, es decir el smbolo.
As que b tendr asociado el nombre de la variable a.
(+ b 10.0) dar un error
(eval b) devolver 15.5 de modo que podemos hacer lo siguiente:
(+ (eval b) 10.0) devolver 25.5
(eval (+ 10.0 5.5)) devolver 15.5 ya que (+ 10.0 5.5) devuelve (+ 10.0 5.5) y eval, lo
evala.
(READ texto)
Esta funcin lee el texto que recibe y devuelve la primera palabra pero como un literal,
un smbolo, no como una cadena de texto.
(read AutoLISP) devuelve AUTOLISP
(read Curso de AutoLISP) devolver CURSO
(read (15.2 9.3 15.5)) en este caso devolver (15.2 9.3 15.5) porque al detectar el
parntesis lo considera un mismo trmino. Es algo similar a escribir en la ventana de
comandos de AutoCAD, si no se pone un parntesis delante no dejar escribir espacios
en blanco. Pues este es otro mtodo para crear una lista, por tanto:
(apply max (read (15.2 9.3 15.5))) devolver el mximo de la lista de nmeros
indicados
Y que pasa si hacemos:
(setq txt (setq a 5.5))
(read txt) devolver (setq a 5.5)
y ahora podemos evaluarlo con EVAL
(eval (read txt)) devolver 5.5 y asigna a la variable a el valor 5.5
Para qu sirve esto? Por ejemplo para solicitar al usuario una expresin de AutoLISP y
evaluarla:
(setq txt (getstring T \nExpresin de AutoLISP: ))
(setq valor (eval (read txt)))
En este caso asignamos a valor el resultado de evaluar una expresin de AutoLISP
introducida por el usuario.
(SET literal_de_smbolo expresin)
Esta funcin es muy parecida a SETQ, se diferencia en que espera el literal de un
smbolo. Veamos algunos ejemplos:
(setq num1 5.0) asigna a la variable num1 el valor 5.0
(set num2 5.5) da un error, ya que espera un literal
(set num2 5.5) asigna a la variable num2 el valor 5.5
Si probamos:
(setq (read num1) 5.0) nos da un error, ya que SETQ no acepta una expresin como
smbolo.
Sin embargo SET si lo acepta:
(set (read num2) 15.0) asigna a la variable num2 el valor 15.0
Carga automtica de los archivos de AutoLISP
Carga automtica de los archivos de
AutoLISP
AutoCAD carga automticamente dos archivos de AutoLISP, si es que existen y se
encuentran en los directorios de soporte. Se trata del ACAD.LSP y el ACADDOC.LSP.
El archivo ACAD.LSP se carga al iniciar AutoCAD y el ACADDOC.LSP se carga siempre
que se abre un dibujo, o se crea un dibujo nuevo. De modo que las funciones
contenidas en el ACAD.LSP tan slo estarn cargadas en el dibujo que se abre al
iniciar AutoCAD, mientras que las funciones contenidas en el ACADDOC.LSP estarn
cargadas en todos los dibujos.
Lo lgico ser entonces guardar nuestras funciones en el ACADDOC.LSP y no en el
ACAD.LSP.
El ACAD.LSP se utilizar tan solo para almacenar aquellas funciones que nos interese
ejecutar al cargar AutoCAD. Por ejemplo, podemos utilizar el archivo ACAD.LSP para
mostrar una imagen, foto, al iniciar AutoCAD.
Si tenemos alguna rutina que se utilice mucho, o que se suele ejecutar en todos los
dibujos la meteremos en el ACADDOC.LSP
Qu rutinas meteremos en el ACADDOC.LSP? Conviene que no sean demasiadas, para
que dicho archivo sea ms manejable y adems para no ocupar demasiado espacio en la
memoria del ordenador. Por tanto, solo incluiremos en el ACADDOC.LSP las rutinas ms
empleadas. Por ejemplo una funcin de tratamiento de errores, o las funciones GAR y
RAG que se utilizan bastante, y adems son bastante pequeas.
Qu pasa si metemos tambin nuestra funcin C:CIRCPERI? Pues no pasara nada
pero Vas a dibujar circunferencias dadas por su permetro en todos los dibujos? no
creo, por eso no merece la pena aadirla al ACADDOC.LSP, ya que si hacemos lo mismo
con todas nuestras rutinas el archivo ACADDOC.LSP tendra un tamao descomunal.
Podemos guardar la rutina CIRCPERI en un archivo independiente y cargarlo desde el
ACADDOC.LSP. En el caso de la rutina CIRCPER, podemos guardarla en el
archivo CIRCPERI.LSP, dentro de uno de los directorios de soporte de AutoCAD, e incluir
la siguiente lnea en el ACADDOC.LSP:
(load circperi.lsp (alert Archivo Circperi.lsp no encontrado))
De este modo tenemos la rutina CIRCPERI en un archivo independiente, lo que nos
soluciona parte del problema, ya que el archivo ACADDOC.LSP ser bastante corto y si
queremos modificar la rutina CIRCPERI tan solo tenemos que manipular un archivo en el
que nicamente est definida dicha funcin.
Pero seguimos teniendo algunos problemas: Si nuestra coleccin de rutinas es muy
extensa tenemos que aadir una lnea de cdigo como la anterior para cada rutina, lo que
se traducir en un archivo ACADDOC.LSP bastante grande y difcil de manipular.
Adems, el mayor inconveniente es que todas nuestras rutinas se cargaran en memoria
automticamente para cada archivo de dibujo, con lo que estaremos sobrecargando la
memoria del ordenador de forma innecesaria.
(AUTOLOAD archivo lista_comandos)
La funcin AUTOLOAD es similar a LOAD, tambin nos permite cargar archivos de
AutoLISP pero slo aquellos archivos que contengan comandos, por ejemplo
C:CIRCPERI pero no servir para archivos en los que solo tengamos funciones como
GAR y RAG.
Qu ventaja tiene el utilizar AUTOLOAD en lugar de LOAD? Al utilizar AUTOLOAD los
archivos no se cargan automticamente, simplemente se predispone a AutoCAD para que
los cargue en cuanto se ejecute uno de los comandos indicados como argumentos en la
lista de comandos.
Por ejemplo, si tenemos un archivo con 3 comandos:
(defun C:comando1 ( / ) .)
(defun C:comando2 ( / ) .)
(defun nosoyuncomando ( / ) .)
(defun C:comando3 ( / ) .)
En el archivo ACADDOC.LSP podramos aadir la siguiente lnea:
(autoload archivo.lsp (comando1 comando2))
Al iniciar un dibujo, se carga el ACADDOC.LSP y se evala la lnea anterior, pero
archivo.lsp no se cargar hasta que se ejecute el comando1 o el comando2. Sin
embargo no se cargar si ejecutamos el comando3, ya que no lo hemos incluido en la
lista de comandos. Adems, al ejecutar uno de los dos comandos anteriores se carga el
archivo, de modo que la funcin nosoyuncomando tambin se cargar, al igual que
elcomando3.
Y qu pasa con los archivos de AutoLISP que no tienen comandos, es decir en los que
solo hay funciones? Pues tendremos que cargarlos con LOAD, con lo cual
se cargaran todos directamente en la memoria y si tenemos bastantes funciones
seguimos teniendo el mismo problema que antes.
Cmo podemos solucionarlo? Pues cargando las funciones solo cuando hacen falta. Por
ejemplo, supongamos que en el comando C:CIRPERI se utiliza la funcin RAG. Tenemos
dos opciones:
1. Incluir la funcin RAG en el archivo Circperi.lsp. De este modo al cargarse el
archivo se cargar la funcin RAG. Esto se suele hacer para las funciones que slo se
utilizan en un comando determinado.
2. Pero si la funcin RAG deseamos utilizarla en otros comandos, es mejor utilizar el
siguiente mtodo: Incluir la funcin RAG en un archivo independiente Rag.lsp y aadir
la siguiente lnea de cdigo dentro del archivo
Circperi.lsp: (load Rag.lsp (alert Archivo Rag.lsp no encontrado))
En el segundo modo, el archivo Circperi.lsp se cargar cuando se ejecute uno de los
comandos indicados en la funcin Autoload del archivo ACADDOC.LSP. Y al cargarse el
archivo Circperi.lsp se cargar mediante la funcin Load el archivo Rag.lsp. Utilizando
este mtodo podemos utilizar una misma funcin en mltiples rutinas, tan solo debemos
asegurarnos de que dicha funcin est definida, es decir que se ha cargado el archivo en
el que se encuentre.
Los archivos ACAD.LSP y ACADDOC.LSP no tienen porque existir. Si no existen pueden
crearse, teniendo en cuenta que se deben guardar en uno de los directorios de soporte de
AutoCAD. En caso de que ya existan, se pueden editar para incluir el cdigo deseado.
Conviene hacer una copia de seguridad de estos archivos porque muchos programadores
crean sus propios archivos ACAD.LSP y ACADDOC.LSP de modo que al instalar un
mdulo o aplicacin para AutoCAD, podis sobreescribir vuestros archivos.
Existen otros dos mtodos para cargar automticamente rutinas de AutoLISP. El primero
consiste en utilizar la opcin disponible en el men de AutoCAD Herr > AutoLISP >
Cargar ya que en el letrero de dialogo que aparece se pueden cargar rutinas y se
pueden seleccionar las rutinas que se desean cargan al inicio.
El tercer mtodo para cargar automticamente las rutinas de AutoLISP es editando los
mens de AutoCAD, pero esto lo veremos ms adelante.
Ejecucin automtica de cdigo de
AutoLISP
Hemos visto que el archivo ACADDOC.LSP se carga automticamente en todos los
dibujos pero Cmo podemos ejecutar automticamente una funcin al iniciarse un
dibujo?
Supongamos que tenemos definida la funcin GAR dentro del archivo ACADDOC.LSP:
(defun GAR )
Para ejecutarla, tan slo debemos aadir en dicho archivo la siguiente lnea de cdigo:
(GAR)
En caso de que dicha funcin tenga argumentos, estos deben indicarse:
(GAR 3.141592)
Cmo ejecutaramos automticamente el comando C:CIRCPERI?
Una vez cargado el comando, para ejecutarlo desde la ventana de comandos de
AutoCAD podemos escribir directamente su nombre CIRCPERI para ejecutarlo. Sin
embargo, desde un archivo de AutoLISP no podemos ejecutarlo as. Tenemos que
hacerlo de esta otra forma:
(C:CIRCPERI)
De modo que podramos incluir en el archivo ACADDOC.LSP las dos siguientes lneas de
cdigo:
(load circperi.lsp (alert Archivo Circperi.lsp no encontrado)) ; Carga el comando
(C:CIRCPERI) ; Ejecuta el comando
Sera mejor utilizar AUTOLOAD en lugar que LOAD en el ejemplo anterior? Pues no.
Utilizar AUTOLOADno tendra mucho sentido, puesto que al ejecutar el comando el
archivo en el que est definido se cargara, por tanto podemos cargarlo ya antes.
Existe otro mtodo para ejecutar cdigo directamente. Se trata de escribirlo directamente,
es decir sin meterlo dentro de ninguna funcin o comando. Por ejemplo, si incluimos las
siguientes lneas de cdigo en el archivo ACADDOC.LSP nos permitir dibujar un circulo
dado su centro y su permetro:
(setq pto (getpoint \nCentro del crculo: ))
(setq peri (getdist pto \nPermetro: ))
(command _.circle pto (/ peri (* 2.0 PI)))
Pero en este caso, el cdigo anterior solo se ejecuta una vez. Si queremos dibujar otro
crculo dado su permetro, no tendramos la funcin CIRCPERI definida.
Para qu se suele utilizar este mtodo?
Por ejemplo, para mostrar mensajes informativos o de bienvenida:
(alert Estas seguro de que quieres utilizar AutoCAD?)
(alert Estas realmente seguro?)
(alert Seguro, seguro?)
Aunque no os aconsejo que utilicis este ejemplo, os cansarais de l a los 5 minutos.
Adems de mensajes de bienvenida podis hacer otras cosas ms tiles, como asignar
valores iniciales a algunas variables:
(setq directorio c:\\rutinas\\)
Tambin podis modificar el valor de alguna variable de sistema de AutoCAD:
(setvar osmode 7)
S::STARTUP
Existe otro mtodo para ejecutar cdigo automticamente. Hemos visto que AutoCAD
utiliza una funcin de tratamiento de errores por defecto que se llamaba *error* y tambin
hemos visto que podamos redefinirla creando nuestra propia funcin de tratamiento de
errores. Bien, pues AutoCAD tambin tiene una funcin interna que se ejecuta
automticamente se trata de S::STARTUP.
El que las funciones *error* y S::STARTUP tengan estos nombres tan raros es para evitar
que a alguien se le ocurra denominar as a alguna funcin de otro tipo.
Para definir la funcin S::STARTUP se utiliza DEFUN, al igual que para cualquier otra
funcin.
(defun S::STARTUP ( / )
(setq directorio c:\\rutinas\\)
)
La funcin S::STARTUP podemos utilizarla para los mismos ejemplos que se daban
antes.
Por ltimo, para terminar el tema, un consejo: Al programar hay que tener bastante
cuidado para no cometer errores, ya que el omitir un simple parntesis o unas comillas,
por ejemplo, modificaran totalmente nuestras funciones. Cuando adems estas funciones
se van a ejecutar automticamente, como en los ejemplos que se han expuesto, la
precaucin al programar debe ser mxima.
Operaciones con archivos
Antes de comenzar con el tema de lectura y escritura de archivos, veamos una pequea
rutina: CARGALISP
CARGALISP recibir una lista como la siguiente: ((c:\\rutinas\\lisp1.lsp (gar rag))
(c:\\rutinas\\lisp2.lsp (inverso tg)))
En la que cada elemento es a su vez otra lista formada por el nombre de un archivo de
AutoLISP (con su ruta, si es necesario) y una lista con los nombres de las funciones (o
variables globales) definidas en dicho archivo. Por ejemplo, en el caso anterior se supone
que en el archivo c:\\rutinas\\lisp1.lsp estn definidas las funciones gar y rag y que
en el archivo c:\\rutinas\\lisp2.lsp estn definidas las funciones inverso y tg.
CARGALISP cargar los archivos de AutoLISP indicados si no estaban definidas, o
cargadas que es lo mismo, las funciones indicadas para cada archivo.
(defun CARGALISP ( lst / )
(while lst
(if (not (apply and (atoms-family 1 (cdar lst))))
(progn
(load (caar lst))
(prompt (strcat \nCargando archivo (caar lst) ))
)
)
(setq lst (cdr lst))
)
)
Tal como est la macro funciona perfectamente. Pero puede producirse un pequeo error.
Qu pasa si no existe, o no se encuentra, el archivo lisp1.lsp o cualquiera de los
archivos de la lista que reciba CARGALISP?
(FINDFILE archivo)
Esta funcin nos permite comprobar la existencia de un archivo. Si el archivo existe
devuelve su nombre y si no existe, o no lo encuentra en la ruta indicada, devolver nil.
En caso de que no se indique la ruta en la que debe buscar el archivo, lo buscar en los
directorios de soporte de AutoCAD.
(findfile c:\\autoexec.bat) debera devolver c:\\autoexec.bat, suponiendo que
vuestro PC tiene Autoexec.bat, claro
(findfile c:\\noexisto.bat) debera devolver nil
FINDFILE en realidad no hace nada, tan solo se utiliza para comprobar la existencia de un
archivo. Entonces, Cuando se utilizar FINDFILE? Pues os voy a poner varios ejemplos
en los que se suele utilizar:
1. Antes de cargar un archivo con LOAD o AUTOLOAD
2. Antes de abrir un fichero de texto, ya sea para leerlo o escribir en l.
3. Antes de abrir un archivo de dibujo en AutoCAD.
4. Antes de cargar y utilizar un archivo DCL (Letrero de dialogo) en AutoLISP.
Por tanto, deberamos modificar el cdigo de la funcin CARGALISP para comprobar la
existencia de los archivos a cargar.
(defun CARGALISP ( lst / )
(while lst
(if (not (apply and (atoms-family 1 (cdar lst))))
;; Comprueba si todas las funciones del primer elemento de la lista
;; estn cargadas
(if (not (findfile (caar lst)))
(alert (strcat No se ha encontrado el archivo (caar lst)))
;; No se encuentra el archivo
(progn
(load (caar lst))
;; Carga el archivo
(prompt (strcat \nCargando archivo (caar lst) ))
;; Indica que se ha cargado el archivo
)
;; Se encuentra el archivo
)
)
(setq lst (cdr lst))
;; Pasa al siguiente elemento de la lista
)
;; Para cada elemento de la lista
)
(GETFILED titulo_letrero
archivo_defecto extensin_defecto
modo)
Esta funcin nos permitir seleccionar un archivo, ya veremos ms adelante como
seleccionar varios archivos. GETFILED muestra un letrero de gestin de
archivos tpico de Windows.
Podemos pasar a GETFILED el ttulo del letrero, el archivo seleccionado por defecto y la
extensin de archivos que se buscar por defecto. GETFILED devuelve el nombre y ruta
del archivo seleccionado.
El argumento modo es de tipo binario y ofrece los siguientes valores:
1 > Para designar un archivo nuevo, es decir, que no exista.
2 > Desactiva la casilla Teclearlo.
4 > Permite indicar cualquier extensin.
8 > Devuelve el nombre del archivo, sin la ruta
(getfiled Selecciona un archivo c:\\autoexec.bat bat 0)
No pasa nada al pulsar en Abrir, ya que no se abre el archivo. GETFILED tan solo nos
deja seleccionarlo y devuelve su nombre.
(getfiled Selecciona un archivo nuevo 1)
Leer y escribir archivos de texto
AutoLISP nos permite leer y escribir archivos de texto ASCII. Al utilizar archivos de texto
en nuestras rutinas debemos siempre seguir los siguientes pasos:
1. Comprobar si existe el archivo.
2. Abrir el archivo.
3. Leer o escribir en el archivo.
4. Cerrar el archivo.
(OPEN archivo modo)
Esta funcin nos permite abrir un archivo de texto y devuelve un descriptor de archivo.
Qu es un descriptor de archivo? Es algo similar a un canal por el que se comunica
AutoCAD con dicho archivo. Podemos abrir varios archivos, es decir abrir varios canales
de comunicacin, de modo que al leer o escribir en un archivo, tenemos que saber cual es
el canal de comunicacin por el que vamos a recibir o enviar datos, es decir necesitamos
conocer el descriptor del archivo.
Hay tres formas de abrir un archivo de texto, en funcin de lo que se quiera hacer a
continuacin con dicho archivo. El argumento modo es el encargado de diferenciar estas
tres formas distintas de abrir archivos:
Podemos abrir un archivo para leerlo > modo r
Podemos abrir un archivo de texto para escribir en l comenzando desde la
primera lnea > modo w
Podemos abrir un archivo de texto para escribir en l a partir de la ltima lnea
> modo a
Para abrir el archivo autoexec.bat en modo lectura:
(open c:\\autoexec.bat r)
Devuelve #<file c:\\autoexec.bat> es decir, el descriptor del archivo o nil si el archivo
no existe.
Aunque en la lnea anterior se abre el archivo autoexec.bat en modo lectura, luego
no podramos hacer nada con l ya que no hemos guardado el descriptor de archivo. Es
decir, no podemos decirle a AutoCAD que lea texto por el canal de comunicacin que
hemos abierto, ya que no conocemos el descriptor del archivo. Incluso tampoco
podramos cerrarlo y quedar abierto en la memoria hasta que se cierre la sesin de
AutoACD. Cmo se debe utilizar entonces la funcin OPEN?
(setq darch (open c:\\autoexec.bat r))
De este modo el valor devuelto por OPEN, el descriptor de archivo, se almacena en la
variable darch.
Antes de ver como leer o escribir en los archivos de texto, veamos como tendriamos que
cerrarlos.
(CLOSE descriptor_archivo)
Cierra el archivo cuyo descriptor se indica y devuelve nil. Fjate en lo importante que es
guardar el descriptor del archivo en una variable, ya que si no lo hacemos no slo no
podremos leer o escribir en el archivo, tampoco podremos cerrarlo.
(close darch)
Hay que tener una cosa en cuenta al trabajar con archivos de texto: Al abrir un archivo de
texto debemos indicar el modo (lectura, escritura, o adiccin) de modo que debemos
saber de antemano lo que vamos a hacer con el archivo, y SLO podremos hacer una
cosa, o leer o escribir. Aunque podemos abrir un archivo en modo escritura, escribir en l,
cerrarlo, abrirlo en modo lectura, leer y volver a cerrarlo.
Otra cuestin de especial inters es que si abrimos un archivo de texto existente en modo
escritura w, nos habremos cargado todo lo que tena anteriormente dicho archivo. As
que mucho cuidado con los archivos que se abren en modo escritura.
Escritura de archivos de texto
Para crear un archivo de texto debemos abrirlo en modo escritura:
(setq darch (open c:\\nuevo.txt w))
Devuelve #<file c:\\nuevo.txt> el descriptor del archivo abierto, que se almacena en la
variable darch.
Tambin podemos abrir el archivo en modo aditivo, para continuar escribiendo a partir de
la ltima lnea de texto del archivo.
Bien, ya tenemos abierto nuestro archivo de texto, vamos a escribir en l:
(PRIN1 [expresin [descriptor_archivo]])
Esta funcin escribe una expresin en el archivo cuyo descriptor se indique. Si no se
indica el descriptor de archivo, la expresin se escribir en la ventana de comandos de
AutoCAD. Veamos algunos ejemplos:
(setq a 5.5 b Curso de AutoLISP)
(prin1 a) escribir el valor de la expresin a en la ventana de comandos de AutoCAD, es
decir, escribir 5.5
Si ejecutas las dos lneas de cdigo anteriores desde la ventana de comandos de
AutoCAD, veras que (prin1a) parece devolver 5.55.5 en realidad devuelve 5.5 pero el eco
de mensajes, repite el valor devuelto por la expresin (prin1 a) es decir 5.5 Por eso,
aparece 5.55.5
(prin1 b darch)
Escribir en Curso de AutoLISP con las comillas incluidas en el archivo C:\Nuevo.txt.
Fjate que PRIN1 puede escribir tanto cadenas de texto como nmeros. Sin embargo la
funcin PROMPT tan slo puede recibir como argumento una cadena de texto.
(prin1 a) escribe A
(prin1 (+ 15 5.5)) escribe 20.5
Hemos indicado una expresin como argumento, si utilizamos PROMPT en lugar
de PRIN1 dar un error.
(prin1 (+ 15 5.5)) escribe (+ 15 5.5)
Si no se indica la expresin a escribir, escribe una cadena nula
(prin1)
Por eso se suele emplear como ltima expresin de los comandos, para que la salida de
nuestras rutinas sea limpia y no se vea el eco de mensajes de la ltima expresin
evaluada.
(prin1 (strcat \t b)) devuelve \tCurso de AutoLISP
PRIN1 no entiende los caracteres de control como \n \t etc.
(PRINT [expresin [descriptor_archivo]])
Esta funcin es muy parecida a PRIN1, veamos en que se diferencian.
(progn (prin1 a) (prin1 a)) escribe 5.55.5
(progn (print a) (print a)) escribe 5.5 pasa a otra lnea y escribe 5.5
Es decir, PRINT salta de lnea antes de escribir la expresin indicada. PRINT escribe la
expresin en una lnea nueva.
(print) devuelve una cadena nula, por eso tambin se emplea como ltima expresin de
los comandos
(print (strcat \t b)) devuelve \tCurso de AutoLISP, es decir PRINT tampoco
entiende los caracteres de control.
Por supuesto, al igual que sucede con PRIN1 si se indica un descriptor de archivo en
lugar de escribir en la ventana de comandos de AutoCAD lo har en un archivo.
(PRINC [expresin [descriptor_archivo]])
Esta funcin tambin es muy parecida a las anteriores.
(progn (princ a) (princ a)) escribe 5.55.5
(princ) devuelve una cadena nula, por eso tambin se emplea como ltima expresin de
los comandos.
(princ (strcat \t b)) ahora escribe Curso de AutoLISP pero tabulado.
Por tanto, PRINC se diferencia de las anteriores en que si interpreta el significado de
los caracteres de control.
Al igual que las funciones anteriores, si se indica un descriptor de archivo escribir en
dicho archivo en lugar de hacerlo en la ventana de comandos de AutoCAD.
(princ \nBienvenido al curso darch)
(WRITE-CHAR cdigo_ASCII [descriptor_archivo])
Esta funcin permite escribir un carcter recibe como argumento su cdigo ASCII. Si se
indica el descriptor de archivo lo escribir en el archivo y sino lo escribir en la ventana de
comandos de AutoCAD.
(write-char 65) escribe A.
Es lo mismo que escribir (write-char (ascii A))
(WRITE-LINE texto [descriptor_archivo])
Esta funcin escribe una lnea de texto entera. El primer argumento debe ser una cadena
de texto, no una expresin. Y si se indica un descriptor de archivo, escribir la lnea de
texto en el archivo, en caso contrario la escribe en la ventana de comandos de AutoCAD.
(write-line Curso de AutoLISP)
Tambin se puede escribir en un archivo indicando el descriptor correspondiente
(write-line Muchas gracias darch)
Ahora podemos cerrar el archivo de texto que hemos abierto
(close darch)
Lectura de archivos de texto
Para leer un archivo de texto debemos abrirlo en modo lectura y guardar su descriptor en
una variable que podamos utilizar despus:
(setq darch (open c:\\nuevo r))
(READ-CHAR [descriptor_archivo])
Lee un carcter del archivo cuyo descriptor se indica y devuelve su cdigo ASCII.
(read-char darch) devuelve 34, que es el cdigo ASCII del primer caracter del archivo de
texto, que es unas comillas
Si no se indica el descriptor, lo lee de la ventana de comandos de AutoCAD.
(read-char) espera a que introduzcas un caracter y devolver su cdigo ASCII
(READ-LINE [descriptor_archivo])
Esta funcin lee una lnea del archivo de texto indicado.
(read-line darch) devolver Curso de AutoLISP\
Observa que las comillas iniciales del archivo ya las habamos ledo con la funcin
anterior read-char.
Al leer un archivo de texto vamos avanzando en l, de modo que si volvemos a
escribir la linea anterior
(read-line darch) devolver Bienvenido al curso Muchas gracias
Esta es la ltima lnea de nuestro archivo as que si volvemos a repetir la lnea anterior
(read-line darch) devolver nil
De este modo sabremos que hemos llegado al final del archivo y podremos cerrarlo
(close darch)
Si intentamos volver a leer ahora en el archivo obtendremos un error.
Si no se indica el descriptor de archivo, la leer de la ventana de comandos de AutoCAD.
(read-line) escribe una palabra o frase y devolver una cadena de texto con lo que has
escrito.
Como ya adelant hace unos das nuestro amigo Gabriel, empezaremos hablando de
algunos caracteres especiales bsicos en Autolisp, no sin antes aclarar que la mayora
de comentarios y notaciones empleadas a partir de ahora han sido tomadas de los
libros cuya bibliografa paso a detallar, y que recomiendo le echis un vistazo
Autor !ose Antonio "a#adura y !avier $pez "it Autolisp %&,%',%( )dit *c Gra+ ,ill
Autor-einaldo togores y Csar .tero "it /rogramacin en Autocad con 0isual $isp
)d1 *c Gra+ ,ill
1 Punto y coma: ; 2irve para a3adir comentarios o aclaraciones que nos ayuden a
entender me#or nuestra rutina1 "odo lo que vaya detrs del punto y coma, en realidad
podramos borrarlo y el programa no sufrira alteraciones1 As que este carcter slo lo
usaremos para esto1
2 Parntesis: ( ) 4ebe haber el mismo n5mero de parntesis de apertura que de
cierre1 4e lo contrario se producir un error1 $os utilizaremos para preceder cualquier
comando de Autolisp y para dar fin a dicho comando1
3 Comillas: " " 2e utilizan para encerrar e6presiones de te6to que queremos que
aparezcan en la pantalla, ya sea en la lnea de comando o en una ventana1 "odo lo que
est entre comillas ser considerado como una cadena de te6to, incluso los parntesis,
comas, punto y comas1111 Como los parntesis, debe haber un n5mero par de
comillas1
4 Punto: . 2e usa como punto decimal1
5 Apstro!o: " )quivale al comando 789."):1 4evuelve el literal de la e6presin1
# Contra$arra: % 4entro de una cadena de te6to podemos incluir una contrabarra
seguida de uno de los siguientes caracteres
%n -etorno de carro, nueva lnea
%r -eturn
%t tabulador
)s decir1 2i escribimos 7G)"/.;<" pt =>n2e3ala un punto=: , cuando Autolisp eval5e
esta e6presin, antes de escribir =2e3ala un punto= en la lnea de comando, har un
salto de carro para que no aparezcan dos o ms e6presiones distintas, unas a
continuacin de otras1
& Cierre a'miracin: ( 2irve para e6traer desde la lnea de comandos, el valor de
una variable1
)#1 72)"8 radio ?1@'A:
2i tecleamos Bradio en la lnea de comandos nos aparecer ?1@'A
AC)A*AC+,-./
CAutolisp no distingue entre may5sculas y min5sculas1
C)s conveniente usar el nombre de las rdenes de Autocad en ingls1 2i traba#amos
con Autocad espa3ol y queremos saber el nombre en ingls tecleamos en la lnea de
comando
7G)"C<A*) =orden en catellano=:
)#1 7G)"C<A*) Dte6toE: y aparece =Fte6t=
CAutolisp siempre traba#a en radianes
CP+ es el n5mero '1%(%?A&@11111, por lo que ninguna variable podr llamarse /;1
C0 es el smbolo de "rue, cierto, por lo que ninguna variable podr llamarse "1
Cnil es el smbolo de falso, por lo que ninguna variable podr llamarse nil1 2iempre
aparecer en min5sculas, nunca <;$1
(1.23- 4sim$5 4ar65) 1.2+-+* 23-C+,-./
$as distintas funciones que forman una rutina se definen mediante el comando
74)G9< HsimbI HargI:
4entro de una rutina podr haber decenas de funciones1 $o que suele hacerse es crear
una funcin principal, desde la cual se irn llamando al resto de funciones secundarias1
)s como si tuvisemos varias rutinas dentro de otras1
HsimbI es el nombre de nuestra funcin
HargI es el nombre de las variables que vamos a tener dentro de esta funcin
;mportante $as variables pueden ser locales o globales1 )sto quiere decir que
2i son globales, podremos seguir utilizndolas fuera de esta funcin1
2i son locales, slo tendrn valor dentro de esta funcin1
"anto unas como otras van entre parntesis1 $as locales van precedidas de una
barra J
2i ponemos un parntesis sin nada 7:, daremos por supuesto que todas son globales1
,ay que tener en cuenta que en rutinas muy largas, donde e6isten muchas variables, y
donde utilizamos otras rutinas, cuantas ms variables globales tengamos, ms lentos
pueden ser los clculos1
9na ver gargada una rutina, para e#ecutarla en otras ocasiones dentro de la misma
sesin de Autocad sin tener que volver a cargarla, debemos a3adir c delante del
nombre de la funcin, para que, tecleando dicho nombre en la lnea de comando ya
arranque de nuevo1
(/.07 4sim$15 4e8pr15 4sim$25 4e8pr25.....) A0*+93+* :A),*./
/ues eso, sirve para atribuir valores a una variable1
)# 72)"8 radio ? 6 %??1'@ y KL?1A@% nombre =2oy un monstruo=:
2i tecleamos esto en la lnea de comandos y luego vamos tecleando sucesivamente
Bradio aparece ?
B6 aparece %??1'@
By aparece KL?1A@%
Bnombre aparece =2oy un monstruo=
(P*,;P0 4mensa<e5) ./C*+9. ;.-/A=.
)scribe un mensa#e en la lnea de comandos
(0.*P*+) /A)0A A 3-A -3.:A )+-.A
(>.0P,+-0 4punto5 4mensa<e5) +-0*,13C. 3- P3-0,Mien mediante
se3alamiento en pantalla, o bien mediante teclado1
)#1
72)"8 pt 7G)"/.;<" =>n;ntroduce un punto=::
4espus de introducir un punto, sus coordenadas se almacenan en la variable pt1
(C,;;A-1 4ar65) .=.C30A 3-A ,*1.- 1. A30,CA1
4ecir antes de nada que es recomendable utilizar el nombre de la orden en ingls,
precedido de un guin ba#o1 As, independientemente de la versin de Autocad y del
idioma, salvo en casos e6cepcionales, nuestra rutina funcionar siempre1
)#1
7C.**A<4 =Fline= pt N7%?O %&O: ==:
)n este caso dibu#a una lnea desde el punto pt, cuyas coordenadas ya habrn sido
determinadas antes, hasta el punto de coordenadas 6P%?O e yP%&O1
)l nombre de la orden debe ir siempre entre comillas, as como cualquier opcin propia
de la orden, como por e#emplo el =enter= final1
)#emplo general
Copiar esta rutina en el editor de 0isual $isp1
C'i6o:
QQQQQQQQQQQQ-utina para dibu#ar tres lneas desde un punto1
74)G9< cdibFlineas 7 J pt% pt& pt' pt(:
Q74)G9< cdibFlineas 7:
7/-.*/" =>n)ste programa dibu#a tres lnas desde un punto=:
72)"8 pt% 7G)"/.;<" =>n/rimer punto =::
72)"8 pt& 7G)"/.;<" =>n2egundo punto =::
7C.**A<4 =Fline= pt% pt& ==:
72)"8 pt' 7G)"/.;<" =>n"ercer punto =::
7C.**A<4 =Fline= pt% pt' ==:
72)"8 pt( 7G)"/.;<" =>nCuarto punto =::
7C.**A<4 =Fline= pt% pt( ==:
:
Como observaris, hemos creado una funcin llamada dibFlineas, a la que hemos
a3adido el prefi#o c para poder e#ecutarla cuando queramos desde la lnea de
comandos, una vez la hayamos cargado, como ya se e6plic en el ")*A %1
)sta funcin contiene ( variables que le hemos dado carcter local, con lo que, una vez
termine, se perdern los valores de sus variables1 2in embargo, si cambias el punto y
coma de la segunda lnea Q74)G9< cdibFlineas 7: y lo pasis a la primera lnea
74)G9< cdibFlineas 7 J pt% pt& pt' pt(:, la rutina queda e6actamente igual, pero
ahora las variables son globales y podemos utilizarlas en otro momento o conocer su
valor tecleando en la lnea de comando Bpt%, Bpt&11111
,aced la prueba de las dos maneras1
"ambin observaris que hemos utilizado >n para salto de lnea1 /odis eliminarlo y ver
lo que pasa1
9n detalle importante1 A mi me gusta poner el abre parntesis y el cierra parntesis en
la misma lnea1 /ero si se hace muy largo, como es el caso del cierra parntesis de una
funcin, me gusta ponerlo en la lnea vertical del que abre1
R con esto doy por terminada esta leccin1 Como siempre, si alguien desea a3adir o
rectificar algo, pues ya sabe1
"ema %1 +ntro'uccin Gunciones *atemticas
Autor *o$ier?o
/asare a describir las 4istintas Gunciones de lisp porcin "emas1
)mpecemos /or $a de *atemticas1
S 2uma
T -esta
C *ultiplicacin
J 4ivisin
-esto rem 4e 9na 4ivisin de neteros
% S suma %
% T resta %
Absoluto valor abs
fi#ar la instancia de parte )ntera de la onu del numero real de
flotar convierte .<9 entero es verdadera .<9
*6imo mcd Com5n denominador
min )l *s /eque3o de la .<9 Grupo
ma6 el alcalde de la .<9 Grupo
sqrt $a -az cuadrada
e6pt e6ponente
e6p /otencia de correos, base 4e $os logaritmos <aturales
log logaritmo natuar
cvunit conversor de unidades
2igamos porciones del 2) de Como 9san )2"A2 Gunciones1
.<9 "iene $isp *.4. /articular de e6presar $as .peraciones *atemticas
, 2egun "engo entendido s deriva de la notacin polaca inversa, no es ;gual /ero s le
aseme#a1
las .peraciones s )scriben poniendo de como prefi#o el .perador
2umar )!)*/$. porcin prrafo & S ' pondremos
S 2uma
7& S ': devuelve ?, 2upuesto /or
7S ( ?,@ T&: da K,@, ba3o distraction este Caso es Contacto $a 2uma de 4os numeros
/ositivos mas negativo de la .<9
$es comento algoritmo, no ,ace Galta )2C-;M;- 9< /rograma prr verificar )2".,
tan solo /ongan en $a $nea de Comandos de Acad la .peracin tal de como la que
arriba de /uesto, parentesis abren, el signo mas, el &, el ', Cierran parentesis y dan
introduccin entrar y podran ver el -esultado en la linea de comando1
".4A2 R A2; prr $as .peraciones
T -esta
7T A K:
7T L ( O1?:
*ultiplica
7C @ K:
7C & T' %1?:
4ivisin
7J %& @:
7J %% @:, divisin 8ue fi#ense aire pasa )2"A, y here vale lea pena ,ablar 2obre
)nteros int y reales1
%% y @ hi#o dos )nteros y porcin del tanto lo daran de Como -esultado $a /arte )ntera
de la divisin 8ue 2era %
ahora si tan solo /onen el divisor de bienes como, el -esultado sueros sin verdadera
7J %% @1O:
e6presada 8ue 4ecir basta /ara 8u mar <5mero .<9 debe verdadera "ener do a
instancia de parte decimal, aunque sean O
@ es enterovirus .<9
@1O es reales .<9
/resten A")<C;U< A )2") ")*A, RA 89) )2 *.";0. 4) )--.-)2 89) 2.< CA2;
;*/.2;M$)2 A0)C)2 4) 4)")C"A-1
bueno /or Ahora los de#o, /ero los antes les de#o 9na $eccin Completa,
lamentablemente no est en ingls, /ero es lo Vnico 8ue "engo a mano
Cita
4efiniciones de funcin
TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT TTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
% T *atemticas
TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT TTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
S 11111 Adds
7S & ': devuelve ?
7S ( ?,@ T&: devuelve K,@
4espus 7setq un &O b A:
7S Ab: devuelve &A
TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT TTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
T 11111 -esta
7T A K: devuelve &
7T L ( O,?: devuelve ',?
4espus 7setq un &O b A:
7T Ab: devuelve %%
7T ba: devuelve T%%
7T A: devuelve T&O1 Cuando se suministra slo un argumento, su valor se resta de O, la se3al de
conmutacin de cualquier n5mero1
TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT TTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
C 11111 *ultiplica
7C @ K: devuelve (&
7C & T' %1?: devuelve TA,O
4espus 7setq un ' b (1?:
7C Ab: devuelve %',?
7C Aa: devuelve A
TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT TTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
J 11111 4ivide
7J %& @: devuelve &
7J %% @: devuelve % 74ivisin usando slo n5meros enteros ignora cualquier resto1 Cuidado con los =divisin
entera1=:
7J %% @1O: devuelve %,L'''''
7J %& ' &: devuelve &
7J %& T&,O: devuelve T@1O
TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT TTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
rem 11111 4evuelve un resto resultante de la divisin
7%O rem ': devuelve %
7%O rem ?: devuelve O
7-em @,& %,&: devuelve O,&
TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT TTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
% S 11111 ;ncrementos de %
7% S %@: devuelve %K
4espus 7setq un &%:
7% S a: devuelve &&1 9sado con setq, esto sirve como un contador de bucle de iteracin1 /or e#emplo, 7setq
c 7% S C::1
7% S T(: devuelve T'
TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT TTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
% T 11111 4isminuye por %
7% T %@: devuelve %?
4espus 7setq un TL:
7% T a: devuelve TA
TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT TTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
abs 11111 4evuelve el absoluto de un n5mero
7Abs K,O: devuelve K,O
7Abs T@: devuelve @
TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT TTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
fi#ar 11111 4escarta parte fraccionaria de un n5mero y devuelve un entero
7Gi6 K1 %: devuelve K
7Gi#ar K,A: devuelve K
7Gi#ar T(,@: devuelve T(
TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT TTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
float 11111 Convierte un n5mero a un n5mero real 7n5mero de punto flotante decimal:
7Gloat ?: devuelve ?,O
7Gloat ?1L&: devuelve ?,L&
TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT TTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
mcd 11111 4evuelve el mayor factor 7divisor:, com5n a dos o ms enteros1 $os argumentos deben ser enteros
positivos1
7*cd &% 'A: devuelve '
7*cd %O& %'L: devuelve @
7*cd 'O (? @O: devuelve %?
AutodesW dice que esta funcin devuelve el =m6imo com5n denominador= 7una frase sin sentido:1 )s me#or
pensar en l como =m6imo com5n divisor=1
TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT TTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
min 11111 4evuelve el ms peque3o 7el ms ba#o: de dos o ms n5meros
7*in L ' %%,LL %( @: devuelve ',O
7*in %' T&L & @@: devuelve T&L
TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT TTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
ma6 11111 4evuelve el mayor de dos o ms n5meros
7*a6 L ' %%,LL %( @: devuelve %(,O
7*a6 T&& T& %@: devuelve %@
TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT TTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
sqrt 11111 4evuelve la raz cuadrada de un n5mero como una verdadera
72qrt %@: devuelve (,O
72qrt &,O: devuelve %,(%(&%(
TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT TTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
e6pt 11111 )leva un n5mero dado para una potencia dada
7)6pt ' (: devuelve L%
7)6pt &1O ?1O: devuelve '&
7)6pt ' T&: devuelve O 7e6ponentes negativos aplicados a los n5meros enteros pueden aparecer para dar
resultados incorrectos, debido a la divisin entera:
7)6pt ',O T&,O: devuelve O,%%%%%%
7)6pt &?@ O,&?: devuelve (,O
4espus 7setq un &,&? b O,?:
7)6pt ab: devuelve %,?
TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT TTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
e6p 11111 4evuelve e elevado a una potencia dada
7)6p %1O: devuelve &1K%L&L
7)6p &,%(: devuelve L1(AA((
7)6p O1(: devuelve %1(A%L&
7T&,O )6p: devuelve O,%'?''?
)l n5mero de )uler, e, es la base de los logaritmos naturales, y es apro6imadamente igual a &,K%L&L1 2e
utiliza para simplificar ciertas frmulas de clculo1 Comparar ingrese a continuacin1
TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT TTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
iniciar 11111 4evuelve el logaritmo natural 7base e: de un n5mero1 Comparacin e6p anteriormente1
7$og ': devuelve %1OAL@%
7$og %1L&: devuelve O,?ALL'K
7$og O1&?: devuelve T%1'L@&A
TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT TTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
cvunit 11111 Convierte un valor o una lista de valores, de una unidad a otra1 )l primer argumento es el
n5mero a convertir, el segundo argumento es la unidad desde la que se va a convertir, el tercer argumento
es la unidad a la que est convirtiendo1
7Cvunit %O =pulgadas= =mm=: devuelve &?(1O
7Cvunit %OO =mm= =pulgadas=: devuelve '1A'KO%
7Cvunit &? =libras= =Wg=: devuelve %%1''AL
7Cvunit 7lista @ ? &(: =pulgadas= =pies=: devuelve 7O,? O1(%@@@K &1O:
4espus 7setq un % b &:
7Cvunit una =pulgada= =mm=: devuelve &?,(
7Cvunit 7list 7eval a: 7eval b:: =pulgadas= =mm=: devuelve 7&?1( ?O1L:
$os nombres de las unidades para el segundo y tercer argumentos deben escribirse tal y como aparecen en
el archivo ACA419<"1 $a funcin cvunit depende de los valores en ACA419<"1 /or lo tanto, para la mayora
de las conversiones, se prefiere la simple multiplicacin o divisin por el factor apropiado dentro de la
e6presin Auto$;2/ sobre la dependencia de un archivo e6terno1
;*** --------------------------------------------------
;;; https://portafoliolisp.wordpress.com/
;;; PortafolioLisp@gmail.com
;;; Septiembre 2012
;*** --------------------------------------------------
;; m!porta: "ib#$a P#!tos % coorde!adas e! &odel Space
'def#! c:p#!toi'(
'set) archi*o 'getfiled +Seleccio!a #! archi*o de p#!tos+ ++
+t,t+ -((
'set) arch 'ope! archi*o +r+((
'set) li!e .(
'while li!e
'set) , 'read-li!e arch((
'set) % 'read-li!e arch((
'set) pt 'list 'atof ,( 'atof %(((
'comma!d +poi!t+ pt ++(
'set) pt2 'list '/ 'atof ,( 0( 'atof %( ((
'comma!d +te,t+ pt2 1 ++ 'strcat +,1+ , +
%1+ %( ++(
(
'close arch(
(
; 2,porta: 2scribe coorde!adas de p#!tos e! #! archi*o .3.
'def#! c:p#!toe'(
'set) co!$#!to 'ssget 4''0 . +P56.+((((
'set) largo 'ssle!gth co!$#!to((
'set) archi*o 'getfiled +Seleccio!a #! archi*o !#e*o+ ++ +t,t+
1((
'set) arch 'ope! archi*o +w+((
'set) 7 0(
'repeat largo
'set) cod 'ss!ame co!$#!to 7((
'set) lista 'e!tget cod((
'set) pt 'cdr 'assoc 10 lista(((
'set) , '!th 0 pt((
'set) % '!th 1 pt((
'set) , 'rtos , 2 0((
'set) % 'rtos % 2 0((
'write-li!e , arch(
'write-li!e % arch(
'set) 7 '/ 7 1((
(
'close arch(
(
EJEMEPLO PTS
0-1818
829101:
0-:08-
82980;2
0-022-
8298100
0-1;9;
8298100
RETICULA EN AUTOLISP
A continuacin se muestra el cdigo fuente para la creacin de una retcula para un plano
topogrfico !a sea de lneas o cruces" #asado en $ puntos capturados por el usuario"
distancia entre cotas" altura del te%to ! tama&o de cruces en caso de elegir 'sta opcin(
)Arc*i+o, RETICULA(LSP
)-uncion, RET
).escripcion, .i#u/a en pantalla una cuadricula !a sea con lineas o cruces
) de las coordenadas cerradas capturando para ello $ puntos"
) distancia entre cotas" altura de te%to ! tama&o de cruces en
) caso de elegir esa opcin(
)Autor, Carlos Al#erto -a0 Alcal
)-ec*a, -e#rero de $112
3defun c,ret 34
3set5 ocmd 3get+ar 6cmdec*o64
o#lp 3get+ar 6#lipmode64
oosm 3get+ar 6osmode64
4
3set+ar 6cmdec*o6 14
3set+ar 6#lipmode6 14
3command 67LA8ER6 67m6 6RETICULA6 67c6 626 66 664
3initget 94
3set5 p9 3getpoint 69ra( Es5uina,644
3terpri4
3initget 94
3set5 p$ 3getcorner p9 6$da( Es5uina,644
3terpri4
3initget 3: $ ;44
3set5 anc*o 3getint 6.istancia entre cotas <911=, 644
3terpri4
3if 3> anc*o nil4
3set5 anc*o 9114
4
3initget 3: $ ;44
3set5 *t 3getreal 6Altura del te%to <$(?=, 644
3terpri4
3if 3> *t nil4
3set5 *t $(?4
4
3set5 %min 3min 3car
p94 3car p$444
3set5 !min 3min 3cadr p94 3cadr p$444
3set5 %ma% 3ma% 3car p94 3car p$444
3set5 !ma% 3ma% 3cadr p94 3cadr p$444
3if 3< %min 14
3set5 i%9 3@ 3fi% 3A %min anc*o44 anc*o44
3set5 i%9 3: 3@ 3fi% 3A %min anc*o44 anc*o4 anc*o44
4
3if 3< %ma% 14
3set5 i%$ 3B 3@ 3fi% 3A %ma% anc*o44 anc*o4 anc*o44
3set5 i%$ 3@ 3fi% 3A %ma% anc*o44 anc*o44
4
3if 3< !min 14
3set5 i!9 3@ 3fi% 3A !min anc*o44 anc*o44
3set5 i!9 3: 3@ 3fi% 3A !min anc*o44 anc*o4 anc*o44
4
3if 3< !ma% 14
3set5 i!$ 3B 3@ 3fi% 3A !ma% anc*o44 anc*o4 anc*o44
3set5 i!$ 3@ 3fi% 3A !ma% anc*o44 anc*o44
4
3initget 6Cru0 Linea64
3set5 op 3getCDord 6Esco/a tipo de cuadricula ECru0ALineaF <C=, 644
3if 3or 3> op 6Cru064 3> op Gn44
3cru04
3linea4
4
3command 67pline6 p9 3list 3car p94 3cadr p$44 p$ 3list 3car p$4 3cadr p944 67c64
3command 67st!le6 66 66 *t 66 66 66 66 664
3if 3> %min 3B i%9 anc*o44
3set5 i%9 %min4
4
3if 3> %ma% 3: i%$ anc*o44
3set5 i%$ %ma%4
4
3if 3> !min 3B i!9 anc*o44
3set5 i!9 !min4
4
3if 3> !ma% 3: i!$ anc*o44
3set5 i!$ !ma%4
4
3set5 i% i%94
3D*ile 3<> i% i%$4
3set5 te% 3strcat 6H>6 3ponercomas i%444
3command 67te%t6 67mr6 3list i% 3B
!min ?(144 IJ1(1 te%4
3command 67c*ange6 67l6 66 67P6 67C6 6$6 664
3set5 i% 3: i% anc*o44
4
3set5 i! i!94
3D*ile 3<> i! i!$4
3set5 te% 3strcat 68>6 3ponercomas i!444
3command 67te%t6 67mr6 3list 3B %min ?(14 i!4 I1(1 te%4
3command 67c*ange6 67l6 66 67P6 67C6 6$6 664
3set5 i! 3: i! anc*o44
4
3set+ar 6cmdec*o6 ocmd4
3set+ar 6#lipmode6 o#lp4
3set+ar 6osmode6 oosm4
3princ4
4
3defun cru0 34
3initget 3: $ ;44
3set5 tc 3getreal 6Tama&o de cru0 <?=, 644
3terpri4
3if 3> tc nil4
3set5 tc ?(14
4
3set5 tc 3A tc $44
3set+ar 6osmode6 14
3if 3> %min 3B i%9 anc*o44
3set5 i%9 %min4
4
3if 3> %ma% 3: i%$ anc*o44
3set5 i%$ %ma%4
4
3if 3> !min 3B i!9 anc*o44
3set5 i!9 !min4
4
3if 3> !ma% 3: i!$ anc*o44
3set5 i!$ !ma%4
4
3set5 i% i%94
3D*ile 3<> i% i%$4
3set5 i! i!94
3D*ile 3<> i! i!$4
3set5 %9 3B i% tc4
%$ 3: i% tc4
!9 3: i! tc4
!$ 3B i! tc4
4
3if 3< %9 %min4
3set5 %9 %min4
4
3if 3= %$ %ma%4
3set5 %$ %ma%4
4
3if 3= !9 !ma%4
3set5 !9 !ma%4
4
3if 3< !$ !min4
3set5 !$ !min4
4
SERKICIOS INTELRALES EN COMPUTACION
SINCON
MANUAL .E AUTOLISP
PREPARA.O POR, INL( LUSTAKO NAKAS
DDD(sincoDs(com adminOsincoDs(com ISLA -ERNAN.INA N;$B?$ 3CIU.A.ELA
PIPIPAPA4" TELEA-AH, $J$1B2J1" $;Q9BQ?R SUITOBECUA.OR
DDD(sincoDs(com
adminOsincoDs(com
Ser+icios Integrales en Computacin
SINCON
MANUAL .E AutoLISP Reali0ado por, INL(LUSTAKO NAKAS R( I( INTRO.UCCITN
.entro del AutoCA. nos encontramos un lengua/e de programacin 5ue usa un interprete
de nom#re AutoLISP" este es una forma comUn del lengua/e LISP" el cual a su +e0 es el
lengua/e ms antiguo en aplicaciones de inteligencia artificial( El AutoLISP coe%iste con el
AutoCA. ! puede ser usado en cual5uier momento 5ue se este editando un di#u/o( Este
lengua/e pro+ee *erramientas comunes a otros pa5uetes de programacin para
estructurar el flu/o de un programa" manipula datos del AutoCA." as como datos propios"
tiene opciones de entrada ! salida IAO para la creacin ! lectura de arc*i+os ASCII(
Presenta adems la capacidad de poder acti+ar cual5uier comando 5ue +enga dentro del
AutoCA. as como tam#i'n puede manipular informaciones propias de un di#u/o
reali0ado en AutoCA." tal es el caso de mane/ar entidades 3Lneas" arcos" crculos" poliB
lneas" etc(4" as como tam#i'n tipos de lneas" estilos 6st!les6" ni+eles 6La!ers6" etc( El
lengua/e LISP original tena la posi#ilidad de definir funciones en forma recursi+a" esto
significa 5ue la funcin era usada al interior de si misma asignndole las +aria#les de
entrada" esta
capacidad presenta tam#i'n el AutoLISP( Mas lamenta#lemente no *a! informacin so#re
el uso del AutoLISP con funciones recursi+as" pero cual5uier li#ro 5ue *aga referencia a
la recursi+idad en el lengua/e LISP puede ser de a!uda para el estudio de funciones
recursi+as dentro del AutoLISP" pues con algunos cam#ios los programas en LISP podrn
ser e/ecutados al interior del AutoLISP" en particular la +ersin de HLISP es la ms
recomendada pues es la 5ue presenta el ma!or parecido con el AutoLISP( Los par'ntesis
son +itales para escri#ir cual5uier instruccin en AutoLISP" sea esta una simple e%presin
o sea un programa completo" digamos adems 5ue el a#rir ! cerrar par'ntesis permiten al
AutoCA. distinguir entre los comandos propios del pa5uete ! las e%presiones del
AutoLISP( Cada +e0 5ue el AutoCA. detecta un par'ntesis a#ierto" interpreta 5ue se
refiere a una e%presin de AutoLISP ! esta pasa en su totalidad" *asta el par'ntesis 5ue
la cierra" a ser e+aluada por el AutoLISP" el cual da un resultado al AutoCA. 5ue puede
usarlo ! continuar con sus operaciones propias( Toda e%presin dentro del AutoLISP
presenta el siguiente formato, 3Nom#reBdeBlaBfuncin argumentoB9 argumentoB$ ((((((4 El
nom#re de la funcin" 5ue puede ser propio del AutoLISP o creado por el usuario"
relaciona a los argumentos 5ue +ienen a continuacin( Los argumentos a su +e0 pueden
ser otras funciones" +aria#les o constantes( Keamos por e/emplo la siguiente e%presin
dada en AutoLISP, 3@ Q $4 E%presin AutoLISP Resultado 3: ? Q4 2 3: $ ; ?4 99 3A ? Q4 9
3A ?(1 Q4 9(RRRV 3B 9? Q 24 ; 3: 3@ $ Q4 9 3B ; V44 ; E%presiones aritm'ticas en AutoLISP ! su
resultado(
La e%presin anterior se podr tipiar en cual5uier momento" como !a se di/o
anteriormente" ! corresponder a la operacin de multiplicacin de los argumentos 5ue
+engan a continuacin en este caso los +alores constantes de Q ! $" el AutoLISP e+aluar
esa e%presin dando un +alor de R( En la ta#la No( 9 se puede apreciar algunas
e%presiones aritm'ticas en AutoLISP ! el resultado 5ue dara el programa( Para ma!or
informacin so#re las e%presiones aritm'ticas +'ase pg R( II( SETEA.O INICIAL Antes
de correr cual5uier programa de AutoLISP" es indispensa#le setear cierto tipo de
informacin dentro del .OS( En primer lugar setearemos las +aria#les LISPWEAP !
LISPSTACX" lo cual se *ar desde el .OS de la siguiente manera, SET
LISPWEAP>$1111 SET LISPSTACX>2111 Los +alores de $1111 ! 2111 pueden ser
cam#iados" pero las sumas de estas dos cantidades no puede e%ceder de ;?111( Otra
+aria#le 5ue re5uiere ser seteada antes de tra#a/ar con el AutoCA. es ACA.-REERAM"
la cual permite setear ma!or cantidad de memoria RAM li#re para uso del AutoCA.( Se
tipiar en pantalla lo siguiente, SET ACA.-REERAM>$1 El +alor de $1 tam#i'n puede
ser alterado de acuerdo a las necesidades del usuario" pero no se recomiendan +alores
ma!ores a Q$" ni menores a $1( Si el +alor de esta +aria#le no es seteado el AutoCA. le
asignar un +alor de 9;( III( KARIAYLES
$ Isla -ernandina N;$B?$ 3Ciudadela Pipi/apa4 Tel'fonoAfa%, J$1B2J1" ;Q9BQ?R
En el inicio del AutoLISP" 'ste no fue llamado con este nom#re ! fue ms #ien llamado
6+aria#les ! e%presiones6 6+aria#les and e%pressions6 para la construccin de macros(
E%isten unas +aria#les propias del sistema 5ue podrn ser manipuladas a tra+'s del
comando SETKAR( Una +aria#le en AutoLISP representa cual5uier cosa 5ue no sea un
+alor constante( Se usan +aria#les de todo tipo( El AutoLISP permite sustituir +aria#les en
lugar de +alores constantes" es posi#le asignar un +alor al nom#re de una +aria#le( Es
posi#le unir la informacin del nom#re de una +aria#le e%plcitamente en un macro" es
posi#le adems usar el nom#re de las +aria#les con e%presiones para desarrollar clculos
!Ao tomar decisiones lgicas( El nom#re de una +aria#le es una coleccin de letras !
nUmeros" siempre ! cuando el primer carcter sea una letra( En la ta#la II se pueden
apreciar nom#res de +aria#les apropiadas ! nom#res de +aria#les incorrectas(
Nom#res de +aria#les Correctas Incorrectas f QV esta ;?t punto99 r!@; 5ue$Qs %Z etc ft:ui
[\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
\\\\\\\\] CARACTERES NO RECOMEN.A.OS PARA NOMYRES .E KARIAYLES
CARACTERES RESERKA.OS O ILELALES, ( I 6 ) 3 4 -UNCIONES .EL AUTOLISP, ^ @
> = < : B A CARACTERES NO RECOMEN.A.OS, _ ` a G b o cual5uier carcter Control
c\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
\\\\\\\d
El +alor 5ue se asigna a una +aria#le puede ser
de cuatro tipos, Karia#le string, Tiene +alores de te%to u#icadas ente comillas para
identificar el +alor como un string( Algunas +aria#les del sistema 3Ker comando SETKAR4
son del tipo string" tal es el caso de la +aria#le CELT8PE" 5ue tiene asignado un +alor
6Y8LA8ER6 entre otras( Enteras, Son nUmeros positi+os o negati+os los cuales no tienen
fracciones o puntos decimales( El +alor de ? sera un tpico e/emplo de un +alor entero
mientras 5ue el +alor ?(1 ser considerado por el AutoLISP como un +alor real ! no como
un +alor entero( Los +alores enteros de#ern estar entre BQ$VR2 ! :Q$VRV( Para +alores
enteros fuera de estos rangos causar +alores errneos( Algunas +aria#les del sistema
toman +alores enteros" tal es el caso de la +aria#le YLIPMO.E 5ue puede tomar +alores
de 1 para desacti+ado ! 9 para acti+ado( Reales, Es un nUmero 5ue inclu!e decimales de
punto flotante( Si se desea escri#ir el +alor de 1(9Q; no se lo podr escri#ir como (9Q;"
pues esto producir un error" por lo 5ue tendremos 5ue escri#irlo con el 1 inicial( Algunas
+aria#les del sistema tienen asignados +alores reales( .emos algunos e/emplo de este
tipo de +aria#les, -ILLETRA." TEHTSIeE" AREA" etc( Listas, Es una +aria#le 5ue
contiene ms de un +alor o una serie de +alores( Los puntos o coordenadas son un tipo
de listas 5ue estn constituidos por dos 3$.4 o tres 3Q.4 elementos num'ricos ! 5ue
representan una coordenada( En las +aria#les del sistema de nom#re LASTPOINT"
LIMMIN" LIMMAH" etc tienen asignado +aria#les del tipo coordenada(
PicCset, Una ta#la 5ue contiene puntos de elementos grficos" del set de seleccin
creados con cual5uier opcin de seleccin de o#/etos en AutoCA." por e/emplo, DindoD"
crossing" etc( Ename 3Nom#re de una entidad4, Este es un tipo de +aria#le 5ue representa
al nom#re de una entidad( A partir de ella se podr generar una lista donde este
comprendida toda la informacin respecto a la entidad" +er comando ENTLET pgina 9$(
ATOMLIST Se recomienda no usar nom#res de funciones del AutoLISP" como nom#res
de +aria#les( El ATOMLIST es una +aria#le en el AutoLISP 5ue guarda todos los nom#res
de funciones definidas ! nom#res de +aria#les( Se puede mirar esta lista tipiado lo
siguiente, _atomlist Apareciendo entonces en pantalla lo 5ue se ilustra en la ;,
Q Isla -ernandina N;$B?$ 3Ciudadela Pipi/apa4 Tel'fonoAfa%, J$1B2J1" ;Q9BQ?R SuitoB
Ecuador
DDD(sincoDs(com
adminOsincoDs(com
Ser+icios Integrales en Computacin
SINCON
Command, _ATOMLIST 3INTERS LRREA. LRTEHT LR.RAN LRCLEAR TYLSEARCW
TYLNEHT ENTUP. ENTMO. ENTSEL ENTLAST ENTNEHT ENT.EL ENTLET
SSMEMY SS.EL SSA.. SSLENLTW SSNAME SSLET ANLTOS RTOS COMMAN.
OSNAP RE.RAN LRAPWSCR TEHTSCR POLAR .ISTANCE ANLLE INITLET
LETXNOR. LETCORNER LETINT LETSTRINL LETORIENT LETANLLE LETREAL
LET.IST LETPOINT MENUCM. PROMPT SETKAR LETKAR TERPRI PRINC PRIN9
PRINT NRITEBLINE REA.BLINE NRITEBCWAR REA.BCWAR CLOSE OPEN STRCASE
ITOA ATO- ATOI CWR ASCII SUYSTR STRCAT STRLEN PAUSE PI MINUSP eEROP
NUMYERP -LOAT -IH SSRT SIN LOL EHPT EHP COS ATAN 9B 9: AYS MAH MIN NOT
OR AN. = => A> > => A> >
-UNCIONES ARITMfTICAS
: Suma nUmeros
Sinta%is, 3: ( ( ( 4
Kalor retornado, Suma de todos los argumentos num'ricos(
B Sustrae n nUmeros
Sinta%is, 3B ( ( ( 4
Kalor retornado, La diferencia entre el primer argumento
! la suma de los restantes argumentos
@ Multiplica nUmeros
Sinta%is, 3@ ( ( ( 4
Kalor retornado, Producto de todos los argumentos
num'ricos(
A .i+ide nUmeros
Sinta%is, 3A ( ( ( 4
Kalor retornado, El cociente del primer argumento
di+idido por el producto de los dems argumentos(
^ .e+uel+e el operador NOT #inario 3complemento de 94 del
argumento
Sinta%is, 3^ 4
Kalor retornado>B(
9: Incrementa un nUmero en uno
Sinta%is, 39: 4
Kalor retornado>9:n
3entero real segUn n sea entero real(4
9B .isminu!e en uno un nUmero(
Sinta%is, 39B 4
Kalor retornado>nB9 3entero real segUn n sea entero
real(4
AYS Con+ierte un nUmero a su +alor a#soluto
Sinta%is, 3AYS 4
Kalor retornado>el +alor a#soluto de n(
ATAN Calcula el arcotangente
Sinta%is, 3ATAN n$4
Kalor retornado>Arcotangente de n9An$(
Kalor en radianes entre A$ ! BA$(
COS Calcula el coseno de un ngulo e%presado en radianes
Sinta%is, 3COS 4
Kalor retornado>El coseno de ang
SIN Calcula el seno de un ngulo e%presado en radianes
Sinta%is, 3SIN 4
Kalor retornado>El seno de ang
EHP Calcula el antilogaritmo neperiano de un numero
Sinta%is,3EHP 4
Kalor
retornado, nUmero real igual a en
EHPT Calcula el resultado de ele+ar un nUmero a una potencia
Sinta%is,3EHPT 4
Kalor retornado, nUmero real o entero
L.C Calcula el m%imo comUn denominador de dos enteros
Sinta%is, 3L.C 4
Kalor retornado>El +alor del m%imo comUn denominador
LOL Calcula el logaritmo neperiano de un nUmero real
Sinta%is, 3LOL 4
Kalor retornado>Un nUmero real(
LOLAN. .e+uel+e el resultado de una 8 lgica 3AN.4 de
una lista de nUmeros enteros a ni+el #inario(
Sinta%is, 3LOLAN. (((4
Kalor retornado, Un nUmero entero(
LOLIOR .e+uel+e el resultado de una O lgica 3OR4 de una
lista de nUmeros enteros a ni+el #inario(
Sinta%is, 3LOLIOR (((4
Kalor retornado, Un nUmero entero
LSW .espla0amientom a ni+el #inario del contenido de un
registro 3defase4 de 3entero4 en un +alor 3entero4(
Si es positi+o se despla0a *acia la i05uierda" si
negati+o" *acia la derec*a(
Kalor retornado, Un nUmero entero(
Sinta%is, 3LSW 4
MAH E%trae el ma!or +alor de una serie de nUmeros
Sinta%is, 3MAH (((4
Kalor retornado>El ma!or +alor encontrado(
MIN E%trae el menor +alor de una serie de nUmeros
Sinta%is, 3MIN (((4
Kalor retornado>El menor +alor encontrado(
MINUSP Comprue#a si un nUmero es menor 5ue 1
Sinta%is, 3MINUSP 4
Kalor retornado>
T si el argumento n es un nUmero ! es negati+o
nil en caso contrario(
REM Calcula el resto de la di+isin entre dos nUmeros
Sinta%is, 3REM 4
Kalor retornado, El resto de di+idir n9 entre n$((
SSRT Calcula la ra0 cuadrada de un nUmero
Sinta%is, 3SSRT 4
Kalor retornado>Un nUmero real" ra0 cuadrada de n
eEROP Comprue#a si un
nUmero es 1
Sinta%is, 3eEROP 4
Kalor retornado,
T si el elemento es 1
nil en caso contrario(
-UNCIONES .E RELACITN
> Comprue#a la igualdad num'rica
Sinta%is, 3> (((4
Kalor retornado,
T si todos los argumentos 3nUmeros o cadenas de
caracteres4 se e+alUan como iguales
num'ricamente
nil en caso contrario
Las cadenas son comparadas en esta funcin ! en las siguientes
en #ase a su +alor num'rico ASCII
A> Comprue#a la desigualdad num'rica
Sinta%is, 3A> 4 (((4
Kalor retornado,
T si todos los argumentos 3nUmeros o cadenas de
caracteres4 no se e+alUan como iguales
num'ricamente
nil en caso contrario
< Comprue#a la relacin gmenor 5ueh entre los argumentos
Sinta%is, 3< (((4
Kalor retornado,
T si cada argumento es num'ricamente menor 5ue
el argumento de su derec*a
nil en caso contrario
= Comprue#a la relacin gma!or 5ueh entre los argumentos
Sinta%is, 3= 4 (((4
Kalor retornado,
T si cada argumento es num'ricamente ma!or 5ue
el argumento de su derec*a
nil en caso contrario
> (((4
Kalor retornado,
T si cada argumento es num'ricamente ma!or
igual 5ue el argumento de su derec*a
nil en caso contrario
AN. Comprue#a los +alores de una serie de e%presiones( 38
lgico4
Sinta%is, 3AN. (((4
Kalor retornado,
T si todos los argumentos se e+alUan con un
+alor no nulo
nil en caso contrario(
OR Comprue#a de i05uierda a derec*a una serie de e%presiones
*asta *allar la primera 5ue se e+alUa con un +alor no
nulo( 3O lgico4
Sinta%is, 3OR (((4
Kalor retornado,
T si alguno de los argumentos se e+alUa con un
+alor no nulo
nil en caso contrario
ES Comprue#a si los
+alores atri#uidos a am#as e%presiones
son id'nticas
Sinta%is, 3ES 4
Kalor retornado,
T si las dos e%presiones estn ligadas a los
mismos datos
nil en caso contrario
ESUAL Comprue#a si dos e%presiones se e+alUan con +alores
iguales
Sinta%is, 3ESUAL margen de error 4
Kalor retornado,
T si las dos e%presiones se e+alUan como la
misma cosa
nil en caso contrario(
Si las dos e%presiones son nUmeros reales se puede incluir un
margen de error
-UNCIONES .E ASILNACITN
SETS Liga el nom#re de sm#olos al +alor de una e%presin
Sinta%is, 3SETS < Sm#olo= < Sm#olo= (((4
Kalor retornado,
El de+uelto por el Ultimo argumento de la funcin(
SETKAR Cam#ia el +alor de +aria#les del sistema(
Sinta%is,
3SETKAR 4
La +aria#le del sistema no podr ser slo de lectura
! el nue+o +alor asignado ser de los 5ue el sistema
pueda aceptar(
Kalor retornado,
El nue+o +alor de la +aria#le del sistema
T8PE E%trae el tipo de dato de un argumento(
Sinta%is, 3T8PE 4
Kalor retornado, El tipo de dato como una cadena en
ma!Usculas
REAL, numero entero
-ILE, descriptor de fic*ero
STR, cadenas
INT, numero entero(
S8M, sm#olos
LIST, listas ! funciones de usuario
SUYR, funciones internas
(((((((
-UNCIONES LRi-ICAS
ANLLE Calcula el ngulo 5ue formara una recta definida por dos
puntos con la direccin positi+a del e/e H del SCP actual
3si los puntos son Q. se pro!ectan so#re el plano de
construccin actual4
Sinta%is, 3 ANLLE 4
Kalor retornado,
Un ngulo en radianes
.ISTANCE Calcula la distancia entre dos puntos
Sinta%is, 3 .ISTANCE 4
Kalor retornado,
Un nUmero real" 5ue es la distancia
en unidades de
di#u/o entre los dos puntos suministrados como
argumentos(
POLAR Computa un punto en relacin a un punto dado(
Sinta%is, 3 POLAR 4
Kalor retornado,
Las coordenadas de un punto situado en el ngulo
gangh ! a una distancia gdish del punto gpth todo
ello con relacin al SCP actual( El ngulo siempre
se refiere al plano de construccin actual(
INTERS Calcula el punto de interseccin entre dos lneas
Sinta%is, 3 INTERS e%tend4
Kalor retornado,
Un punto 5ue indica el punto de interseccin de la
lnea definida por pt9 ! pt$ ! la lnea definida
por ptQ ! pt;" si no se encuentra ningUn punto de
interseccin la funcin retorna un nil
E%tend, Si e%tend se e+alUa como nil" las lneas se
prolongan *asta encontrar el punto de interseccin" en
caso contrario si no se codifica" slo se #usca la
interseccin en la longitud de los segmentos definidos
por los puntos
COMMAN. E/ecuta ordenes Autocad
Sinta%is,
3COMMAN.
Eargumentos +lidosF(((
4
Kalor retornado, nil
OSNAP Aplica a un punto un modo de referencia Autocad
Sinta%is, 3OSNAP 4
Kalor retornado,
Una lista de punto resultante del modo de
referenciar o#/etos 5ue se est' aplicando al
argumento pt
El funcionamiento de esta orden depende del +alor de la
+aria#le del sistema gapertura g ! del punto de +ista Q.
actual(
-UNCIONES .E ENTRA.A INTERACTIKA(
LETPOINT .etiene la e/ecucin del programa para 5ue el usuario
introdu0ca un punto(
Sinta%is, 3LETPOINT pt Emensa/eF4
pt, punto de #ase opcional
mensa/e, cadena opcional 5ue ser presentada en el
rea de ordenesApeticiones de la pantalla" en el
momento de la solicitud del
punto
Kalor retornado,
El punto introducido" como una lista de nUmeros
reales(
LET.IST .etiene la e/ecucin del programa para 5ue el usuario
introdu0ca una distancia
Sinta%is, 3LET.IST pt Emensa/eF4
pt, punto de #ase opcional
mensa/e, cadena opcional 5ue ser presentada en el
rea de ordenesApeticiones de la pantalla" en el
momento de la solicitud de la distancia
Kalor retornado, Un nUmero real
LETANLLE .etiene la e/ecucin del programa para 5ue el usuario
introdu0ca un ngulo(
Sinta%is, 3LETANLLE pt Emensa/eF4
pt, punto de #ase opcional
mensa/e, cadena opcional 5ue ser presentada en el
rea de ordenesApeticiones de la pantalla" en el
momento de la solicitud del ngulo
Kalor retornado, El +alor del ngulo en radianes
LETORIENT .etiene la e/ecucin del programa para 5ue el usuario
introdu0ca un ngulo(
Sinta%is, 3LETORIENT pt Emensa/eF4
pt, punto de #ase opcional
mensa/e, cadena opcional 5ue ser presentada en el
rea de ordenesApeticiones de la pantalla" en el
momento de la solicitud del ngulo
Kalor retornado,
El +alor del ngulo en radianes
La diferencia con LETANLLE radica en 5ue el ngulo 5ue de+uel+e
LETORIENT no se +e afectado por las +aria#les del sistema
Autocad ang#ase ! angdir(
Es Util por tanto para introducir ! guardar informacin angular
a#soluta(
LETCORNER .etiene la e/ecucin del programa para 5ue el usuario
introdu0ca un punto" ! tra0a un rectngulo de g#anda
elsticah en la pantalla a medida 5ue el usuario mue+e el
dispositi+o se&alador
Sinta%is, 3LETCORNER Emensa/eF4
pt, Primera es5uina del rectngulo(
mensa/e, cadena opcional 5ue ser presentada en el
rea de
ordenesApeticiones de la pantalla" en el
momento de la solicitud de la otra es5uina(
Kalor retornado,
El punto introducido por el usuario
LETKAR E%trae un +alor almacenado en una +aria#le del sistema de
AutoCA.
Sinta%is, 3LETKAR 4
Kalor retornado, +alor de la +aria#le del sistema
especificada(
LETINT .etiene la e/ecucin del programa para 5ue el usuario
introdu0ca un nUmero entero(
Sinta%is, 3LETINT Emensa/eF4
mensa/e, cadena opcional 5ue ser presentada en el
rea de ordenesApeticiones de la pantalla" en el
momento de la solicitud del entero
Kalor retornado,
El entero introducido por el usuario
LETREAL .etiene la e/ecucin del programa para 5ue el usuario
introdu0ca un nUmero real
Sinta%is, 3LETREAL Emensa/eF4
mensa/e, cadena opcional 5ue ser presentada en el
rea de ordenesApeticiones de la pantalla" en el
momento de la solicitud del nUmero real
Kalor retornado,
El real introducido por el usuario
LET-ILE. Presenta un cuadro de dialogo de nom#res de arc*i+os !
espera una entrada de usuario(
Sinta%is,
3LET-ILE.
4
parmetros,
+alor entero 5ue controla el comportamiento del
cuadro de dialogo(
3Ker manual4
Kalor retornado,
El nom#re del arc*i+o seleccionado como una cadena
nil si no se selecciona ninguno(
LETSTRINL .etiene la e/ecucin del programa para 5ue el usuario
introdu0ca una cadena de caracteres
Sinta%is, 3LETSTRINL EespacioF Emensa/eF4
Espacio, Si este argumento es distinto de nil"
la cadena introducida puede contener espacios en
#lanco(
mensa/e, cadena opcional 5ue ser presentada en
el rea de ordenesApeticiones de la pantalla" en el
momento de la solicitud de la
cadena
Kalor retornado,
La cadena introducida una cadena +aca 3gh4 si el
usuario puls Enter sin teclear caracteres(
LETXNOR. .etiene la e/ecucin del programa para 5ue el usuario
introdu0ca una cadena de caracteres( Esta funcin
comprue#a la +alide0 de lo introducido #asndose en una
lista de pala#ras +lidas esta#lecidas usando la funcin
INILET
Sinta%is, 3LETXNOR. Emensa/eF4
mensa/e, cadena opcional 5ue ser presentada en
el rea de ordenesApeticiones de la pantalla" en el
momento de la solicitud de la cadena
Kalor retornado,
La cadena introducida una cadena +aca 3gh4 si el
usuario
puls Enter sin teclear caracteres(
INILET Comprue#a la +alide0 de las repuestas para una funcin
gLET(((h 3+er manual Autolisp4
-UNCIONES PARA LESTITN .E LISTAS
CREACITN .E LISTAS
LIST Crea una lista a partir de un nUmero de e%presiones
Sinta%is, 3 LIST (((4
Kalor retornado, Una lista de los argumentos de la
funcin(
APPEN. -unde +arias listas en una
Sinta%is, 3APPEN. (((((((((((4
Kalor retornado, Una lista Unica
CONS A&ade al principio de una lista como primer elemento una
e%presin
Sinta%is, 3CONS 4
Kalor retornado, La nue+a lista
EHTRACCITN .E ELEMENTOS .E UNA LISTA
LENLWT Cuenta los elementos de una lista
Sinta%is, 3LENLWT 4
Kalor retornado, El nUmero entero correspondiente(
CAR E%trae el primer elemento de una lista(
Sinta%is, 3CAR 4
Kalor retornado, El primer elemento de la lista
C.R E%trae una nue+a lista donde estn todos los elemento de
la lista menos el primero(
Sinta%is, 3C.R 4
Kalor retornado, la nue+a lista
CAAR" CA.R " C..R" CA.AR" etc(
Todas las posi#les
oncatenaciones *asta un cuarto ni+el
de las funciones CAR ! CA.R(
LAST E%trae el Ultimo elemento de una lista
Sinta%is, 3LAST 4
Kalor retornado, el Ultimo elemento de la lista(
NTW E%trae un elemento de una lista a partir de especificar
su posicin en ella 3pos4
Sinta%is, 3NTW 4
las posiciones dentro de la lista son numeradas de
i05uierda a derec*a empe0ando por la posicin 1
Kalor retornado,
El elemento encontrado" o nil si no se encontr(
ASSOC Locali0a su#listas en una lista de asociaciones
utili0ando elemento como pala#ra cla+e" ! donde 'ste puede ser cual5uier e%presin
+lida suscepti#le de
aparecer como primer elemento de una de las su#listas
Lista de asociaciones,
33cal+e9 inf943cla+e$ inf$(((43cla+eQ infQ(((4(((4
Sinta%is, 3ASSOC 4
Kalor retornado,
La primera su#lista encontrada( Si la cla+e no
aparece de+uel+e nil
MANIPULACITN .E LISTAS
MEMYER Yusca la primera aparicin de una e%presin en una lista
! de+uel+e el resto de la lista a partir de la e%presin
encontrada(
Sinta%is, 3MEMYER 4
Kalor retornado,
una lista donde el primer elemento es la e%presin
encontrada ! el resto" el resto de la lista *asta el
final( Si no se encuentra la e%presin de+uel+e nil(
REKERSE In+ierte un lista
Sinta%is, 3REKERSE 4
Kalor retornado, La lista con sus miem#ros en orden
in+erso(
LISTP Comprue#a si un argumento es una lista
Sinta%is, 3LISTP 4
Kalor retornado,
T si la e%presin es una lista
nil en caso contrario
SUYST Yusca en una lista un miem#ro especificado ! sustitu!e
cada aparicin de 'ste por otro especificado
Sinta%is,
3SUYST 4
Kalor retornado, La lista modificada(
-OREACW
Procesa uno a uno los elementos de una lista ! e+alUa
cada e%presin para cada uno de los elemento de la lista
Sinta%is, 3-OREACW (((4
+ari +aria#le de memoria a la 5ue -OREACW ligara
secuencialmente los +alores de la lista
suministrada ! 5ue normalmente ser usada en
la e%presin(
Kalor retornado,
El resultado de la Ultima e%presin e+aluada(
-UNCIONES .E CON.ICITN
CON. Lee una serie de listas( E+alUa las e%presiones restantes
encontradas en la primera lista cu!o primer elemento no
se e+alUe como nulo ! pasa por alto las restantes listas
Sinta%is, 3CON. jjj((4
Kalor retornado, El retornado por la Ultima e%presin de
las lista e+aluada( Si no se e+alUa ninguna lista " la
funcin CON. de+uel+e nil
I- E+alUa una e%presin Autolisp #asndose en si una
e%presin de compro#acin inicial se e+alUa como no nula
Sinta%is,
3I-
Ee%presin si test es>nil F
4
Kalor retornado,
El +alor retornado por e%presin e+aluada)
nil en otro caso(
PROLN E+alUa secuencialmente una serie de e%presiones(
Sinta%is, 3PROLN (((4
Kalor retornado, La Ultima e%presin e+aluada
-UNCIONES PARA LESTITN .E CICLOS(
REPEAT E+alUa repetidamente una serie de una mas e%presiones
Autolisp un nUmero determinado de +eces(
Sinta%is, 3REPEAT (((4
n, Entero 5ue indica el nk de repeticiones a
reali0ar(
Kalor retornado,
El resultado de la Ultima e%presin e+aluada
NWILE E+alUa repetidamente una serie de una ms e%presiones
Autolisp #asndose en si una e%presin de compro#acin
inicial se e+alUa como un +alor nulo no nulo(
Sinta%is, 3NWILE (((4
Test, E%presin de compro#acin" 5ue *ace 5ue
las dems
e%presiones se e+alUen
mientras 'sta se mantenga distinta de
nil(
Kalor retornado, El resultado de la Ultima e%presin
e+aluada
-UNCIONES PARA LESTITN .E -ICWEROS(
LOA. Carga un arc*i+o Autolisp en la memoria ! e+alUa las
e%presiones en el arc*i+o(
Sinta%is, 3LOA. EreserrorF 4
nom#re de fic*ero, cadena de caracteres con en
nom#re" sin e%tensin (lsp" del fic*ero(
Si no se indica ningUn camino se #usca el
fic*ero segUn el camino de acceso a
#i#liotecas Autocad(
3recordar 5ue para o#tener la contra#arra en
una cadena de caracteres es necesario
teclearla dos +eces GG o en su lugar" una +e0
la #arra derec*a A4(
reserror, +alor +uelto por la funcin en el caso de
5ue la carga del fic*ero fracase( Si no se
proporciona este argumento" la funcin
presenta un mensa/e de error AutoLISP
Kalor retornado, El de la Ultima e%presin e+aluada" si
la carga es #uena(
Los fic*eros 5ue se 5uiere sean cargados al iniciarse la sesin del
editor de di#u/o tendrn 5ue estar especificados en el fic*ero
ACA.(LSP 5ue Autocad carga automticamente(
OPEN A#re un arc*i+o de disco para leer o almacenar datos
Sinta%is,
3OPEN 4
cla+e de acceso, cadena de una letra minUscula
6r6, A#re un fic*ero para lectura
6D6, A#re un fic*ero para escritura
6a6, A#re un fic*ero para escri#ir a&adiendo
nue+os datos al final del mismo( sitUa
el puntero al final del fic*ero
a#ierto( Con+iene compro#ar 5ue no
e%iste una marca de CTRL e3cdigo ASCII
decimal $R4 de final de te%to" !a 5ue
en ese caso no es posi#le a&adir datos(
Kalor retornado, El descriptor de fic*ero utili0ado por
las funciones de
EntradaASalida a fic*ero" por
tanto se de#er atri#uir a un sm#olo 5ue permita
referirse a ese descriptor(
CLOSE Cierra un arc*i+o a#ierto
Sinta%is,
3CLOSE 4
Kalor retornado, nulo
-IN.-ILE Locali0a un arc*i+o en la ruta de #Us5ueda de arc*i+os de
Autocad(
Sinta%is, 3-IN.-ILE 4
Kalor retornado, una cadena de caracteres con el nom#re
completo del arc*i+o indicando la ruta de
locali0acin(
-UNCIONES .E LECTURA 8 ESCRITURA
ESCRITURA
PRIN9 Imprime una e%presin AutoLISP en el rea de ordenes la
escri#e en un arc*i+o a#ierto en modo de escritura(
Sinta%is, 3PRIN9 Ee%presin Edescriptor de fic*eroFF4
Kalor retornado, el argumento de la e%presin
PRINC Imprime una e%presin AutoLISP en el rea de ordenes la
escri#e en un arc*i+o( 3La diferencia con PRIN9 es 5ue
PRINC e+alUa los caracteres de control 5ue apare0can en
la e%presin4(
Sinta%is, 3PRINC Ee%presin Edescriptor de fic*eroFF4
Kalor retornado, el argumento de la e%presin
PRINT Imprime un salto de lnea " una e%presin AutoLISP ! un
espacio en el rea de ordenes lo escri#e en un arc*i+o(
Sinta%is, 3PRINT Ee%presin Edescriptor de fic*eroFF4
Kalor retornado, el argumento de la e%presin
PROMPT Presenta una cadena de caracteres en el rea de ordenes(
3E+alUa caracteres de control4
Sinta%is, 3PROMPT 4
Kalor retornado, nulo
NRITEBCWAR Escri#e un solo carcter en el rea de ordenes #ien en
un fic*ero a#ierto(
Sinta%is,
3NRITEBCWAR Edescriptor de fic*eroF4
Kalor retornado, El cdigo ASCII para los caracteres
escritos
NRITEBLINE Escri#e una cadena de caracteres en al rea de ordenes
#ien en un arc*i+o 3e+alUa caracteres de
control(
Sinta%is, 3NRITEBLINE Edescriptor de fic*eroF4
Kalor retornado, La cadena de caracteres(
TERPRI Imprime un salto de lnea en el rea de ordenes(
Sinta%is, 3TERPRI4
Kalor retornado, nulo
LECTURA
REA.BCWAR Lee caracteres procedentes del #ufer del teclado o de un
arc*i+o a#ierto en modo de lectura(
Sinta%is, 3REA.BCWAR Edescriptor de fic*eroF4
Kalor retornado, El cdigo ASCII para el carcter ledo(
REA.BLINE Lee una cadena de caracteres procedentes del #ufer del
teclado o de un arc*i+o a#ierto en modo de lectura(
Sinta%is, 3REA.BLINE Edescriptor de fic*eroF4
Kalor retornado, la cadena leda( Cuando se alcan0a el
final de un arc*i+o de lectura el +alor retornado es nil(
E/emplo,
3SETS A 91 Y gWOLAh4
gWOLAh
3PRIN9 A4
9191
3PRIN9 gGnCASAh4
gGnCASAhgGnCASAh
3PRINC A4
9191
3PRINC gGnCASAh4
gCASAgGnCASAh
3PRINT A4
91 91
3PRINT gGnCASAh4
gGnCASAh gGnCASAh
3PROMPT gGnCASAh4
CASAnil
3NRITEBCWAR A4
91
3NRITEBCWAR RV4
CRV
3NRITEBLINE Y4
WOLA
gWOLAh
3NRITEBLINE gGnCASAh4
CASA
gCASAh
-UNCIONES MONOLlNEA
APPL8 .e+uel+e el resultado de e/ecutar la 6funcin6 tomando
como argumentos los elementos de la 6lista6
Sinta%is, 3 APPL8 4
Kalor retornado, El de+uelto por el argumento de la
funcin
E/emplo,
9(B 3APPL8 I: I3 9 $ Q 44>9 : $ : Q>R
$(B 3APPL8 ISTRCAT I36A6 6Y6 6C64>6AYC6
MAPCAR .e+uel+e el resultado de e/ecutar la 6funcin6 tomando
como argumentos de funcin los elementos sucesi+os de
6lista 96 (((((((((((((6lista n6
Sinta%is, 3 MAPCAR (((( 4
Kalor retornado, una lista con las sucesi+as soluciones(
E/emplo,
9(B 3MAPCAR I: I391 $1 Q1 4 I3; Q $44>39; $Q Q$4
$(B 3MAPCAR IMAH I3$ ;4 I3V B?4 I3B2 $14>32 $14
Q(B 3SETS A 91 Y $1 C Q14
3MAPCAR I9: 3LIST A Y C4>399 $9 Q94
LAMY.A .efine una funcin sin darle un nom#re( El con/unto de
e%presiones se aplica so#re los argumentos
Sinta%is,
3LAMY.A (((4
Kalor retornado, el resultado de la Ultima e+aluacin(
Se suele utili0ar com#inada con APPL8 ! MAPCAR(
E/emplo,
9(B 3APPL8
I3LAMY.A
3 H 8 e 4
3@ H 3B 8 e 4 4
4
I3 ? $1 9; 4
4
Resultado>Q1
$(B 3MAPCAR
I3 LAMY.A
3 H 8 e 4
3@ H 3B 8 e 4 4
4
I3 ? R 4
I3 $1 Q1 4
I39; 1 4
4
Resultado>3 Q1 921 4
-UNCIONES .E CONKERSITN 8 TRANS-ORMACITN
RTOS Con+ierte un nUmero real en una cadena de caracteres
Sinta%is, 3RTOS Emodo EprecisinFF4
numero, nUmero real 3o entero 5ue tomar como real4
modo 3opcional4, entero del 9 al ? 5ue determina el
formato num'rico de la cadena,
9( Unidades cientficas
$( Unidades decimales
Q( Pies ! pulgadas I 3fraccin decimal4
;( Pies ! pulgadas II 3fraccin propia4
?( Unidades fraccionarias
precisin 3opcional4, entero 5ue determina el nUmero de
decimales de precisin en la cadena
Si no se especifican los argumentos modo ! precisin se
asume el esta#lecido por la +aria#les de Autocad LUNITS !
LUPREC
Kalor retornado, Una cadena de caracteres
E/emplo, 3RTOS ?(R $ ;4>= g?(R1116
.ISTO- Con+ierte un cadena en un nUmero real" con un determinado
formato de +isuali0acin(
Sinta%is, 3.ISTO- E modoF4
Cadena, cadena de caracteres 5ue e%presa un +alor
num'rico(
modo 3opcional4, entero del 9 al ? 5ue
indica el formato
num'rico del nUmero real e%presado en la cadena 3El
cdigo se corresponde con el dado en la funcin
anterior4" la funcin de#er ser capa0 de interpretar el
argumento cadena de acuerdo con el modo especificado,
Si no se especifica el argumento modo se asume el
esta#lecido por la +aria#le de Autocad LUNITS
Kalor retornado, Un nUmero real
ANLTOS Con+ierte un nUmero 35ue representa un ngulo en
radianes4 en una cadena de caracteres
Sinta%is, 3ANLTOS Emodo EprecisinFF4
numero, +alor del ngulo en radianes(
modo 3opcional4, entero del 9 al ? 5ue determina el
formato num'rico en la cadena,
1( Lrados se%agesimales(
9( Lrados" minutos ! segundos
$( Lrados centesimales(
Q( Radianes
;( Unidades geod'sicas(
precisin 3opcional4, entero 5ue determina el nUmero de
decimales de precisin en la cadena
Si no se especifican los argumentos modo ! precisin se
asume el esta#lecido por la +aria#les de Autocad LUNITS !
LUPREC
Kalor retornado, Una cadena de caracteres(
ANLTO- Con+ierte una cadena de caracteres en un nUmero real 5ue
representa un ngulo
Sinta%is, 3ANLTO- E modoF4
Cadena, cadena de caracteres 5ue e%presa un +alor
num'rico de ngulo
modo 3opcional4, entero del 9 al ; 5ue indica el formato
num'rico del ngulo e%presado en la cadena 3El cdigo se
corresponde con el dado en la funcin anterior4" la
funcin de#er ser capa0 de interpretar el argumento de
la cadena de acuerdo con el modo especificado,
Si no se especifica el argumento modo se asume el
esta#lecido por la +aria#le de Autocad LUNITS
Kalor retornado, Un +alor correspondiente al num'rico de un
ngulo en radianes(
CKUNIT
Con+ierte un nUmero lista de nUmeros de una unidad de
medida a otra 3Las cadenas 5ue representan unidades de
medida +lidas en esta funcin estn almacenadas en el
fic*ero ACA.(UNT4
Sinta%is, 3CKUNIT 4
cad+ie, cadena de unidad de medida +ie/a(
cadnue, cadena de unidad de medida nue+a(
Kalor retornado, Un nUmero o lista de nUmeros con+ertida a la
unidad de medida nue+a(
TRANS Transforma las coordenadas de un punto de un sistema de
coordenadas a otro(
Sinta%is,
3TRANS
EdespF
4
cod+ie, cdigo 5ue e%presa el sistema de coordenadas en
el cual se e%presa el punto(
codnue, cdigo 5ue e%presa el sistema de coordenadas en
el cual se 5uiere e%presar el punto
1( SCU
9( SCP
$( SCK 3+isuali0acin4
Q( SCK espacio papel
desp , si es distinto de nil" entiende el primer
argumento como un despla0amiento(
Kalor retornado, Una lista de punto con sus coordenadas
transformadas(
REA. E%trae datos de una cadena de caracteres
Sinta%is, 3REA. 4
Kalor retornado, El primer tem de una cadena de caracteres
la primera lista si la cadena contiene listas(
E/emplo,
3REA. g*ola a todosh4 *ola
3REA. g3$1 Q1 ;14h4 3$1 Q1 ;14
ASCII Con+ierte el primer carcter de una cadena de caracteres
a su cdigo ASCII
Sinta%is, 3ASCII 4
Kalor retornado, Un entero 5ue representa el cdigo ASCII
ATO- Con+ierte una cadena de caracteres en un nUmero real
Sinta%is, 3ATO- 4
Kalor retornado, un nUmero real
ATOI Con+ierte una cadena de caracteres en un nUmero entero
Sinta%is, 3ATO- 4
Kalor retornado, un nUmero entero
CWR Con+ierte un nUmero entero 5ue representa un carcter
ASCII en la cadena de un slo carcter
correspondiente
Sinta%is, 3CWR 4
Kalor retornado, una cadena de un slo carcter
ITOA Con+ierte un entero en una cadena de caracteres
Sinta%is, 3ITOA 4
Kalor retornado, una cadena de caracteres
-IH Con+ierte un nUmero real en entero(
Sinta%is, 3-IH 4
Kalor retornado, El nUmero entero 5ue resulta de 5uitar los
decimales al real(
-LOAT Con+ierte un nUmero entero en real(
Sinta%is, 3-LOAT 4
Kalor retornado, un numero real
-UNCIONES .E CONTROL .E PANTALLA(
RE.RAN Redi#u/a la pantalla de presentacin 3 las entidades
especificadas4
Sinta%is, 3RE.RAN 4 3sinta%is simplificada para el redi#u/ado
de la pantalla4
Kalor retornado, nil
LRAPWSCR -uer0a la presentacin de pantalla grfica en sistema de
pantalla Unica(
Sinta%is, 3LRAPWSCR4
Kalor retornado, nulo
TEHTSCR Presenta la pantalla te%to en sistemas de pantalla Unica
Sinta%is, 3TEHTSCR4
Kalor retornado, nulo
TEHTPALE Presenta la pantalla te%to en sistemas de pantalla Unica
! la limpia
Sinta%is, 3TEHTPALE4
Kalor retornado, nulo
KPORTS E%trae los nUmeros de identificacin de las +entanas
grficas
Sinta%is, 3KPORTS4
Kalor retornado, Una lista de su#listas donde los elementos de
cada su#lista son,
9( El nUmero de identificacin de cada +entana grfica(
$( Coordenadas de la es5uina inferior i05uierda
3coordenadas normali0adas4(
Q( Coordenadas de las es5uina superior derec*a((
-UNCIONES PARA MANEPAR CA.ENAS .E TEHTO
REA. E%trae datos de una cadena de caracteres
Sinta%is, 3REA. 4
Kalor retornado, El primer tem de una cadena de caracteres
la primera lista si la cadena contiene listas(
STRCASE Con+ierte los caracteres de una
cadena a minUsculas o
ma!Usculas
Sinta%is, 3STRCASE 4EmodoF4
con+ersin a minUsculas, modo>A nil
con+ersin a ma!Usculas , modo>nil no se presenta(
Kalor retornado, La cadena con+ertida
STRCAT Empalma 3concatena4 dos mas cadenas
Sinta%is, 3STRCAT E6cadena$6F(((((((((((4
Kalor retornado, Una sola cadena empalmada(
STRLEN Cuenta los caracteres de una cadena
Sinta%is, 3STRLEN 4
Kalor retornado, Un nUmero entero
SUYSTR E%trae una porcin de una cadena de caracteres(
Sinta%is, 3SUYSTR E long F4
inicio, nUmero entero 5ue indica la posicin de primer
carcter a e%traer(
long, longitud de la su#cadena a e%traer 3 si no se da
proporciona la su#cadena desde la posicin inicial
*asta el final4
Kalor retornado, La su#cadena e%trada
OTRAS -UNCIONES .E UTILI.A.
EKAL E+alUa e%presiones
Sinta%is,3EKAL 4
Kalor retornado, El +alor retornado por la e%presin e+aluada
En la lnea de ordenes la a#re+iatura es el signo _
SUOTE Procesa una instruccin sin e+aluarla
Sinta%is,3SUOTE 4
Kalor retornado, La e%presin sin e+aluarla
La sinta%is alternati+a es el apstrofo( No puede usarse en el
indicador Command(
NULL Comprue#a si una e%presin se e+alUa como nulo
Sinta%is, 3NULL 4
Kalor retornado,
T si la e%presin e+aluada es nulo
nil en caso contrario(
SUIT -uer0a a la rutina actual a a#andonar el procesamiento(
Sinta%is, 3SUIT4
Kalor retornado,
El mensa/e g5uitAe%it a#orth 3a#andonarAsalir a#ortar4
NUMYERP Comprue#a si la e+aluacin de una funcin es un nUmero
Sinta%is, 3NUMYERP 4
Kalor retornado,
T si la e%presin e+aluada es un numero
nil en caso contrario(

You might also like