Autolisp Clase Didactica

122
INDICE Primeros pasos con AutoLISP......................3 Las variables en AutoLISP........................8 Operaciones matemáticas básicas.................10 Solicitar números al usuario....................13 Crear nuevos comandos de AutoCAD................16 Introducción al entorno de Visual LISP..........17 Cargar los archivos de AutoLISP.................23 Operaciones matemáticas en AutoLISP.............26 Solicitar textos y puntos al usuario............29 Funciones para manejar listas...................30 Ejecutar comandos de AutoCAD....................33 Operaciones de comparación......................35 Operaciones lógicas en AutoLISP.................38 Estructuras condicionales simples...............40 Estructuras condicionales múltiples.............43 Mostrar textos al usuario en AutoLisp...........44 Las variables de sistema de AutoCAD.............47 Funciones de conversión de datos en AutoLISP....49 Obtener distancias y ángulos del usuario........50 El comando deshacer en las rutinas de AutoLISP. .54 Funciones de tratamiento de errores en AutoLISP. 58 Limitar las respuestas de los usuarios..........65 Limitar las respuestas de los usuarios (II).....70 Estructuras repetitivas: Bucles.................74 Estructuras repetitivas: Bucles.................78

description

Introduccion a Autolisp para principiantes, explicacion paso a paso con ejemplos para un mejor entendimiento

Transcript of Autolisp Clase Didactica

INDICE

Primeros pasos con AutoLISP3Las variables en AutoLISP8Operaciones matemticas bsicas10Solicitar nmeros al usuario13Crear nuevos comandos de AutoCAD16Introduccin al entorno de Visual LISP17Cargar los archivos de AutoLISP23Operaciones matemticas en AutoLISP26Solicitar textos y puntos al usuario29Funciones para manejar listas30Ejecutar comandos de AutoCAD33Operaciones de comparacin35Operaciones lgicas en AutoLISP38Estructuras condicionales simples40Estructuras condicionales mltiples43Mostrar textos al usuario en AutoLisp44Las variables de sistema de AutoCAD47Funciones de conversin de datos en AutoLISP49Obtener distancias y ngulos del usuario50El comando deshacer en las rutinas de AutoLISP54Funciones de tratamiento de errores en AutoLISP58Limitar las respuestas de los usuarios65Limitar las respuestas de los usuarios (II)70Estructuras repetitivas: Bucles74Estructuras repetitivas: Bucles78Funciones para manipular cadenas de texto83Trabajar con ngulos y distancias87Funciones avanzadas para manejar listas88Aplicar funciones a los elementos de una lista90Literales y otras funciones de utilidad95Carga automtica de los archivos de AutoLISP98Operaciones con archivos102Leer y escribir archivos de texto104

Introduccin a la programacin en AutoCAD

Primeros pasos con AutoLISP

Objetivos del cursoAprovechando 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 deAutoCAD.Con este curso no se pretende formar a expertos programadores. Ms bien, se pretende acercar el lenguaje de programacinAutoLISP 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, tanslo 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 cmo funciona esa base de datos.

Cdigo de una macro en AutoLISPMerece la pena aprender a programar sobre AutoCADDesde 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, comoSolidWorksoCatia, 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 archivosconvirtindoseen 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 aprendery 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 endepurar 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 denominapseudocdigo. Un mtodo algo ms avanzado y eficaz es utilizardiagramas 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 utilizarEvernoteo cualquier otro sistema que te permita almacenar de informacin o gestionar las macros que has creado.Interfaces de programacinAutoCAD 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: AutoLISPes 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 comandoso cargar programas desde archivos externos. Puedes utilizar AutoLISP para automatizar tareas repetitivas y crear nuevos comandos de AutoCAD ActiveX Automationconstituye 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) VBAes 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 ObjectARXes 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 AutoCADDe momento nos centraremos en la programacin sobre AutoCAD utilizando el intrprete interno de AutoLISP para pasar en breve al entorno de Visual LISP y posteriormente a la programacin en VBA.Caractersticas de AutoLISPElLISPfue desarrollado a finales de los aos 50 porJohn 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 eninteligencia artificial. Su nombre proviene deLIST 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 loslenguajes interpretados, se va traduciendo el programa a cdigo mquina (el idioma de los ordenadores) a medida que se ejecuta en loslenguajes compilados, el cdigo fuente (texto) del programa se traduce a cdigo mquina generando un archivo ejecutable (.EXE) que es el que ejecutar el programaHay 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 deacceder 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 puedeacceder a la informacin de los objetosde AutoCAD para determinar de qu 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 AutoCADpara 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 deprogramas paramtricosy 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 deVisual LISPque 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 utilizanActiveX. Otra de las novedades que aporta Visual LISP son losreactores 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 temporalExpresiones y procedimientos de evaluacinUn programa en AutoLISP consiste en una serie de expresiones del tipo (funcin argumentos).Cada expresin comienza con unparntesis de aperturaal que sigue el nombre de unafuncin de AutoLISP(o una funcin creada por el usuario) y una serie deargumentos(a veces opcionales) que dependen de la funcin indicada y vanseparados por al menos un espacio en blanco. Cada expresin termina con unparntesis 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 argumentos1y2devuelve el resultado3.(+31 22 -3)Ejecuta la funcin+que realiza la suma de los argumentos31,22y-3devuelve el resultado50.Prueba tambin:(-17 2)(+2.5 22.8)(-0.25 22.5)(+12 -2 31 -7.5)Ejemplo:(+(*2 3)2)devuelve8. Recuerda que primero evala la lista interior y devuelve su resultado a la exterior.(+7(/5.0 2)-3)devuelve6.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 intrprete 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 intrprete 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 datosLos 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 AutoLISPEjemplo:(+5 2)devuelve7.(+5 2.0)devuelve7.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 constantePI= 3.14159 para realizar clculos. Por ejemplo, ejecuta de nuevo el comando CIRCULO y cuando pregunte el radio de la circunferencia, teclea(/6(*2PI)). Obtendremos una circunferencia de permetro6.Notacin empleadaPara 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 recomendadasEn 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: ;;; 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, 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 comandoConvenciones utilizadas en el curso El cdigo en AutoLISP se mostrar en negrita y con los siguientes colores: los parntesis de apertura y cierre se mostrarn en rojo( ) las funciones de AutoLISP se mostrarn en azulsetq los nmeros se mostrarn en verde125.6 12 los textos se mostrarn en rosa/nDesigne un punto: los comentarios se mostrarn en prpura;Esto es un comentario las funciones de usuario se mostrarn en maysculas(GAR90.0)

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(*2PI)). Pero que sucede si queremos utilizar el valor obtenido por(/6(*2PI))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 esSETQy 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 nombres 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:(setqa3)Esta expresin crea la variableay le asigna el valor3. Devuelve el valor de la variablea.Que valor crees que devolver(setqb(+1 3)melones23.0)? Fjate que se han definido dos variablesbymelonesde valor4y23.0respectivamente. Comomelonesha 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 trmino 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 devolvernil, que es lo mismo que nada o vaco. Por ejemplo:!adevuelve3.Prueba tambin las siguientes expresiones y comprueba los valores asignados a las variables:(setqc(+b3))Los valores de las variables tambin pueden utilizarse para realizar operaciones y asignar el resultado de dichas operaciones a una variable.(setqd b)Se puede definir una variable igual al valor de otra variable.(setqa3.5)Se puede modificar el valor asociado a una variable, por eso se llama variable.(setqb2.0)Qu sucede con el valor de la variabled? Tomar el nuevo valor asignado a la variablebo seguir con el anterior? Al definir la variabledse le asigno el valor que tena la variableben 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 caracteres de control: \\ representa al smbolo \ \ representa al smbolo \n representa un cambio de lnea (retorno del carro) \t representa una tabulacin(setqa \tBienvenido al Curso Introduccin a la programacin en AutoCAD)En este caso adems, hay que notar que en la variableaprimero 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 variableacontiene una cadena de texto en lugar de un nmero.Existen una serie de smbolos predefinidos: TRepresenta al valor lgico Cierto o Verdadero. nilRepresenta al valor lgico Falso.(setqbT)(setqcnil)En este caso, a la variablease le ha asignado una cadena de texto, a la variablebel valor Cierto o Verdadero y a la variablecel valor Vacoo Falso.Para almacenar el radio de la circunferencia de permetro 6 unidades en una variable podemos teclear:(setqrad(/6(*2PI)))Podramos crear una circunferencia e indicar!rada AutoCAD cuando nos pregunte por el radio deseado.Ejemplo: Por qu las siguientes expresiones estn mal?(setq157 25)(setqrad5Rad4)(setqb 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 valor23.Prueba(+5 2.5)Ahora+no representa a la funcin suma, sino a una variable de valor23. 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 cmo 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)devuelve12(+3.0 9)devuelve12.0(setqa(+3 9 4))devuelve16y lo almacena en la variablea(+3.5 -1)devuelve2.5Prueba ahora la siguiente expresin:(setqa(+a2.5))devuelve18.5Hemos asignado a la variableael resultado de una operacin en la que usamos el anterior valor asignado a la variableacomo uno de los argumentos de la operacin.Si le pasamos a la funcin+un nico nmero como argumento, nos devuelve ese nmero.(+12.5)devuelve12.5(+-7.0)devuelve-7.0Si ejecutamos la funcin suma sin argumentos, devuelve 0.(+)devuelve0La expresin(+.52)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)devuelve2.5(+3 -0.6)devuelve2.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)devuelve6.0(-11 5)devuelve6(setqa(-12 5 4))devuelve3y lo almacena en la variablea(-3.5 -1)devuelve-4.5(setqa(-a2.5))devuelve0.5y lo almacena en la variablea.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)devuelve7.0En 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.(-)devuelve0

