Disegnare una catenaria
Per creare i fili tra i palloncini di Balloon Platform Defense ho dovuto capire come disegnare una corda appesa tra due punti, la forma nota più in generale come catenaria. Tutti gli esempi che ho trovato online o ponevano vincoli al problema, come i due punti alla stessa altezza, o davano per scontate certe informazioni, come l’angolo con cui parte la corda, che qui non erano disponibili: si conoscono solo il punto iniziale e quello finale della corda, e la sua lunghezza. Wikipedia fornisce molte informazioni sulle equazioni della catenaria, ed è da lì che sono partito. L’equazione della catenaria è:y=a\cosh \left (\frac{x}{a} \right )=\frac{a\left ( e^{\frac{x}{a}}+e^{-\frac{x}{a}} \right )}{2}
Questo presuppone che il punto più basso della corda sia dove attraversa l’asse y. In pratica, alle variabili x e y si aggiungono delle costanti, entrambe ancora da determinare, perché non sappiamo dove sarà il punto più basso: è uno dei motivi per cui il problema è più complicato di tutti gli esempi dei libri di testo. (Avete notato che i problemi di matematica della vita reale sono sempre molto più complicati degli esempi dei libri? Aspetto ancora il problema reale con un integrale risolvibile analiticamente.) Ma questo dovrà aspettare, perché prima bisogna determinare il valore di a, la costante dell’equazione che decide in sostanza quanto la curva è stretta o larga. Attenzione: se i punti si trovano nella stessa posizione sull’asse x, a sarà infinito, quindi questo caso va gestito prima di arrivare qui, così come il caso in cui sono molto vicini e a è incalcolabilmente grande. (Tenete presente che «incalcolabilmente grande» qui indica qualsiasi numero che, usato come argomento della funzione esponenziale, le farebbe restituire NaN o infinito con la precisione in virgola mobile che state usando.) E naturalmente evitate che il codice arrivi fin qui se i due punti sono più lontani della lunghezza della corda: il risultato sarebbe pessimo.
Calcolare il fattore di scala
Per calcolare a, Wikipedia fornisce l’equazione (basata su una proprietà della catenaria: mentre cosh dà la posizione della curva, sinh ne dà la lunghezza):\sqrt{s^{2}-v^{2}}=2a\sinh \left ( \frac{h}{2a} \right )
dove s è la lunghezza della corda, e h e v sono le distanze orizzontale e verticale (in valore assoluto) tra il punto iniziale e quello finale. Sono tutti valori noti, quindi resta una sola incognita, che però va trovata numericamente. All’inizio ho provato senza badare troppo al valore iniziale, e la convergenza era una questione di fortuna. Per fortuna si scopre che è facile trovare un buon valore iniziale. La serie di Taylor del seno iperbolico è:
\sinh x=x+\frac{x^{3}}{3!}+\frac{x^{5}}{5!}+\cdots
Con le sostituzioni u = \frac{1}{4a^{2}} e c = \sqrt{s^{2}-v^{2}}, l’equazione da risolvere diventa:
c=\frac{1}{\sqrt{u}}\sinh \left ( h\sqrt{u} \right )
che, prendendo i primi tre termini della serie di Taylor di sinh e semplificando, dà:
c=\frac{1}{\sqrt{u}}\left (h\sqrt{u}+\frac{\left ( h\sqrt{u} \right )^{3}}{3!} +\frac{\left ( h\sqrt{u} \right )^{5}}{5!} \right )
c=\frac{1}{\sqrt{u}}\left (h\sqrt{u}+\frac{h^{3}u\sqrt{u}}{3!} +\frac{h^{5}u^{2}\sqrt{u}}{5!} \right )
c=h+\frac{h^{3}u}{3!} +\frac{h^{5}u^{2}}{5!}
che, riordinata, diventa:
\frac{h^{5}}{120}u^{2}+\frac{h^{3}}{6}u+\left ( h-c \right )=0
È una semplice equazione di secondo grado in u, e sostituendo i suoi coefficienti nella formula risolutiva imparata a scuola x = \frac{-b\pm \sqrt{b^{2}-4ac}}{2a}
si ottiene un buon valore iniziale per u e quindi per a.
u = \frac{-\frac{1}{6}h^{3}+ \sqrt{\frac{1}{36}h^{6}-\frac{1}{30}h^{5}\left ( h-c \right )}}{\frac{1}{60}h^{5}}, dove a=\frac{1}{2\sqrt{u}}
Questo valore iniziale è abbastanza vicino da trovare una soluzione con il metodo delle tangenti (metodo di Newton). Scrivendo il problema nella forma f\left ( a \right )=0
si ha f\left ( a \right )=2a \sinh \left ( \frac{h}{2a} \right )-c
e {f}'\left ( a \right )=2 \sinh \left ( \frac{h}{2a} \right )-\frac{h}{a}\cosh \left ( \frac{h}{2a} \right )
Poiché a_{n+1}=a_{n}-\frac{f\left ( a_{n} \right )}{{f}'\left ( a_{n} \right )}
,
a_{n+1}=a_{n}-\frac{2a \sinh \left ( \frac{h}{2a} \right )-c}{2 \sinh \left ( \frac{h}{2a} \right )-\frac{h}{a}\cosh \left ( \frac{h}{2a} \right )}=a_{n}-\frac{a \sinh \left ( \frac{h}{2a} \right )-0.5c}{ \sinh \left ( \frac{h}{2a} \right )-\frac{h}{2a}\cosh \left ( \frac{h}{2a} \right )}
Al momento verifico che la successione arrivi entro 0,001 dal valore precedente, cosa che di solito avviene in 2-4 iterazioni, anche se a volte ne servono più di dieci quando le coordinate x sono più vicine. Probabilmente sarebbero possibili metodi di Householder di ordine superiore senza molti più calcoli, dato che il grosso del lavoro sta nel calcolare le funzioni iperboliche, e le derivate successive della funzione dovrebbero dare solo altri multipli di queste. Ora che conosciamo la scala, possiamo calcolare la traslazione.
Calcolare la traslazione
L’equazione standardy=a\cosh \left (\frac{x}{a} \right )
presuppone che la catenaria sia simmetrica rispetto all’asse y e abbia il punto più basso in (0,a), mentre quella che disegniamo può trovarsi ovunque sullo schermo, quindi dobbiamo trovare una traslazione (p,q) che la porti nella posizione giusta, e l’equazione diventa:
y-q=a\cosh \left (\frac{x-p}{a} \right )
(Ricordiamo che a questo punto a è noto, x e y sono variabili, quindi restano incognite solo p e q.) La mia prima idea è stata sostituire nell’equazione i valori noti di x e y, cioè i due estremi della corda. In teoria funziona, ma le equazioni risultanti, nonostante i miei sforzi per semplificarle, durante i calcoli producevano spesso valori che le variabili in virgola mobile a doppia precisione non riuscivano a gestire. Alla fine ho dovuto trovare un altro approccio, che si è rivelato comunque più efficiente.
Ricordiamo che, sostituendo cosh con sinh nell’equazione della catenaria, si ottiene la lunghezza della curva. Sostituendo in questa forma le coordinate x degli estremi sinistro e destro, insieme alla lunghezza desiderata della corda (s), si ottiene l’equazione:
a\sinh \left (\frac{x_{right}-p}{a} \right )-a\sinh \left (\frac{x_{left}-p}{a} \right )=s
Una delle identità delle funzioni iperboliche afferma che:
\sinh x - \sinh y=2\cosh\left ( \frac{x+y}{2} \right ) \sinh \left ( \frac{x-y}{2} \right )
Quindi:
\sinh \left (\frac{x_{right}-p}{a} \right )-\sinh \left (\frac{x_{left}-p}{a} \right )=2\cosh\left ( \frac{x_{right}+x_{left}-2p}{2a} \right ) \sinh \left ( \frac{x_{right}-x_{left}}{2a} \right )
Nell’argomento di cosh, le coordinate x destra e sinistra vengono sommate e divise per 2, il che dà la coordinata del punto medio, quindi tanto vale sostituirla direttamente. La sottrazione nell’argomento di sinh dà lo stesso valore che prima abbiamo chiamato h, quindi anche questo sinh si calcola come quantità nota, e l’equazione originale si riordina così:
\cosh\left ( \frac{x_{middle}-p}{a} \right ) = \frac{s}{2a\sinh \left ( \frac{h}{2a}\right )}
Ora possiamo ricavare p con il settore coseno iperbolico (arcosh), ma con cautela. Poiché cosh è una funzione pari, otterremo sempre una risposta positiva, ma esiste anche una risposta negativa, quindi ci sono due possibili valori di p.
p =x_{middle}\pm a\cosh^{-1}\left ( \frac{s}{2a\sinh \left ( \frac{h}{2a}\right )} \right )
Per capire quale valore ci serve, possiamo guardare le coordinate y degli estremi. Facendo una prova con un pezzo di spago si vede che, a parità di lunghezza e di coordinate x, il punto più basso della curva (se cade tra le coordinate x) sarà a destra del centro (e quindi corrisponderà all’arcosh positivo) se la coordinata y destra è più bassa di quella sinistra, e viceversa.
Un altro problema che può presentarsi è che, quando le coordinate y sono uguali, il punto più basso della curva dovrebbe trovarsi esattamente al centro, quindi l’argomento di cosh dovrebbe essere zero e il valore di cui si prende l’arcosh dovrebbe essere uno. A causa delle imprecisioni della virgola mobile, spesso risulta leggermente minore di uno, causando un errore quando si calcola l’arcosh. Conviene controllare se le coordinate y sono uguali (o quasi) prima di iniziare questo calcolo, per risparmiare calcoli ed evitare questo errore, e in quel caso supporre semplicemente che p sia esattamente a metà strada tra gli estremi.
Ora che a e p sono noti, q si calcola sostituendo i valori di x e y di uno degli estremi nell’equazione
y-q=a\cosh \left (\frac{x-p}{a} \right )
e riordinandola così:
q=y-a\cosh \left (\frac{x-p}{a} \right )
Ricavate q da qui e avrete l’equazione finale con cui disegnare la curva.
y=a\cosh \left (\frac{x-p}{a} \right )+q
Ora disegnare la curva è semplice. Durante la maggior parte dei passaggi per calcolare i parametri ho calcolato le funzioni iperboliche con la massima precisione possibile, perché era difficile capire come si sarebbe propagata un’eventuale imprecisione. Ma in quest’ultimo passaggio, che richiede la maggior parte dei calcoli, saprete quanto è grande l’argomento che usate e quanta imprecisione potete tollerare, e potrete prevedere se una serie di Taylor fino a una certa potenza sarà abbastanza precisa; secondo la mia esperienza, il più delle volte conviene usarla.