martes, 9 de agosto de 2011

tutorial muy básico AUTOLISP

NOTA: el enlace siguiente es un básico super-útil.


Tema 1. Introducción:

Autor: Robierzo

Vaya por delante que yo no soy el que más sabe de esto y que estaría encantado que corrigieseis todo cuanto creáis que puede corregirse o añadir.

Para aquellos que no tienen ni idea, parece obligado decir que:

1º-. AutoLisp es un lenguaje de programación para Autocad. Es decir, si no trabajas con autocad es bastante ilógico aprender una herramienta que sólo funciona bajo Autocad. A partir de Autocad 14 nace el VisualLisp, que no es otra cosa que Autolisp, pero con una cantidad enorme de nuevas funciones que facilitan mucho las cosas. "Para quien lo domine, claro, pues no es mi caso.

2º-. Cuantos más conocimientos se tienen de autocad mas fácil es de elaborar las rutinas en autolisp. Al fin y al cabo, se trata de realizar un programita que haga lo que auocad no hace, o que hace a medias, o que hace de modo lento y tedioso.

3º-. Las rutinas son ficheros de texto, de extensión "lsp", que normalmente se guardan en las carpetas de acceso directo de autocad, normalmente en la carpeta SUPPORT. Si echáis un vistazo en esta carpeta, encontraréis muchos de estos ficheritos con extensión *.lsp. Normalmente ocupan muy poco, pues son ficheros de texto, editables con cualquier editor de texto. Si editáis uno de estos ficheritos, veréis el código original de una rutina normal y corriente de Autolisp. Muchas veces el autor de una rutina de éstas opta por compilarla. La compilación lo que hace es crear un fichero en lenguaje máquina, mas accesible para nuestro ordenador, que acelera las operaciones de la rutina, y además oculta el contenido real de la rutina. Estos ficheros compilados tienen extensión *.fas. Son exactamente igual que los *.lsp, pero como digo, en lenguaje máquina. De esta manera podemos proteger nuestras rutinas de cambios o intrusismo por parte de otros “piratillas” que quieran hacerlas de su propiedad.

4º-. Autocad, a partir de su versión 14, incorpora una herramienta a modo de editor, que podéis encontrar en la barra de menús: "Herramientas/Autolisp/editor de VsualLisp"

Desde aquí se abre el editor de Visual-Lisp/AutoLisp. Una vez abierto el editor vamos a “Archivo/nuevo archivo” y ya estamos en disposición de empezar a elaborar nuestra nueva rutina.

-----------------------------------------------------------------------------

Yo soy desconocedor de gran parte de los iconos y herramientas del editor de VisualLisp, por lo que si alguien puede ampliar el funcionamiento de los mismos, pues todos encantados. Si bien, yo nací con autolisp de la versión 11 de Autocad, y entonces sólo cabía la posibilidad de crear las rutinas con un simple editor de texto de MS-DOS, para probarlas luego en autocad. Ahora utilizo el editor de VisualLisp, muy útil por su sistema de presentación, pues utiliza de forma automática colores distintos para comandos de autolisp, aclaraciones, variables, textos,....

Os resultará fácil comprenderlo. Podéis abrir cualquier fichero *.lsp para echarle un vistazo, eso sí. Sin cambiar nada, de momento.

-----------------------------------------------------------------------

5º-. Existen 2 máximas en programación:

1ª máxima: Ningún programa funciona a la primera. Es más. Yo diría que ningún programa funciona a la segunda. (Si tu eres de los que lo consigues, enhorabuena). Así que no desesperéis si las cosas no salen a las primeras de cambio.

2ª máxima: Cualquier programa es mejorable. Si creéis que sois unos monstruos de la creación por hacer un excelente programa, sabed que vendrá alguien que os dejará hechos polvo, simplemente añadiendo una coma a vuestra magnífica rutina. ¿Por qué creéis que autocad va por la enésima versión?

6º-. Las maneras de cargar una rutina en autocad son dos: 1ª: Desde la barra de menús de autocad “Herramientas/Autolisp/cargar” o 2ª: desde la línea de comandos, escribiendo: (load”nombre rutina”)