(* [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)devuelve27(*3.0 9)devuelve27.0(setqa(*3 9 4))devuelve108y lo almacena en la variablea(*3.5 -1)devuelve-3.5Prueba ahora la siguiente expresin:(setqa(*a 2.5))devuelve270.0Si le pasamos a la funcin*un nico nmero como argumento, nos devuelve ese nmero.(*12.5)devuelve12.5(*-7.0)devuelve-7.0Si ejecutamos la funcin*sin argumentos, devuelve0.(*)devuelve0(/ [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)devuelve3(/11 5.5)devuelve2.0En esta funcin es muy importante recordar que si todos los nmeros de la lista son enteros, el resultado tambin ser entero.(/7 2)devuelve3(/7 2.0)devuelve3.5(setqa(/12.5 4 2))devuelve1.5625y lo almacena en la variablea(/3.5 -1)devuelve-3.5(setqa(/a0.5))devuelve3.125y lo almacena en la variableaSi le pasamos a la funcin/un nico nmero como argumento, nos devuelve ese nmero.(/12.5)devuelve12.5(/-7.0)devuelve-7.0Si ejecutamos la funcin/sin argumentos, devuelve0.(/)devuelve0(1+ )Esta funcin incrementa en una unidad el nmero indicado como argumento.(1+5)devuelve6. Ojo entre 1 y + no debe haber ningn espacio, ya que el nombre de la funcin es 1+.(1+2.5)devuelve3.5(1+0)devuelve1(1+-7)devuelve-6Una aplicacin bastante habitual de esta funcin es la de incrementar ndices o contadores:(setqi1)(setqi(1+i))devuelve2(1- )Esta funcin reduce en una unidad el nmero indicado.(1-5)devuelve4. Ojo entre 1 y - no debe haber ningn espacio, ya que el nombre de la funcin es 1-.(1-2.5)devuelve1.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.(getintCuntos aos tienes?:)Podemos asignar el valor introducido por el usuario a una variable y as utilizarlo despus.(setqedad(getintCuntos aos tienes?:))(setqedad(+edad1))nos dar la edad que tendrs el prximo ao.Tambin puedes crear una variable que contenga el mensaje de solicitud de la funcinGETINT(setqmens Cuntos aos tienes?:)(setqedad(getintmens))En este casomenses 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:(setqa27mens Cuntos aos tienes?:)(setqedad(getintmens))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 variablea, que contiene el valor numrico27, de modo que la variable edad debera tomar el valor27, 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 funcinGETINTse est ejecutando el interprete de LISP, y al indicar!acomo respuesta estamos diciendo que ejecute el interprete de LISP para obtener el valor asociado a la variablea. Como el intrprete 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 intrprete 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.(setqpeso(getrealCuntos kilos pesas?:))(setqpeso(-peso1))nos dar el peso que tendrs si adelgazas un kilo.Tambin puedes crear una variable que contenga el mensaje de solicitud de la funcinGETREAL(setqmens Cuntos kilos pesas?:)(setqpeso(getrealmens))Funciones de usuario y nuevos comandos

Definir funciones de usuarioHemos 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 llamaDEFUN.(DEFUN ( [argumentos] / [variables_locales] ) [expr1] [expr2] )El primer argumento representa el nombre de lafuncinde 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: losargumentosson valores que recibir la funcin cuando sea ejecutada por el usuario, o llamada desde otras funciones lasvariables localesson aquellas variables que se emplearn tan solo dentro de la funcin que queremos definir, de modo que restringimos su uso al entorno de la funcinPor ltimo, se aaden las expresiones que ejecutar la funcin. Veamos algunos ejemplos:(defun2+(valor) (+valor2))En este caso hemos definido una nueva funcin llamada 2+, que recibe como argumento un nmero y realiza la suma de ese nmero y2. 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)devuelve7(2+0)devuelve2(2+-2)devuelve0Defundevuelve el resultado de la ltima expresin ejecutada, que en el caso anterior es(+valor2).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 argumentosPodras pensar que el nmero indicado se almacena en una variable llamada valor, pero no es as. Puedes comprobarlo escribiendo! Valoren la lnea de comandos, lo que nos devolvernil.En la funcin anterior tenemos un argumento y no hay variables locales. La vamos a modificar un poco:(defun2+(valor) (setqvalor(+valor2)))Ahora seguro que estas totalmente convencido de que el resultado obtenido se almacena en la variable valor. Pues comprobemos si tienes razn:(2+5)devuelve7!valordevuelvenilLa funcin 2+ recibe como argumento un nmero, que almacena en la variable valor. Pero elmbito 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 esnil. Vamos con otra prueba(setqvalor5)devuelve5(2+4)devuelve 6Que valor crees que tendr la variable valor? Pensemos un poco. inicialmentevaloreranil al ejecutar(setqvalor5)asignamos a la variablevalorel nmero entero5 cuando llamamos a la funcin 2+ con la expresin(2+4)tenemos que valor es4 dentro de la funcin 2+ asignamos(setqvalor(+valor2))de modo que valor ser6 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 quevalorser5 por tanto, si tecleamos!valordevolver5Pero, que pasa si ejecutamos(setqvalor(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 es6. De modo que valor ser6.Retoquemos un poco ms la funcin 2+(defun2+(valor) (setqinicial valor valor(+valor2)))y borremos el contenido de valor. Para ello simplemente le asignamosnil.(setqvalornil)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:!valordevuelveniltal como suceda en el ejemplo anterior!inicialdevuelve4Observa que valor se comporta como una variable local, solo se emplea dentro de la funcin. Sin embargo inicial es dembito global, es decir se sigue empleando al salir de la funcin. Vamos a modificar un poquito ms nuestra funcin:(defun2+(valor/inicial) (setqinicial valor valor(+valor2)))Ahora hemos aadido la variable inicial a la lista de variables locales, con lo que su mbito ser local. Para comprobarlo!inicialdevuelve4(setqinicialnil)!inicialdevuelvenil(2+3)!inicialdevuelvenilBueno, vamos con la ltima modificacin de la funcin 2+(defun2+(/valor) (setqvalor(getintNmero:)) (setqvalor(+valor2)))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 empleaGETINTpara solicitar un nmero al usuario.Lo habitual es que se trate deevitar 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 AutoCADLa funcin de AutoLISPDEFUNno solo permite crear funciones de usuario, tambin permite crear nuevos comandos de AutoCAD.Siguiendo con el ejemplo anterior(defunC:2+(/valor) (setqvalor(getintNmero:)) (setqvalor(+valor2)))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) (setqinicial valor valor(+valor2)))(C:2+2)devuelve4Si 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 funcin2+en el dibujo actual, de modo que si hay ms dibujos abiertos, en ellos no estar definida.En el siguiente tema veremos cmo guardar nuestras funciones en archivos de texto, a la vez que comenzamos a trabajar con el entorno deVisual LISP.

Introduccin al entorno de Visual LISP

Archivos de cdigo fuente en AutoLISPYa 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 AutoCADDe 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 intrprete 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 AutoCADNosotros seguiremos utilizando la ventana de comandos de AutoCAD para ver cmo 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 usuarioAntes 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:(defunRAG(ang)(/(*ang180.0)pi))Hay tres reglas bsicas que sigue AutoLISP:1. el nmero de parntesis de apertura debe ser igual al nmero de parntesis de cierre2. primero se evalan las listas ms interiores3. toda funcin de AutoLISP devuelve un resultadoEl intrprete de AutoLISP no evala los retornos de carro (Intros), de modo que el cdigo se poda haber escrito todo seguido, en una misma lnea:(defunRAG(ang) (/(*ang180.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 funcindefun.No es necesariotabular el cdigo, pero facilita su lectura y adems nos permite detectar posibles errores con los parntesis (Regla nmero 1).Pies una constante que ya est definida en AutoLISP,piequivale al nmero 3.141592En la primera lnea (defunRAG(ang) definimos la funcinRAG(Radianes A Grados) que recibe un argumento ang (el ngulo en radianes).Veamos cmo funciona la segunda lnea: Por la Regla nmero 2, primero se evaluar la lista interior(*ang180.0)que multiplica el ngulo en radianes ang por180.0y 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 funcindefun, cumpliendo as con la Regla nmero 1.Recordemos la estructura de la funcin de AutoLISP defun:(DEFUN ( [argumentos] / [variables_locales] ) [expresin1] [expresin2] ). En la funcinRAGtenemos un argumento y no se han declarado variables locales (por lo que no es necesario poner el carcter /), adems solo tenemos una expresin(/(*ang180.0)pi). Como se dijo en el tema anterior,defundevuelve el resultado de la ltima expresin, que en nuestro caso resulta ser el ngulo ya convertido a grados decimales.Nuestra funcinRAGse ejecutara as:(RAG1.57)siendo1.57el ngulo en radianes, y devolvera ese ngulo en grados decimales (aproximadamente90).No es necesario poner el nombre de la funcinRAGen 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 cdigoEs 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, porque seguramente no recordaras muy bien cmo 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 comentaPor 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.(defunRAG(ang); Recibe un ngulo en radianes(/(*ang180.0)pi);; Multiplica el ngulo en radianes por 180.0 y lo divide por pi.)El editor de Visual LISPEl 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 LISPMostrar algo similar a la siguiente imagen:

El editor de Visual LISPAl 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 pulsaControl + N).Aparece una nueva ventana, tal como puede verse en la siguiente imagen:

Nueva ventana de cdigo en el editor Visual LISPEs en esta pantalla donde vamos a escribir el cdigo de nuestra rutinaRAG, pero antes un pequeo comentarioEs 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.(defunRAG(ang); Recibe un ngulo en radianes(/(*ang180.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 cmo queda la funcin RAG en el editor:

La funcin RAG en el editor de Visual LISPEn 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 azulsetq los comentarios en morado;Esto es un comentario los parntesis en color rojo(setqa2.0) los nmeros en color verde2.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 negroAdems,las funciones de usuario se destacarn escribindose en maysculasRAG.Este formato de colores se utilizar tambin en los artculos de este curso, tal como se muestra en el cdigo de la funcinRAGanterior.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 radianes1.57)SETWaparecer en negro y no en azul, porque la funcin de AutoLISP esSETQ, 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 funcindefun), 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 funcinRAG, 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 lareconoceramos.As que lo mejor ser guardar el cdigo de la funcinRAGen 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 llamadaGARque reciba como argumento un ngulo en grados decimales y que devuelva ese ngulo en radianes. Esprcticamenteigual 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 funcinGARen un archivo llamado GAR.lsp en el directorio donde tengas tus rutinas.

Cargar los archivos de AutoLISP

Para que la funcinRAGque 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 eleditor de Visual LISP2. En el men desplegable de AutoCAD Herr>AutoLISP>Cargar aplicacin.3. Utilizando la funcin de AutoLISPLOAD.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 teclasCTRL+ALT+E.Al cargar el archivo, aparece la Consola de Visual LISP mostrando un mensaje parecido al siguiente: ; N formularios cargado de #. 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 habra 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: (RAG0) (RAGpi) (RAG(/pi4))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 aplicacionesEste 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:(loadrag)No hace falta indicar la extensin del archivo. Escribiendo as el nombre del archivo solo cargar el archivoRAG.LSPsi est en uno de los directorios de soporte de AutoCAD o en el directorio actual. En caso contrario hay que indicar la ruta completa:(loadc:\rutinas\rag.lsp)Pero si lohiciramosas nos dara un error, ya que AutoCAD no reconoce elcarcter\, de modo que hay que escribirlo de forma algo especial. Para AutoLISP el carcter \ hay que indicarlo de cualquiera de esas 2 formas: \\ o /. Por lo tanto escribiremos:(loadc:\\rutinas\\rag.lsp)o(loadc:/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:(loadrag(setqtest0))En este caso, si no se encuentra el archivoRAG.lspa la variabletestse 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 encontradoEsto es todo, de momento, sobre la carga de archivos de AutoLISP en AutoCAD. Ms adelante veremos otros mtodos para cargar nuestras rutinas.Veamos cmo 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.(defunGAR(ang); Recibe un ngulo en grados decimales(/(*angpi)180.0);; Multiplica el ngulo en grados decimales por Pi y lo divide por 180.0.)Es muy parecida a la funcinRAG, no?Crear un directorio para los archivos de AutoLISPSupongamos 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 AutoCADTambin podemos subir o bajar el nuevo directorio en la lista de directorios de soporte. Esto se hace para definir las prioridades, es decir dnde 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 funciones1+y1-. Ahora vamos con otras funciones de AutoLISP que nos permitirn 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:(abs23.8)devuelve23.8(abs-23.8)tambin devuelve23.8Si el nmero que recibe como argumento es entero, devuelve un nmero entero y si es un nmero real, devuelve un real.(abs-7)devuelve7(abs-7.0)devuelve7.0(abs0)devuelve0(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 estdetrsdel punto decimal.(fix15.8)devuelve15.(fix-15.8)devuelve-15(fix0.99)devuelve0(fix-0.99)devuelve0(REM numero1 numero2 [numero3] )Esta funcin devuelve el resto de la divisin de numero1 entre numero 2.(rem2.5 2)devuelve0.5(rem3 2)devuelve1Cuando se indican ms de 2 nmeros(rem1 2 3)es equivalente a(rem(rem1 2)3). Es decir, primero calcula el resto de la divisin entre1y2, que es1, y despus lo divide entre3y devuelve su resto, que es1.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.(rem3 2.0)devuelve1.0(SIN angulo)Devuelve el seno de un ngulo indicado en radianes.(sin0)devuelve0.0(sin(/pi2))devuelve1.0(COS angulo)Funciona igual que la anterior, pero devuelve el coseno del ngulo, que recibe en radianes.(cos0)devuelve1.0(cospi)devuelve-1.0(ATAN numero 1 [numero2])Devuelve el arco cuya tangente sea numero1. Por ejemplo:(atan0)devuelve0.0ya que el ngulo que tiene tangente0es el0.0Si se indica un segundo nmero(atannum1 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(sinangulo)(cosangulo))devuelveangulo(SQRT numero)Esta funcin devuelve la raz cuadrada del numero que recibe como argumento. Siempre devuelve un nmero real, no entero.(sqrt4)devuelve2.0(sqrt2.0)devuelve1.41(EXPT num exp)Devuelve el nmero num elevado al exponente exp.(expt2 2)devuelve4(expt2 3)devuelve8Si 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.(expt3 2.0)devuelve9.0(EXP num)Devuelve el nmero e (e = 2.71828) elevado al nmero nm. Siempre devuelve un nmero real.(exp1)devuelve2.71828(exp2)devuelve7.38906(LOG numero)Esta funcin devuelve el logaritmo neperiano del nmero que recibe como argumento.(log1)devuelve0.0(log2)devuelve0.693147(GCD entero1 entero2)Esta funcin recibe dos nmeros enteros y devuelve su mximo comn divisor (o denominador). Siempre devuelve un nmero entero.(gcd15 5)devuelve5(gcd9 33)devuelve3(MAX num1 num2 )Devuelve el mayor de los nmeros que recibe como argumentos.(max2 4 1 3 6)devuelve6(max8 4 -9)devuelve8Si 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.(max8 4.0 -9)devuelve8.0(MIN num1 num2 )Devuelve el menor de los nmeros que recibe como argumentos.(min2 3 6)devuelve2(min8 4 -9)devuelve-9Si 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.(min8 4.0 -9)devuelve-9.0Pues ya estn vistas todas las funciones matemticas Enhorabuena!!!Solicitar textos y puntos al usuario

Recuerdas las funcionesGETINTyGETREAL? 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:(getstringCul es tu nombre?)Supongamos que te llamas Pepe, a(getstringCul es tu nombre?)responderasPepe y ya est. Incluso sepodraasignar el nombre que indique el usuario a una variable:(setqnombre(getstringCul 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:(setqnombre(getstringTCul es tu nombre?))Le estamos indicando el argumento [modo] = T. Este argumento puede ser cualquier expresin de AutoLISP, en este caso le pasamos el valorT= 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 devuelvanil, permite espacios.(setqnombre(getstring(+1 2)Cul es tu nombre?))permite responder con espacios, ya que(+ 1 2)devuelve3que es distinto denil.(setqnombre(getstring(setqvar1nil)Cul es tu nombre?))no permite responder con espacios, ya que(setqvar1nil)devuelvenil.Para solicitar puntos se utilizan dos funciones que tambin son parecidas aGETINTy aGETREAL.(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:(getpointPunto inicial)Lo habitual es que adems ese punto se almacene en una variable(setqpto(getpointPunto inicial))As asignamos a la variableptoalgo parecido a lo siguiente:(120.56 135.88 0.0)Veamos ahora para que sirva el argumento opcional[pto_base]aprovechando que tenemos el puntoptodefinido.(getpointpto Siguiente punto:)Aparece una lnea elstica entre el puntoptoy 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:(getpointpto Siguiente punto:)(getcornerpto Siguiente punto:)Al utilizargetpoint, se muestra una lnea elstica entre el puntoptoy la posicin del cursor. Si se utilizagetcorner, en lugar de una lnea elstica, aparece un rectngulo.Fijmonosun momento en lo que devuelven tantogetpointcomogetcorner:(125.68 117.68 0.0). Se trata de una lista, una lista con las coordenadas de un punto. Bien, pues en el prximo artculo veremos algunas funciones para manejar listas.Funciones para manejar listas

AutoLISP es un lenguaje de programacinbasado en listasas 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 labase 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 variableptohemos asignado el valor devuelto porgetpoint, tenemos una lista con las coordenadas X, Y y Z del punto designado. Supongamos quepto=(10.0 20.0 0.0).(carpto)devuelve la coordenada X del puntopto. Es decir10.0(CDR lista)Esta funcin devuelve la lista que recibe como argumento pero sin el primer elemento.(cdrpto)devolver una lista formada por las coordenadas Y y Z del puntopto. Es decir,(20.0 0.0)(CADR lista)Basndonosen 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 puntopto? Veamos: CDRdevuelve la lista sin el primer elemento CARdevuelve el primer elemento de una listaDe modo que(cdrpto)devuelve (Y Z). As que para obtener la coordenada Y podemos escribir:(car(cdrpto))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 (cdrpto)devuelve (Y Z) (cdr(cdrpto))devuelve (Z)Podras pensar que escribiendo(cdr(cdrpto))obtenemos la coordenada Z, sin embargo no es as. La expresin(cdr(cdrpto))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(cdrpto)))devuelve la coordenada Z del punto pto.En resumen, las coordenadas del punto pto se obtendran mediante: X ==>(carpto) Y ==>(car(cdrpto)) Z ==>(car(cdr(cdrpto)))Otras funciones combinandoCAR y CDRSi en las expresiones indicadas anteriormente para obtener las coordenadas X, Y y Z ponemos las letras A y D decArycDren maysculas, lo anterior quedara: X ==>(cArpto) Y ==>(cAr(cDrpto)) Z ==>(cAr(cDr(cDrpto)))Este ejemplo es simplemente para introducir una simple regla demnemotecniaya quelas funciones CAR y CDR se pueden agrupar. Para ello, existen una serie de funciones que se denominan juntando las Aes y las Des decArycDrrespectivamente. El ejemplo anterior, queda: X ==>(cArpto) Y ==>(cAr(cDrpto))==(cADrpto) Z ==>(cAr(cDr(cDrpto)))==(cADDrpto)Esto nos servir como regla para recordar el nombre de estas funciones. Debes recordar tambin que tan solo se permiten 4 niveles de amidacin, 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 variablelst=((a b) (c d) (e f)). OJO!! es una lista en la que sus elementos son a su vez listas.Puedes definir la variablelstescribiendo:(setqlst(list(lista b)(listc d)(liste f)))Cmo obtendramosa?? (carlst)devuelve(a b)que es el primer elemento delst, yaes el primer elemento de(a b)as que: (car(carlst))devuelvea, o lo que es lo mismo:(cAArlst)devuelveay el elemento c? (cDrlst)devuelve la lista sin el primer elemento, es decir((c d) (e f)). Ahora si hacemos(cAr(cDrlst))devuelve el primer elemento de la lista anterior, es decir(c d). As que(cAr(cAr(cDrlst)))devuelvec, o lo que es lo mismo:(cAADrlst)devuelvecCmo obtenerd? (cDrlst)devuelve((c d) (e f)) (cAr(cDrlst))devuelve el primer elemento de((c d) (e f)), es decir devuelve(c d) Si ahora hacemos(cDr(cAr(cDrlst)))obtenemos(d), que no es lo mismo qued. Ya que se trata de una lista cuyo primer elemento esd. As que(cAr(cDr(cAr(cDrlst))))devuelved, o lo que es lo mismo:(cADADrlst)devuelvedY cmo obtener e ? (cDrlst)devuelve((c d) (e f)) y(cDr(cDrlst))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(cDrlst)))devuelve(e f), de modo que (cAr(cAr(cDr(cDrlst))))devuelvee, o lo que es lo mismo:(cAADDrlst)devuelveePor ltimo, veamos cmo se obtiene f. (cAr(cDr(cDrlst)))devuelve(e f)tal como se vio en el ejemplo anterior. As que(cDr(cAr(cDr(cDrlst))))devuelve(f), que os recuerdo que se trata de una lista y que no es lo mismo quef. Por tanto(cAr(cDr(cAr(cDr(cDrlst)))))devuelvef.Podramospensar que(cADADDr lst)tambin devuelvef. Pero al ejecutar esta lnea AutoCAD nos dice que la funcincADADDrno est definida.Ya dijimos antes que se puedenagrupar hasta 4 funciones cAr y cDr, peroaquestamos intentando agrupar 5, ylgicamenteno podemos. Para obtenerfpodramosescribir, por ejemplo: (cAr(cDADDrlst)) (cADADr(cDrlst))(LENGTH lista)En la variableptotenamosuna 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 slotendrn2 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 existeproducindoseun 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:(lengthpto)devuelve3. y si el puntoptoestuvieraen 2D (X Y) devolvera2.Y qu devolvera(lengthlst)? siendolst=((a b) (c d) (e f)). Pues devolvera3, ya que lst es una lista con 3 elementos, que a su vez son listas de dos elementos cada una.Qu devolvera(length(carlst))? El nmero de elementos del primer elemento delst, es decir el nmero de elementos de (a b), que es2.(LIST elemento1 elemento2 )Esta funcin devuelve una lista formada por los elementos indicados. De modo que se utiliza para crear listas. Por ejemplo:(list1 2 3)devuelve(1 2 3)(listpepe2Juan)devuelve(pepe 2 Juan)Veamos que hace la siguiente expresin:(list(lista b)c(listd e)f)Recuerda que en AutoLISP cuando nos encontramos conlistas anidadasunas dentro de otras, siemprese evalan primero las listas interiores. (lista b)devuelve(a b) (listd e)devuelve(d e)As que(list(lista b)c(listd e)f)devuelve la siguiente lista((a b) c (d e) f).Ejecutar comandos de AutoCAD

Una de las mayores ventajas de la programacin enAutoLISPes 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 devuelvenil los nombres de los comandos de AutoCAD, y sus opciones, se indican como textos por lo que van incluidos entre comillas(commandlinea(list0.0 0.0) (list100.0 200.0))Dibujar una lnea desde el origen al punto100,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 pulsarINTRO. Pues ese Intro tambin hay quepasarloa 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 datosdependerndel comando de AutoCAD indicado. Por ejemplo para el comando circulo, ser:(commandcirculo(list0.0 0.0)25.0)Esto dibujar una circunferencia de radio25con centro en el origen.Los idiomas de AutoCADSupongamos 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:(commandlinea(list0.0 0.0) (list100.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 bilinge, 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(list0.0 0.0)25.0)(command_line (list0.0 0.0) (list100.0 200.0))Las opciones de los comandos tambin se deben indicar en ingls anteponiendo un guin bajo. Por ejemplo:(command_circle(list0.0 0.0)_d25.0)Esta lnea dibuja una circunferencia deDimetro 25con centro en el origen.Comandos de AutoCAD originalesPor 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 dibujepentgonosy el comando linea para que dibuje circunferencias.Si redefinimos el comando lnea para que dibuje circunferencias, entonces deberamos indicar algo similar a(commandlinea centro radio)en lugar de(commandlinea pt0 pt1). Pero cmoharamosentonces para dibujar una lnea?Para ejecutar los comandos originales de AutoCAD, y no los redefinidos (si lo estn) debemosanteponer al nombre del comando un punto, por ejemplo:(command.circulo(list0.0 0.0)25.0)(command.linea(list0.0 0.0) (list100.0 200.0))Podemos adems indicar los comandos en Ingls anteponiendo un guin bajo as que tambin lospodramosescribir as:(command._circle(list0.0 0.0)25.0)(command_.circle(list0.0 0.0)25.0)Da igual si se pone antes el punto o el guin bajo.Redefinir un comando de AutoCADPara 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:(commandanuladef linea)o(command_undefine _line)2. podemos comprobar que el comando lnea ya no funciona1. Puedes tratar de ejecutarlo en castellano, en ingls, directamente en AutoCAD o en una expresin de AutoLISP2. 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 LISP1. Creamos la macro que se indica a continuacin, la guardamos y la cargamos en AutoCAD(defunC:LINEA( )(setqpt(getpointCentro del crculo:))(setqrad(getrealRadio 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 ordenador2. ejecutar el comando de AutoCAD redefine (En Ingls es igual, pero con un guin bajo delante) e indicar el 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 llamadoCIRCPERIque 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 devuelveTy en caso contrario devuelvenil.(=5(+1 4))devuelveTporque(+ 1 4)devuelve5(=5(+1 4.0))devuelveTaunque(+ 1 4.0)devuelve5.0y no5. Pero5y5.0valen lo mismo, no?(=5 5.0)devuelveTNo solo podemos evaluar nmeros, tambin textos:(setqtxt1 Curso de Lisp)(=txt1 Curso de Lisp)devuelveT(=txt1 Curso de LISP)devuelvenil. No es lo mismo un texto en maysculas que en minsculas.(=LISP Lisp)devuelvenilEstamos comparando expresiones, as que:(=(+1 5) (/12 2))devuelveTporque ambas expresiones devuelven como resultado6.La funcin=puede aceptar ms de dos expresiones:(=6(+1 5)6.0(/12 2))devuelveT, pues las cuatro expresiones devuelven6o6.0(que vale lo mismo).(/= expr1 expr2 )Es muy similar a la anterior. DevuelveTsi las expresiones no devuelven el mismo valor y devuelvenilsi todas las expresiones devuelven el mismo valor.(/=6 6.0)devuelvenil, porque6y6.0no son distintos (valen lo mismo).(/=(+5 5) (/12 2))devuelveT, pues la primera expresin devuelve10y la segunda6.(/=LISP Lisp)devuelveT(< expr1 expr2 )Compara si expr1 es menor q expr2(3 4)devuelvenilEn el ejemplo anterior, como la primera expresin(>3 4)devuelvenil, ya no secontinanevaluando el resto de expresiones. Cmo hay una expresin que devuelvenil,ANDdevolvernil. 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))devuelvenil, porque ambas expresiones sonnil(or(=5 5.0) (>3 4))devuelveT, pues la primera expresin se cumpleEn el ejemplo anterior, como la primera expresin(=5 5.0)devuelveT, ya no secontinanevaluando el resto de expresiones. Cmo hay una expresin que devuelveT,ORdevolverT. De modo que la expresin(>3 4)ya no se evala.(setqa Soy otro texto b15cTdnil)(ora b)devuelveT(orc d)devuelvenil(ord d)devuelvenil(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).(setqpt1(list10.0 20.0 0.0)pt2(list10.0(*10.0 2)0.0)pt3(list9.99 20.0 0.0)pt4(list9.99 20.02 0.0))Al comparar estas listas (puntos) con la funcin=siempre nos devuelvenil. Aunquept1ypt2sean iguales, y muy parecidos apt3ypt4. Por tanto, la funcin=no nos servir para comparar listas.Para comparar dos listas se utilizar la funcin EQUAL.(equal5 5.0)devuelveT, al igual que la funcin=, porque5vale lo mismo que5.0(equalpt1 pt2)devuelveTEQUALadems ofrece un argumento opcional [precisin]. Veamos cmo funciona :(equal4.99 5.0 0.1)devuelveT, porque compara4.99y5pero con una precisin de0.1. As que con esa precisin4.99==5.0Sin embargo, si subimos la precisin(equal4.99 5.0 0.001)devuelvenilY qu pasa con las listas? Tambin podemos indicarle una precisin? Veamos..(equalpt1 pt30.1)devuelveT, porque compara los elementos de las listas (coordenadas) con la precisin que hemos indicado,0.1Si subimos la precisin(equalpt1 pt30.001)devuelvenil(equalpt1 pt40.01)devuelvenil(equalpt1 pt40.02)devuelveT, porque la precisin es0.02que es exactamente la diferencia entre20.02y20El utilizar una precisin muy elevada no implica que todas las comparaciones devuelvanT, todo depender de los valores a comparar:(equal15 20 100)devuelveT(equal5000 4200 100)devuelvenil(NOT expr)A esta funcin le gusta llevarle la contraria a la expresin que recibe como argumento. si la expresin devuelvenil, entoncesNOTdevuelveT. si la expresin devuelve cualquier cosa que no seanil, entoncesNOTdevuelvenil.(not5)devuelvenil(notTexto)devuelvenil(not(+5 1))devuelvenilSi hacemos(setqa5bnilcTd Nuevo texto)(notb)devolverT, porquebesnil(notc)devolvernil.Veamos que devuelve la siguiente expresin:(and(notc)5)ComocesT,(notc)devuelvenil. Al no cumplirse la primera expresin deAND, esta devuelvenily no contina evaluando.Estructuras condicionales simples

Hasta ahora nuestro cdigo ha sido completamente lineal, las lneas de cdigo que escribamos seejecutabanuna tras otra en el mismo orden. En este tema veremos un tipo de funciones que nospermitirnbifurcar el cdigo, de modo que ya no exista un nico camino sino dos o ms. Veamos un ejemplo en pseudocdigo:1. Introducir el lmite inferior2. Introducir el lmite superior3. El lmite superior es menor que el inferior?1. SI> Mensaje El lmite superior debe ser mayor que el inferior2. NO > intervalo = lmite superior lmite inferior(IF condicin expr_si_cumple [expr_no_cumple])La funcinIFes una de las ms empleadas al programar. Devuelve el valor de la ltima expresin evaluada. Si condicin es distinta de nil, entonces evala laexpr_si_cumple. Si condicin devuelvenilevala laexpr_no_cumple, si existe y si no existe no hace nada. Veamos algunos ejemplos:(if(=2 2.0) (alertLos nmeros son iguales))La condicin a evaluar es:(= 2 2.0)en la que tenemos un nmero entero2y uno real2.0, pero su valor es el mismo. Aunque sean de distinto tipo2y2.0valen igual. As que la condicin devuelveT,evalundosela condicin si cumple que muestra un mensaje de alerta. La funcinIFdevuelve el valor de la ltima expresin evaluada, es deciralert, que esnil.(if(=2 3) (alertLos nmeros son iguales))En este caso la condicin devuelvenily al no existir expresin no cumple, no hara nada ms. Qu valor devolveraIF? El de siempre, el valor de la ltima expresin evaluada, que en este caso ha sido la propia condicin que devuelvenil. De modo queIFdevolvernil.(if(=2 3)(alertLos nmeros son iguales)(alertLos 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 devuelvenil.Veamos el siguiente ejemplo:(setqliminf(getint\nLmite inferior:))(setqlimsup(getint\nLmite superior:))(if(>liminf limsup)(alertEl lmite superior debe ser mayor que el inferior)(setqlimsup(getint\nLmite superior:))(setqintervalo(-limsup liminf))(setqintervalo(-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 esla primera expresin(alertEl lmite superior debe ser mayor que el inferior).Si la condicin no se cumple, devuelvenil, 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 queIFno 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 funcinIFse suele emplear la funcinPROGN. El valor devuelto porPROGNes 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?(setqliminf(getint\nLmite inferior:))(setqlimsup(getint\nLmite superior:))(if(>liminf limsup)(progn(alertEl lmite superior debe ser mayor que el inferior)(setqlimsup(getint\nLmite superior:))(setqintervalo(-limsup liminf)))(setqintervalo(-limsup liminf)))En este caso la condicin si cumple es todo lo siguiente:(progn(alertEl lmite superior debe ser mayor que el inferior)(setqlimsup(getint\nLmite superior:))(setqintervalo(-limsup liminf)))Si se cumple la condicin, se evala la condicin si cumple, es decir elprogn. De modo que se van evaluando las expresiones contenidas en la funcinPROGN, que devuelve el valor de la ltima expresin(setqintervalo(-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,(setqintervalo(-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) ( Hace queGETdistdevuelva la distancia en 2D. Es como si proyectase la distancia real sobre el plano XY.Getdistsolicita una distancia, que se puede escribir directamente, o se pueden indicar dos puntos en pantalla. En este caso,getdistdevolver 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(initget64)antes de la ejecutargetdist. Por ejemplo:(setqpt1(getpoint\nPunto base:))(initget64)(setqdist12(getdistpt1 \nSegundo punto:))Por ltimo, el cdigo 128 permite indicar una expresin de AutoLISP como respuesta. Por ejemplo, podemos utilizar nuestra rutinaRAG(Radianes A Grados decimales) para indicar un ngulo en grados decimales cuando nosotros lo tenemos en radianes.(initget128)(setqang(getreal\nIntroducir ngulo:))En este caso el usuario podra indicar como respuesta a la solicitud del ngulo:(RAG(/ pi4))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 rutinasARANDyCIRCPERI.Si revisamos el cdigo de la macroCIRCPERIencontraremos la siguiente lnea:(setqpto(getpoint\nCentro de la circunferencia:))deberamos aadir alguna limitacin como respuesta del usuario? Veamos: Si el usuario pulsa Intro como respuesta a la variableptose le asocia el valornil, que es lo que devolveraGetpoint. 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(initget1)antes de la funcingetpoint. 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 ainitgetel cdigo 8. El cdigo 32 no tiene sentidoaqu, 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.Aqunos pide un punto, as que no tiene demasiado sentido.Definitivamente el cdigo quedara:(initget1)(setqpto(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(setqperi(getdist))(setqrad(/peri(*2pi)))(setqrad(getvarcirclerad)))Deberamos aadir la funcininitgetcon el cdigo 1 antes de la funcingetdist?Veamos como funciona esta parte del cdigo: Si el usuario introduce una distancia, se evala la condicin si cumple delIFes decir:(setqrad(/peri(*2pi)))Y si el usuario pulsaIntro, se asigna aperiel valornily evala la condicin no cumple delIF, es decir:(setqrad(getvarcirclerad)) Si aadimos antes delgetdistla expresin(initget1), el usuario no podr indicarIntro, as que nunca se ejecutara la expresin no cumple. Por tanto no aadimos el cdigo 1 aInitget. El permetro del crculo no puede ser ni cero ni un nmero negativo, de modo que podemos aadir ainitgetlos cdigos 2 y 4. Tambin podramos aadir el cdigo 64 para queGETdistdevuelva 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 valor0.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:(defunC:CIRCPERI(/pto rad peri cmd0)(if(=(setqcmd0(getvarcmdecho))1)(setvarcmdecho0))(initget1)(setqpto(getpoint\nCentro de la circunferencia:))(if(=(getvarcirclerad)0.0)(progn(prompt\nPermetro:)(initget7))(progn(prompt\nPermetro :)(initget6)))(if(setqperi(getdist))(setqrad(/peri(*2pi)))(setqrad(getvarcirclerad)))(command_.circle pto rad)(if(=cmd01)(setvarcmdecho1))(princ))(prompt\nNuevo comando CIRCPERI cargado)Vamos ahora a modificar la rutinaARAND.La primera solicitud que tenemos enARANDes la del centro de la arandela.Prcticamentees igual que la solicitud del centro del crculo enCIRCPERI, as que le aadimos tambin el cdigo 1 aInitget:(initget1)(setqpto(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 aadiremosInitgetcon el modo 7. Veamos el cdigo completo:(defunC:ARAND (/pto rad cmd0)(command_.undo _begin)(if(=(setqcmd0(getvarcmdecho))1)(setvarcmdecho0))(initget1)(setqpto(getpoint\nCentro de la arandela:))(initget7)(setqrad(getdistpto \nRadio interior:))(command_.circle pto rad)(initget7)(setqrad(getdistpto \nRadio exterior:))(command_.circle pto rad)(if(=cmd01)(setvarcmdecho1))(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 funcinINITGETy 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:(initget7Dimetro Permetro)(setqrad(getdist\nRadio del circulo / Dimetro / Permetro :))como respuesta agetdistpodemos 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 variblerad. Si indicamos como respuesta Dimetro, asocia a la variableradla cadena de texto Dimetro. Si indicamos como respuesta Permetro, asocia a la variableradla 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 respuestalas letras que aparecen en maysculas. Es decir, laDo laP.En el siguiente ejemplo:(initget7Dimetro desHacer)(setqrad(getdist\nRadio del circulo / Dimetro / desHacer:))Para seleccionar la opcin Dimetro habr que escribir al menos laD. Pero para seleccionar desHacer al menos habr que escribirH.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 seleccionarDimetro.Supongamos que tenemos el siguiente cdigo:(initget7Dimetro desHacer)(setqrad(getdist\nRadio del circulo:))En este casogetdistaceptar como respuestas a la peticin del radio de la circunferencia Dimetro y desHacer. Pero al no indicar estas opciones en el mensaje degetdist, el usuario no sabr que existen. De modo que es recomendable indicar al usuario las opciones que puede seleccionar:(initget7Dimetro desHacer)(setqrad(getdist\nRadio del circulo / Dimetro / desHacer :))Como mejor se ve es con un ejemplo as que, vamos a modificar la rutinaARANDaadiendo una opcin para indicar el dimetro en lugar del radio. Tenemos que modificar las siguientes lneas:(initget7)(setqrad(getreal\nRadio interior:))Primero aadimos Dimetro a la lista de palabras clave deinitget:(initget7Dimetro)Y a continuacin le decimos al usuario que existe una opcin llamada Dimetro que puede seleccionar como respuesta:(setqrad(getreal\nRadio interior / Diametro:))De esta forma ya hemos aadido la opcin DimetroPero, qu sucede si el usuario indica como respuesta la opcin Dimetro? Pues que asignamos a la variableradla 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)(setqrad(getreal\nDimetro interior:)))Hay que tener especial cuidado con la condicin delIF(=rad Dimetro)ya que hay que indicar la palabra clave tal y como aparece en la lista de palabras clave deinitget.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 variablerady luego(if(=rad Dimetro) devuelvenil, puesto querades distinto de Dimetro. Si el usuario indicaDoDiam, odimetro, entonces asigna a la variableradla cadena de texto Dimetro. Luego al entrar en elIF,(=rad Diametro)devuelveTas que evala la expresin si cumple(setqrad(getreal\nDimetro interior:))que pide un dimetro al usuario y lo asigna a la variablerad. Peroradviene 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:(initget7Dimetro)(setqrad(getreal\nRadio interior / Dimetro:))(if(=rad Dimetro)(setqrad(/(getreal\nDimetro interior:)2.0)))Pero, Qu pasa si el usuario hace lo siguiente? IndicaDcomo respuesta al radio interior. Indica-50o0como dimetro.Pues que asignara a la variableradel resultado de dividir-50o0entre2.0. Por tanto tendramos una circunferencia con radio negativo o cero.Recuerda queinitgetsolo tiene efecto sobre la siguiente funcin de solicitud de datos, de modo que tenemos que aadir de nuevo la funcinInitgetantes de preguntar por el dimetro:(initget7Dimetro)(setqrad(getreal\nRadio interior / Dimetro:))(if(=rad Dimetro)(progn(initget7)(setqrad(/(getreal\nDimetro interior:)2.0))))Se ha aadido la funcinPrognya que sino, solo se puede ejecutar una expresin como condicin si-cumple delIF.Para el radio o dimetro exterior se hara exactamente lo mismo. Por tanto el cdigo completo ser:(defunC:ARAND(/pto rad cmd0)(command_.undo _begin)(if(=(setqcmd0(getvarcmdecho))1)(setvarcmdecho0))(initget1)(setqpto(getpoint\nCentro de la arandela:))(initget7Dimetro)(setqrad(getdistpto\nRadio interior / Dimetro:))(if(=rad Dimetro)(progn(initget7)(setqrad(/(getreal\nDimetro interior:)2.0))))(command_.circle pto rad)(initget7Dimetro)(setqrad(getdistpto \nRadio exterior / Dimetro:))(if(=rad Dimetro)(progn(initget7)(setqrad(/(getreal\nDimetro exterior:)2.0))))(command_.circle pto rad)(if(=cmd01)(setvarcmdecho1))(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 conINITGET, por ejemplo:(initgetDEShacer Nuevo Repetir)(setqopc(getkword\nDEShacer / Nuevo / Repetir:))En este caso el usuario tan slo podr indicar como respuesta una de las palabras clave de la funcinInitgety se la asigna a la variableopc.No hemos indicado el modo en Initget, tal solo las palabras clave. En la rutinaARANDnos interesaba que apareciera el modo 7 para que no se indique como respuestaIntro,0o un nmero negativo. Pero no es obligatorio indicar siempre un modo.Un ejemplo bastante habitual en las macros es el siguiente:(initgetDEShacer Nuevo Repetir)(setqopc(getkword\nDEShacer / Nuevo / Repetir:))(cond((=opc DEShacer)(alertHas seleccionado la opcin DEShacer))((=opc Nuevo)(alertHas seleccionado la opcin Nuevo))(T(alertHas 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 slopodamoscrear programas cuya ejecucin fuera lineal: Haz esto Ahora esto otro Luego vimos las estructuras condicionalesIFyCONDque 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 funcinwhileejecuta las expresiones indicadasMIENTRASse cumpla la condicin, y devuelve el valor de la ltima ex