cg-Cad

Lisp »Tips 'n Tricks »CAL in AutoLISP

Geomcal (cal) è un calcolatore in linea di AutoCAD che accetta espressioni strutturate in accordo con le regole matematiche dell'algebra e restituisce risultati alla linea di comando CAD. Esempio:

 Command: cal >> Expression: 1+1/2
 1.5

Cal può essere usato in autolisp semplificando così l'inserimento di formule.

Uso di cal in autolisp: (cal "formula").

Come esempio dell'utilizzo di Cal all'interno del codice autolisp ecco un lisp che genera numeri irrazionali. La formula da implementare è in questo esempio n=√(9/121*100n+(112-44*n)/121). *

In stile autolisp la formula assume questo aspetto elegante:

(sqrt (+ (* (/ 9 121)(expt 100 n))(/ (- 112 (* 44 n)) 121)))

Scritta nel sorgente autolisp ed eseguito il lisp (con n=10) genera l'errore:

; error: function undefined for argument: -2

Si deve forzare il numero intero come reale per non ottenere come risultato di una divisione 0.

(sqrt (+ (* (/ 9.0 121)(expt 100 n))(/ (- 112 (* 44.0 n)) 121)))
n=10
11118.4

(sqrt (+ (* (/ 9.0 121)(expt 100.0 n))(/ (- 112 (* 44.0 n)) 121)))

n=10
2.72727e+009

Ecco il lisp con (cal "formula")

NIR

;;; NIR.LSP (C) 2005 by Claudio Piccini
;;; www.cg-cad.com
;;;
;;; Implementa la formula per generare uno "Zebra Irrational"
;;; http://sprott.physics.wisc.edu/pickover/mathcon2.html

(defun c:nir ( / n s )
 (setvar "cmdecho" 0)
 (initget (+ 2 4))
 (setq n (getint "\n numero [10]: "))
 (if (= n nil)(setq n 10))
 (setq n (cal "sqrt(9/121*100^n+(112-44*n)/121)"))
 (setq s (rtos n 2 14))
 (princ s)
 (setvar "cmdecho" 1)
 (princ)
)
;;;eof

Test del Lisp

Attivare il Calcolatore Geometrico dalla linea di comando CAD...
Command: cal >> Expression: 0
0

Command: NIR
numero [10]: 1
2.82842712474619

Command: NIR
numero [10]: 5
27272.72725636364

Command: NIR
numero [10]: 10
2727272727.272728

Command: NIR
numero [10]: 100
2.72727272727273E+99

Restando in tema d'irrazionale ecco un altro lisp che legge (anche) cal in input.

ANIR

;;; ANIR.LSP (C) 2005 by Claudio Piccini
;;; www.cg-cad.com
;;;
;;; Implementa un algoritmo per approssimare numeri irrazionali.
;;; http://home.att.net/~srschmitt/rationalapprox.html

(defun c:anir ( / steps 
                  numero x r a
                  s sp sq
                  k p q p1 p2 q1 q2
 )
 (setvar "cmdecho" 0)

 (setq k  0 ; numero di appros.
       p1 1
       p2 0
       q1 0
       q2 1
 )

 (setq numero (getstring "\nNumero (ad es. \"pi\"): "))
 (setq x (eval (read numero)))
 (setq r x)

 (initget (+ 2 4))
 (setq steps (getint "\nNumero di approssimazioni [10]: "))
 (if (= steps nil)(setq steps 10))

 (while (< k steps)
  (setq a (fix r))
  (setq p (+ (* a p1) p2))
  (setq q (+ (* a q1) q2))
  (setq sp (rtos p 2 0))
  (setq sq (rtos q 2 0))
  (setq s (strcat "\n" (rtos (/ (* p 1.0) q) 2 15) "=" sp "/" sq))
  (princ s)
  (setq k (1+ k))
  (setq r (/ 1 (- r a)))
  (setq p2 p1
        q2 q1
        p1 p
        q1 q
  )
 )

 (command "_redraw")
 (setvar "cmdecho" 1)
 (princ)
)
;;;eof

Test del Lisp

Command: anir
Numero (ad es. "pi"): "pi"
Numero di approssimazioni [10]: 15
3=3/1
3.142857142857143=22/7
3.141509433962264=333/106
3.141592920353982=355/113
3.141592653011902=103993/33102
3.141592653921421=104348/33215
3.141592653467437=208341/66317
3.141592653618936=312689/99532
3.141592653581078=833719/265381
3.141592653591404=1146408/364913
3.141592653589389=4272943/1360120
3.141592653589815=5419351/1725033
3.141592653589793=80143857/25510582
3.141592653589793=245850922/78256779
3.141592653589793=817696623/260280919

Command: anir
Numero (ad es. "pi"): "(sqrt 2)"
Numero di approssimazioni [10]: 15
1=1/1
1.5=3/2
1.4=7/5
1.416666666666667=17/12
1.413793103448276=41/29
1.414285714285714=99/70
1.414201183431953=239/169
1.41421568627451=577/408
1.414213197969543=1393/985
1.41421362489487=3363/2378
1.414213551646055=8119/5741
1.414213564213564=19601/13860
1.41421356205732=47321/33461
1.414213562427273=114243/80782
1.414213562363799=275807/195025

Command: anir
Numero (ad es. "pi"): "(exp 1)"
Numero di approssimazioni [10]: 15
2=2/1
3=3/1
2.666666666666666=8/3
2.75=11/4
2.714285714285714=19/7
2.71875=87/32
2.717948717948718=106/39
2.718309859154929=193/71
2.718279569892473=1264/465
2.718283582089552=1457/536
2.718281718281718=2721/1001
2.718281835205992=23225/8544
2.71828182294395=25946/9545
2.718281828735696=49171/18089
2.718281828445401=517656/190435

Accendere il Calcolatore Geometrico dalla linea di comando CAD...
Command: cal >> Expression: 0
0

Command: anir
Numero (ad es. "pi"): "(cal "sqrt(9/121*100^10+(112-44*10)/121)")"
Numero di approssimazioni [10]: 15
2727272727=2727272727/1
2727272727.333334=8181818182/3
2727272727.25=10909090909/4
2727272727.285714=19090909091/7
2727272727.272728=30000000000/11
2727272727.272728=1143889090909091/419426
2727272727.272728=2287808181818182/838863
2727272727.272728=3431697272727273/1258289
2727272727.272728=5719505454545457/2097152
2727272727.272728=3E+20/123649340209
2727272727.272728=3E+20/123651437361
2727272727.272728=3E+21/1112860839097
2727272727.272728=3E+21/1236512276458
2727272727.272727=6E+21/2349373115555
2727272727.272728=1E+22/3585885392013

Command: anir
Numero (ad es. "pi"): "(cal "sqrt(9/121*100^30+(112-44*30)/121)")"
Numero di approssimazioni [10]: 5

2.727272727272728E+29=3E+29/1; error: divide by zero

Per approfondire:
Approximation of Irrational Numbers
(*) Zebra Irrationals
(*) La matematica di Oz, C.A. Pickover (Franco Muzzio Editore)

Lisp »Tips 'n Tricks

Ultimo Aggiornamento_Last Update: 9 Maggio 2005