Ej.: si tenemos una rutina que se llama prueba.lsp, escribiríamos: (load”prueba”)

7º-. Y para terminar esta tediosa introducción, un par de cositas más.

En autolisp hay dos elementos que son imprescindibles. El paréntesis “ ()”y el punto y coma “ ; ” . Todas las funciones o expresiones deben ir precedidas de un punto y coma o metidas entre paréntesis. De esto ya hablaremos en la próxima cita.

Os adjunto, diligencia de DEVIGT, las funciones matemáticas que vamos a utilizar habitualmente, para que os vayáis familiarizando.

Tema 1. Introducción: Funciones matemáticas


Autor: Robierzo

Pasaré a describir las distintas funciones de lisp por temas.

Empecemos por la de Matemáticas.

+ suma

- resta

* multiplica

/ divide

rem resto de una división de neteros

1+ suma 1

1- resta 1

abs valor absoluto

fix la parte entera de un numero real

float convierte un entero en un real

gcd máximo común denominador

min el más pequeño de un grupo

max el mayor de un grupo

sqrt la raíz cuadrada

expt exponente

exp potencia de e , base de los logaritmos naturales

log logaritmo natuar

cvunit conversor de unidades

Sigamos por cómo se usan estas funciones.

Lisp tiene un modo particular de expresar las operaciones matemáticas

, según tengo entendido se deriva de la Notación polaca inversa, no es igual pero se le asemeja.

las operaciones se escriben poniendo como prefijo el operador

por ejemplo para sumar 2 + 3 pondremos

+ suma

( + 2 3 ) devuelve 5 , por supuesto

( + 4 5.6 -2 ) da 7.6, en este caso es la suma de dos numeros positivos mas un negativo

Les comento algo , no hace falta escribir un programa para verificar esto,

tan solo pongan en la linea de comandos de acad la operación tal como la he puesto arriba , abren parentesis , el signo mas, el 2, el 3 , cierran parentesis y dan intro enter y podrán ver el resultado en la linea de comando.

y así para todas las operaciones

- resta

( - 9 7 )

( - 8 4 0.5 )

Multiplica

( * 6 7)

( * 2 -3 1.5 )

Division

( / 12 6 )

( / 11 6) , fíjense que pasa con esta division , y aquí vale lea pena hablar sobre enteros INT y reales .

11 y 6 son dos enteros y por lo tanto darán como resultado la parte entera de la división que será 1

ahora si tan solo ponen el divisor como real , el resultado será un real

( / 11 6.0)

basta decir que para que un número sea real debe tener expresada su parte decimal , aunque sean 0

6 es un entero

6.0 es un real

PRESTEN ATENCIÓN A ESTE TEMA , YA QUE ES MOTIVO DE ERRORES QUE SON AVECES CASI IMPOSIBLES DE DETECTAR.

bueno por ahora los dejo , pero antes les dejo una lección completa , lamentablemente está en inglés , pero es lo único que tengo a mano

Cita:

Function Definitions

--------------------------------------------------------------------------------

1 - Mathematics

--------------------------------------------------------------------------------

+ ..... Adds

(+ 2 3) returns 5

(+ 4 5.6 -2) returns 7.6

After (setq a 20 b 9)

(+ a b) returns 29

--------------------------------------------------------------------------------

- ..... Subtracts

(- 9 7) returns 2

(- 8 4 0.5) returns 3.5

After (setq a 20 b 9)

(- a b) returns 11

(- b a) returns -11

(- a) returns -20. When only one argument is supplied, its value is subtracted from 0, switching the sign of any number.

--------------------------------------------------------------------------------

* ..... Multiplies

(* 6 7) returns 42

(* 2 -3 1.5) returns -9.0

After (setq a 3 b 4.5)

(* a b) returns 13.5

(* a a) returns 9

--------------------------------------------------------------------------------

/ ..... Divides

(/ 12 6) returns 2

(/ 11 6) returns 1 (Division using only integers ignores any remainder. Beware of "integer division.")

(/ 11 6.0) returns 1.833333

(/ 12 3 2) returns 2

(/ 12 -2.0) returns -6.0

--------------------------------------------------------------------------------

rem ..... Returns a remainder resulting from division

(rem 10 3) returns 1

(rem 10 5) returns 0

(rem 6.2 1.2) returns 0.2

--------------------------------------------------------------------------------

1+ ..... Increments by 1

(1+ 16) returns 17

After (setq a 21)

(1+ a) returns 22. Used with setq, this serves as a loop counter for iteration. For example, (setq c (1+ c)).

(1+ -4) returns -3

--------------------------------------------------------------------------------

1- ..... Decrements by 1

(1- 16) returns 15

After (setq a -8)

(1- a) returns -9

--------------------------------------------------------------------------------

abs ..... Returns the absolute of a number

(abs 7.0) returns 7.0

(abs -6) returns 6

--------------------------------------------------------------------------------

fix ..... Discards fractional portion of a number and returns an integer

(fix 7. 1) returns 7

(fix 7.9) returns 7

(fix -4.6) returns -4

--------------------------------------------------------------------------------

float ..... Converts a number to a real number (floating point decimal number)

(float 5) returns 5.0

(float 5.82) returns 5.82

--------------------------------------------------------------------------------

gcd ..... Returns the greatest factor (divisor) common to two or more integers. Arguments must be positive integers.

(gcd 21 39) returns 3

(gcd 102 138) returns 6

(gcd 30 45 60) returns 15

Autodesk says this function returns the "greatest common denominator" (a meaningless phrase). It is better to think of it as "greatest common divisor."

--------------------------------------------------------------------------------

min ..... Returns the smallest (lowest) of two or more numbers

(min 8 3 11.88 14 6) returns 3.0

(min 13 -28 2 66) returns -28

--------------------------------------------------------------------------------

max ..... Returns the greatest of two or more numbers

(max 8 3 11.88 14 6) returns 14.0

(max -22 -2 16) returns 16

--------------------------------------------------------------------------------

sqrt ..... Returns the square root of a number as a real

(sqrt 16) returns 4.0

(sqrt 2.0) returns 1.414214

--------------------------------------------------------------------------------

expt ..... Raises a given number to a given power

(expt 3 4) returns 81

(expt 2.0 5.0) returns 32

(expt 3 -2) returns 0 (negative exponents applied to integers can appear to give incorrect results because of integer division)

(expt 3.0 -2.0) returns 0.111111

(expt 256 0.25) returns 4.0

After (setq a 2.25 b 0.5)

(expt a b) returns 1.5

--------------------------------------------------------------------------------

exp ..... Returns e raised to a given power

(exp 1.0) returns 2.71828

(exp 2.14) returns 8.49944

(exp 0.4) returns 1.49182

(exp -2.0) returns 0.135335

Euler's number, e, is the base of natural logarithms, and equals approximately 2.71828. It is used to simplify certain formulas in calculus. Compare log below.

--------------------------------------------------------------------------------

log ..... Returns the natural log (base e) of a number. Compare exp above.

(log 3) returns 1.09861

(log 1.82) returns 0.598837

(log 0.25) returns -1.38629

--------------------------------------------------------------------------------

cvunit ..... Converts a value, or a list of values, from one unit to another. The first argument is the number to be converted, the second argument is the unit from which you are converting, the third argument is the unit to which you are converting.

(cvunit 10 "inch" "mm") returns 254.0

(cvunit 100 "mm" "inch") returns 3.93701

(cvunit 25 "lb" "kg") returns 11.3398

(cvunit (list 6 5 24) "inch" "feet") returns (0.5 0.416667 2.0)

After (setq a 1 b 2)

(cvunit a "inch" "mm") returns 25.4

(cvunit (list (eval a) (eval b)) "inch" "mm") returns (25.4 50.8)

The unit names for the second and third arguments must be spelled as they appear in the ACAD.UNT file. The cvunit function depends on the values in ACAD.UNT. Therefore, for most conversions, simple multiplication or division by the appropriate factor within the AutoLISP expression is preferred over dependence on an external file.


Tema 2. Primeros pasos:

Autor: Robierzo

Como ya adelantó hace unos días nuestro amigo Gabriel, empezaremos hablando de algunos caracteres especiales básicos en Autolisp, no sin antes aclarar que la mayoría de comentarios y notaciones empleadas a partir de ahora han sido tomadas de los libros cuya bibliografía paso a detallar, y que recomiendo le echéis un vistazo:
Autor: Jose Antonio Tajadura y Javier López Tit: Autolisp 12,13,14 Edit: Mc Graw Hill
Autor:Reinaldo togores y César Otero Tit: Programación en Autocad con Visual Lisp Ed.: Mc Graw Hill

1º Punto y coma: ; Sirve para añadir comentarios o aclaraciones que nos ayuden a entender mejor nuestra rutina. Todo lo que vaya detrás del punto y coma, en realidad podríamos borrarlo y el programa no sufriría alteraciones. Así que este carácter sólo lo usaremos para esto.
2º Paréntesis: ( ) Debe haber el mismo número de paréntesis de apertura que de cierre. De lo contrario se producirá un error. Los utilizaremos para preceder cualquier comando de Autolisp y para dar fin a dicho comando.
3º Comillas: " " Se utilizan para encerrar expresiones de texto que queremos que aparezcan en la pantalla, ya sea en la línea de comando o en una ventana. Todo lo que esté entre comillas será considerado como una cadena de texto, incluso los paréntesis, comas, punto y comas.... Como los paréntesis, debe haber un número par de comillas.
4º Punto: . Se usa como punto decimal.
5º Apóstrofo: ‘ Equivale al comando (QUOTE). Devuelve el literal de la expresión.
6º Contrabarra: \ Dentro de una cadena de texto podemos incluir una contrabarra seguida de uno de los siguientes caracteres:
\n: Retorno de carro, nueva línea
\r: Return
\t: tabulador
Es decir. Si escribimos: (GETPOINT pt "\nSeñala un punto") , cuando Autolisp evalúe esta expresión, antes de escribir "Señala un punto" en la línea de comando, hará un salto de carro para que no aparezcan dos o más expresiones distintas, unas a continuación de otras.
7º Cierre admiración: ! Sirve para extraer desde la línea de comandos, el valor de una variable.
Ej.: (SETQ radio 5.639)
Si tecleamos !radio en la línea de comandos nos aparecerá 5.639

ACLARACIONES
*Autolisp no distingue entre mayúsculas y minúsculas.
*Es conveniente usar el nombre de las órdenes de Autocad en inglés. Si trabajamos con Autocad español y queremos saber el nombre en inglés tecleamos en la línea de comando:
(GETCNAME "orden en catellano")
Ej.: (GETCNAME “texto”) y aparece "_text"
*Autolisp siempre trabaja en radianes
*PI es el número 3.1415926....., por lo que ninguna variable podrá llamarse PI.
*T es el símbolo de True, cierto, por lo que ninguna variable podrá llamarse T.
*nil es el símbolo de falso, por lo que ninguna variable podrá llamarse nil. Siempre aparecerá en minúsculas, nunca NIL.


(DEFUN ) DEFINIR FUNCIONES
Las distintas funciones que forman una rutina se definen mediante el comando
(DEFUN )
Dentro de una rutina podrá haber decenas de funciones. Lo que suele hacerse es crear una función principal, desde la cual se irán llamando al resto de funciones secundarias. Es como si tuviésemos varias rutinas dentro de otras.
es el nombre de nuestra función
es el nombre de las variables que vamos a tener dentro de esta función
Importante: Las variables pueden ser locales o globales. Esto quiere decir que:
Si son globales, podremos seguir utilizándolas fuera de esta función.
Si son locales, sólo tendrán valor dentro de esta función.
Tanto unas como otras van entre paréntesis. Las locales van precedidas de una barra /
Si ponemos un paréntesis sin nada (), daremos por supuesto que todas son globales.
Hay que tener en cuenta que en rutinas muy largas, donde existen muchas variables, y donde utilizamos otras rutinas, cuantas más variables globales tengamos, más lentos pueden ser los cálculos.
Una ver gargada una rutina, para ejecutarla en otras ocasiones dentro de la misma sesión de Autocad sin tener que volver a cargarla, debemos añadir c: delante del nombre de la función, para que, tecleando dicho nombre en la línea de comando ya arranque de nuevo.

(SETQ .....) ATRIBUIR VALORES

Pues eso, sirve para atribuir valores a una variable.

Ej: (SETQ radio 5 x 155.36 y 785.961 nombre "Soy un monstruo")
Si tecleamos esto en la línea de comandos y luego vamos tecleando sucesivamente:
!radio aparece 5
!x aparece 155.36
!y aparece 785.961
!nombre aparece "Soy un monstruo"

(PROMPT ) ESCRIBE MENSAJE
Escribe un mensaje en la línea de comandos

(TERPRI) SALTA A UNA NUEVA LINEA

(GETPOINT ) INTRODUCE UN PUNTOBien mediante señalamiento en pantalla, o bien mediante teclado.
Ej.:
(SETQ pt (GETPOINT "\nIntroduce un punto:"))
Después de introducir un punto, sus coordenadas se almacenan en la variable pt.

(COMMAND ) EJECUTA UNA ORDEN DE AUTOCAD
Decir antes de nada que es recomendable utilizar el nombre de la orden en inglés, precedido de un guión bajo. Así, independientemente de la versión de Autocad y del idioma, salvo en casos excepcionales, nuestra rutina funcionará siempre.
Ej.:
(COMMAND "_line" pt '(150 120) "")
En este caso dibuja una línea desde el punto pt, cuyas coordenadas ya habrán sido determinadas antes, hasta el punto de coordenadas x=150 e y=120.
El nombre de la orden debe ir siempre entre comillas, así como cualquier opción propia de la orden, como por ejemplo el "enter" final.


Ejemplo general:
Copiar esta rutina en el editor de Visual Lisp.

Código:
;;;;;;;;;;;;Rutina para dibujar tres líneas desde un punto.
(DEFUN c:dib_lineas ( / pt1 pt2 pt3 pt4)
;(DEFUN c:dib_lineas ()
(PROMPT "\nEste programa dibuja tres línas desde un punto")
(SETQ pt1 (GETPOINT "\nPrimer punto: "))
(SETQ pt2 (GETPOINT "\nSegundo punto: "))
(COMMAND "_line" pt1 pt2 "")
(SETQ pt3 (GETPOINT "\nTercer punto: "))
(COMMAND "_line" pt1 pt3 "")
(SETQ pt4 (GETPOINT "\nCuarto punto: "))
(COMMAND "_line" pt1 pt4 "")
)

Como observaréis, hemos creado una función llamada dib_lineas, a la que hemos añadido el prefijo c: para poder ejecutarla cuando queramos desde la línea de comandos, una vez la hayamos cargado, como ya se explicó en el TEMA 1.
Esta función contiene 4 variables que le hemos dado carácter local, con lo que, una vez termine, se perderán los valores de sus variables. Sin embargo, si cambias el punto y coma de la segunda línea ;(DEFUN c:dib_lineas () y lo pasáis a la primera línea (DEFUN c:dib_lineas ( / pt1 pt2 pt3 pt4), la rutina queda exactamente igual, pero ahora las variables son globales y podemos utilizarlas en otro momento o conocer su valor tecleando en la línea de comando: !pt1, !pt2.....
Haced la prueba de las dos maneras.
También observaréis que hemos utilizado \n para salto de línea. Podéis eliminarlo y ver lo que pasa.
Un detalle importante. A mi me gusta poner el abre paréntesis y el cierra paréntesis en la misma línea. Pero si se hace muy largo, como es el caso del cierra paréntesis de una función, me gusta ponerlo en la línea vertical del que abre.

Y con esto doy por terminada esta lección. Como siempre, si alguien desea añadir o rectificar algo, pues ya sabe.

FUENTE:
http://www.3dgazpacho.com/autolisp/tema2_primerospasos.html

No hay comentarios:

Publicar un comentario