Tecniche di manipolazione intuitiva di splines...

176
Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio Morciano Corso di Laurea in Ingegneria Elettronica Universit` a degli studi L’Aquila Anno 2001 Relatore: Prof. Gabriele Di Stefano Correlatore: Dott. Gian Marco Todesco Studente: Fabrizio Morciano

Transcript of Tecniche di manipolazione intuitiva di splines...

Page 1: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

Tecniche per la manipolazioneintuitiva di splines bidimensionali

di

Fabrizio Morciano

Corso di Laurea in

Ingegneria Elettronica

Universita degli studi L’Aquila

Anno 2001

Relatore: Prof. Gabriele Di Stefano

Correlatore: Dott. Gian Marco Todesco

Studente: Fabrizio Morciano

Page 2: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

Indice

Indice i

1 Introduzione 1

1.1 Considerazioni generali . . . . . . . . . . . . . . . . . . . 1

1.1.1 Il Progetto Paperless . . . . . . . . . . . . . . . . 1

1.2 Struttura della tesi . . . . . . . . . . . . . . . . . . . . . 2

2 Il mondo dell’animazione 4

2.1 Fasi di sviluppo . . . . . . . . . . . . . . . . . . . . . . . 4

2.2 La presenza del digitale . . . . . . . . . . . . . . . . . . . 7

2.3 L’animazione 3D . . . . . . . . . . . . . . . . . . . . . . 9

2.4 L’animazione mista . . . . . . . . . . . . . . . . . . . . . 10

3 Il progetto Paperless 12

3.1 Obiettivi . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

3.2 Tecnologie . . . . . . . . . . . . . . . . . . . . . . . . . . 13

3.2.1 Acquisizione dell’input da un dispositivo digitale . 14

3.2.2 Vettorializzazione di immagini raster . . . . . . . 15

3.2.3 Inbetweening . . . . . . . . . . . . . . . . . . . . 17

3.2.4 Colorazione e colorazione automatica . . . . . . . 17

4 Stato dell’arte 20

4.1 Manipolare una curva . . . . . . . . . . . . . . . . . . . . 20

4.2 Tecnologie e limiti . . . . . . . . . . . . . . . . . . . . . 21

i

Page 3: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

INDICE INDICE

5 Curve di Bezier e splines 25

5.1 Curve di Bezier e splines . . . . . . . . . . . . . . . . . 25

5.1.1 Generalita . . . . . . . . . . . . . . . . . . . . . . 25

5.1.2 Curve di Bezier . . . . . . . . . . . . . . . . . . . 27

5.1.3 Spline e curve di Bezier . . . . . . . . . . . . . . 32

5.2 L’algoritmo di de Casteljau . . . . . . . . . . . . . . . . . 38

5.3 Calcolo della distanza minima tra una curva ed un punto

del piano . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

5.3.1 Risoluzione con la proprieta dell’involucro convesso 40

5.3.2 Risoluzioni con i polinomi di Bezier . . . . . . . . 41

5.4 Curvatura . . . . . . . . . . . . . . . . . . . . . . . . . . 44

5.4.1 Riferimento di Frenet . . . . . . . . . . . . . . . . 46

5.4.2 Algoritmi per il calcolo della curvatura . . . . . . 48

6 Utilizzo e progetto di tecniche di manipolazione 51

6.1 Gli strumenti . . . . . . . . . . . . . . . . . . . . . . . . 51

6.1.1 Strumenti di disegno . . . . . . . . . . . . . . . . 52

6.1.2 Strumenti di manipolazione . . . . . . . . . . . . 54

6.1.3 Strumenti per il controllo della visualizzazione . . 58

6.2 Gli Algoritmi . . . . . . . . . . . . . . . . . . . . . . . . 59

6.2.1 Ricerca di una curva . . . . . . . . . . . . . . . . 60

6.2.2 Suddivisione di una curva in tratti di lunghezza

fissata . . . . . . . . . . . . . . . . . . . . . . . . 61

6.2.3 Minimizzazione del numero di curve di una linea . 62

6.2.4 Taglio e rotazione . . . . . . . . . . . . . . . . . . 68

7 Il programma Fasped 71

7.1 Il programma Fasped . . . . . . . . . . . . . . . . . . . . 71

7.2 La struttura delle classi per l’interfaccia . . . . . . . . . 72

7.2.1 fbGrOb . . . . . . . . . . . . . . . . . . . . . . . 72

7.2.2 fbWindow . . . . . . . . . . . . . . . . . . . . . . 74

ii

Page 4: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

INDICE INDICE

7.2.3 fbFasped . . . . . . . . . . . . . . . . . . . . . . . 74

7.3 La struttura delle classi dei tools . . . . . . . . . . . . . 75

7.3.1 fbTool . . . . . . . . . . . . . . . . . . . . . . . . 75

7.3.2 fbCursor . . . . . . . . . . . . . . . . . . . . . . . 76

7.3.3 fbFrameManager . . . . . . . . . . . . . . . . . . 76

7.4 La struttura delle classi per la grafica . . . . . . . . . . . 76

7.4.1 fbFrame . . . . . . . . . . . . . . . . . . . . . . . 77

7.4.2 fbPolyLine . . . . . . . . . . . . . . . . . . . . . . 77

7.4.3 fbCurve . . . . . . . . . . . . . . . . . . . . . . . 77

7.5 La struttura delle classi per l’analisi numerica . . . . . . 80

7.5.1 fbPoint . . . . . . . . . . . . . . . . . . . . . . . . 80

7.5.2 fbStraightLine . . . . . . . . . . . . . . . . . . . . 81

7.5.3 fbVector . . . . . . . . . . . . . . . . . . . . . . . 81

7.5.4 fbMatrix . . . . . . . . . . . . . . . . . . . . . . . 81

7.5.5 fbOperation . . . . . . . . . . . . . . . . . . . . . 82

8 Lavori futuri 83

8.1 Line Library . . . . . . . . . . . . . . . . . . . . . . . . . 83

8.2 Feature del disegno . . . . . . . . . . . . . . . . . . . . . 83

A Appendice A 85

A.1 Codice Sorgente . . . . . . . . . . . . . . . . . . . . . . . 85

A.1.1 fbArrow . . . . . . . . . . . . . . . . . . . . . . . 85

A.1.2 fbAutoSwitch . . . . . . . . . . . . . . . . . . . . 86

A.1.3 fbBender . . . . . . . . . . . . . . . . . . . . . . . 86

A.1.4 fbBSpline . . . . . . . . . . . . . . . . . . . . . . 88

A.1.5 fbCircle . . . . . . . . . . . . . . . . . . . . . . . 90

A.1.6 fbClamp . . . . . . . . . . . . . . . . . . . . . . . 91

A.1.7 fbConfig . . . . . . . . . . . . . . . . . . . . . . . 93

A.1.8 fbCursor . . . . . . . . . . . . . . . . . . . . . . . 95

A.1.9 fbCurve . . . . . . . . . . . . . . . . . . . . . . . 96

iii

Page 5: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

INDICE INDICE

A.1.10 fbDrawingPin . . . . . . . . . . . . . . . . . . . . 100

A.1.11 fbEllipse . . . . . . . . . . . . . . . . . . . . . . . 101

A.1.12 fbException . . . . . . . . . . . . . . . . . . . . . 102

A.1.13 fbFasped . . . . . . . . . . . . . . . . . . . . . . . 103

A.1.14 fbFrameManager . . . . . . . . . . . . . . . . . . 106

A.1.15 fbFrame . . . . . . . . . . . . . . . . . . . . . . . 106

A.1.16 fbFunction . . . . . . . . . . . . . . . . . . . . . . 108

A.1.17 fbGeometric . . . . . . . . . . . . . . . . . . . . . 111

A.1.18 fbGeoObj . . . . . . . . . . . . . . . . . . . . . . 111

A.1.19 fbGrOb . . . . . . . . . . . . . . . . . . . . . . . 112

A.1.20 fbLoader . . . . . . . . . . . . . . . . . . . . . . . 116

A.1.21 fbMath . . . . . . . . . . . . . . . . . . . . . . . . 117

A.1.22 fbOperation . . . . . . . . . . . . . . . . . . . . . 128

A.1.23 fbPan . . . . . . . . . . . . . . . . . . . . . . . . 137

A.1.24 fbPencil . . . . . . . . . . . . . . . . . . . . . . . 138

A.1.25 fbPen . . . . . . . . . . . . . . . . . . . . . . . . 139

A.1.26 fbPointManipulator . . . . . . . . . . . . . . . . . 140

A.1.27 fbPoint . . . . . . . . . . . . . . . . . . . . . . . . 141

A.1.28 fbPolyLine . . . . . . . . . . . . . . . . . . . . . . 145

A.1.29 fbPotential . . . . . . . . . . . . . . . . . . . . . . 149

A.1.30 fbRectangle . . . . . . . . . . . . . . . . . . . . . 150

A.1.31 fbSaver . . . . . . . . . . . . . . . . . . . . . . . . 151

A.1.32 fbSelector . . . . . . . . . . . . . . . . . . . . . . 151

A.1.33 fbStraightLine . . . . . . . . . . . . . . . . . . . . 152

A.1.34 fbSubSelector . . . . . . . . . . . . . . . . . . . . 154

A.1.35 fbTool . . . . . . . . . . . . . . . . . . . . . . . . 155

A.1.36 fbTriangle . . . . . . . . . . . . . . . . . . . . . . 157

A.1.37 fbUtil . . . . . . . . . . . . . . . . . . . . . . . . 157

A.1.38 fbVisitAndChangeColor . . . . . . . . . . . . . . 159

A.1.39 fbVisitAndChangeDesignAspect . . . . . . . . . . 160

iv

Page 6: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

INDICE INDICE

A.1.40 fbVisitAndChangeTolerance . . . . . . . . . . . . 161

A.1.41 fbVisitAndChangeVisibility . . . . . . . . . . . . 161

A.1.42 fbVisitor . . . . . . . . . . . . . . . . . . . . . . . 162

A.1.43 fbWindow . . . . . . . . . . . . . . . . . . . . . . 163

Bibliografia 166

v

Page 7: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

Ringraziamenti

Numerose sono le persone che mi sento di ringraziare per questo lavo-

ro. Per primo ringrazio il Dott. Gian Marco Todesco (mentore prezioso,

prodigo di ottimi consigli), per aver seguito e supervisionato quanto rea-

lizzato; ringrazio il Prof. Gabriele Di Stefano e l’Ing. Vincenzo Vennarini

per le correzioni suggeritemi; ringrazio Francesca per gli splendidi disegni

utilizzati negli esempi dei tool e lo stuff di Digital Video per la cortesia

e l’assistenza accordatami; ringrazio inoltre Francesca, Emiliana, Franco

ed Andrea per il supporto che mi hanno fornito per il completamento di

questa tesi.

Page 8: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

a Emiliana e Franco

Page 9: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

Capitolo 1

Introduzione

1.1 Considerazioni generali

L’animazione e un vasto mondo che racchiude al suo interno molteplici

forme di espressioni grafiche come: i films di animazione, i video-giochi, le

animazioni per il Web. Lo sviluppo di una qualsiasi di queste espressioni,

richiede un lavoro lungo e specialistico. Nasce la necessita di avvalersi di

strumenti che siano di aiuto sia per innovare un contesto classico, sia per

velocizzare i tempi di realizzazione. Il contesto di cui ci interesseremo,

sara quello dei film di animazione bidimensionali (cel animation). Gli

strumenti richiesti possono essere offerti dalla Computer Graphics, adat-

tando le tecniche esistenti ad uno specifico campo o, soprattutto, svilup-

pando nuove tecniche da abbinare a dispositivi di interazione innovativi,

come nel progetto Paperless.

1.1.1 Il Progetto Paperless

Paperless e un Progetto Europeo, che ha come scopo la realizzazione di

uno strumento software di supporto allo sviluppo di films di animazione

2D. Paperless e basato sulla combinazione di tool user friendly, con di-

1

Page 10: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

1. INTRODUZIONE

spositivi di interazione innovativi. Questa tesi, si prefigge di sviluppare

dei tools, da utilizzare nell’ambito di tale progetto.

Modulo di disegno

In Paperless, e previsto che venga realizzato un modulo, in cui sia pos-

sibile il disegno del fotogramma di un personaggio direttamente su uno

schermo a cristalli liquidi. Questo disegno sara composto da un insie-

me di pennellate (strokes). Il nostro compito sara di fornire dei tools,

necessari alla manipolazione di strokes, dall’utilizzo facile e dal risultato

intuitivo.

La facilita d’uso risulta necessaria in quanto stiamo realizzando uno

strumento che non sara dedicato ad un utente che abbia dimestichezza

con l’utilizzo di computer. Inoltre, il numero di linee presenti in un

disegno e molto grande e manipolarle rispettando alcune condizioni (come

la continuita) risulterebbe difficile e noioso.

D’altra parte, rispetto agli strumenti offerti da un convenzionale siste-

ma CAD1 (che permettono il controllo accurato dei parametri descriventi

il modello matematico del disegno), quelli da noi proposti agiscono come

metafora del mondo reale. I modelli da noi impiegati descrivono det-

tagliatamente come il tool deve realizzare la manipolazione, senza che

l’utente abbia la necessita di controllare ogni parametro.

1.2 Struttura della tesi

Nei capitoli successivi tratteremo i seguenti argomenti:

• nel Capitolo 2 forniremo una breve introduzione al mondo dell’a-

nimazione 2D, descrivendo le fasi di realizzazione di un film di

animazione ed il ruolo del digitale;

1Computer Aided Design

2

Page 11: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

1. INTRODUZIONE

• nel Capitolo 3 parleremo in modo piu esteso del progetto Paperless,

quali sono i suoi obiettivi e qual e stato, nel suo ambito, il nostro

ruolo;

• nel Capitolo 4 esporremo lo stato dell’arte sulla manipolazione

di immagini bidimensionali, indicando quali tecniche risultano piu

indicate al nostro caso;

• nel Capitolo 5 tratteremo la teoria relativa alle curve di Bezier ed

alle splines, fornendo le descrizioni matematiche delle tecniche di

manipolazione introdotte nel 4;

• nel Capitolo 6 analizzeremo le tecniche ed i tools realizzati, spie-

gandone l’utilizzo e gli algoritmi;

• nel Capitolo 7 presenteremo il codice dell’ambiente di test che

abbiamo realizzato;

• in Appendice allegheremo le linee di codice piu significative.

3

Page 12: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

Capitolo 2

Il mondo dell’animazione

Il mondo dell’animazione, in questi ultimi anni, sta subendo dei cam-

biamenti profondi. Come in molti altri campi, il computer si integra o

sostituisce le tecniche tradizionali e diventa un potente aiuto. In questo

capitolo, esporremo le fasi per la realizzazione di un film di animazione

in modo tradizionale ed i cambiamenti portati dall’utilizzo del computer.

2.1 Fasi di sviluppo

Lo sviluppo di un film di animazione prevede la realizzazione di uno story-

board (una serie di disegni in cui viene scomposta la sceneggiatura). Una

volta realizzato lo storyboard, e fatte eventuali correzioni alla sceneggia-

tura, si procede con la registrazione della colonna sonora. La colonna

sonora deve essere incisa prima, perche e necessaria alla sincronizzazione

tra disegno e parlato. Lo strumento su cui si basa la produzione di un

film, e il foglio macchina (Fig. 2.1). Il foglio macchina e una griglia, dove,

in verticale, abbiamo l’asse dei tempi e, in orizzontale, un insieme di celle

in cui sono inseriti i numeri che identificano i disegni. Ogni fotogramma

del film, sara ottenuto dalla sovrapposizione dei disegni indicati nelle cel-

le orizzontali (vedremo in seguito, come cio sia possibile). Sull’asse dei

tempi viene inserito il testo delle parole (ricavato dalla colonna sonora)

4

Page 13: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

2. IL MONDO DELL’ANIMAZIONE

Figura 2.1: Foglio macchina

che competera a quella scena e questo permette la gia citata sincroniz-

zazione tra il parlato ed il disegno. Nel foglio macchina possono essere

aggiunte ulteriori indicazioni, quali, ad esempio, quelle per il movimento

della camera.

Ora gli animatori sono pronti a realizzare le scene principali di un’a-

nimazione; per le quali si realizza un modello di animazione (delle bozze

di studio, usate come “modello” per i movimenti di ogni personaggio).

Per realizzazioni di qualita, un personaggio puo essere animato me-

diante una tecnica detta rotoscoping. Il rotoscoping sfrutta i movimenti

di un attore umano: questo viene filmato, i fotogrammi vengono stampa-

ti su carta e vengono utilizzati dagli animatori come guida per muovere

in modo piu realistico un personaggio.

In ogni caso, i movimenti vengono scomposti in una serie di fotogram-

mi, la cui rapida successione realizza l’animazione vera e propria. Perche

l’occhio umano non avverta il passaggio da uno all’altro, e opportuno

usare almeno 24 fotogrammi (frames) ogni secondo. Questi disegni sono

5

Page 14: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

2. IL MONDO DELL’ANIMAZIONE

realizzati da una gerarchia di animatori ed intercalatori: i primi realizza-

no le scene “chiave” (i key frames), quelle con le posizioni iniziali e finali

di un personaggio (character); i secondi provvedono a disegnare le scene

intermedie (gli inbetweens). Le tavole sono poco differenti l’una dall’altra

e per realizzazione di basso costo si puo allora decidere di utilizzare lo

stesso frame piu volte (se ripetuto due volte, parleremo di animazioni a

passo-2 , altrimenti si parlera di animazione a passo-1). Una volta rea-

lizzati i frames, viene effettuato il pencil test (l’animazione delle matite),

mediante il quale si controlla che l’animazione risulti fluida e che non

ci sia una grossa discrepanza tra le pennellate delle varie tavole. Se il

test non viene superato, si decide quali disegni devono essere sostituiti,

aggiunti o rimossi. Una volta che siano state completate le modifiche,

le tavole sono nuovamente testate, ripetendo il procedimento, finche non

si ottiene il risultato voluto. A questo punto, i disegni realizzati devo-

no essere copiati su lucido (cels), inchiostrati (a questo provvedono gli

inchiostratori) e colorati. La colorazione e realizzata a mano ed i colori

sono piatti (omogenei e privi di sfumature). Ad ogni personaggio viene

associata una palette di colori (il color model) valida lungo tutto il film ed

evita che abbia un colore diverso in scene differenti. Vengono inoltre rea-

lizzati gli sfondi e, quando tutte le tavole sono pronte, si puo cominciare

la fase di registrazione. Per ogni fotogramma si prendono i disegni neces-

sari (che sono individuati dal numero sulla riga del foglio macchina) e si

dispongono su un opportuno dispositivo per la registrazione detto rostro

(Fig. 2.2).

Il rostro si compone di:

• una camera, posta in cima ad una struttura piramidale e perpen-

dicolare ai piani sottostanti;

• una serie di vassoi trasparenti (trasparent trays), tutti fra loro

paralleli, in cui possono essere inseriti i lucidi;

6

Page 15: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

2. IL MONDO DELL’ANIMAZIONE

Figura 2.2: Schema di un rostro

• uno sfondo fisso, in cui viene posto il disegno che realizza la sceno-

grafia del fotogramma.

La camera puo effettuare tutti i movimenti che la mantengono perpendi-

colare al piano (puo traslare e zoomare); i disegni, anche se sono vincolati

a rimanere sul vassoio, possono essere traslati o ruotati, solo per lo sfon-

do non sono possibili movimenti. Il vantaggio di utilizzare una struttura

di questo genere e che permette di associare uno (o piu) vassoi ad un

personaggio. Le animazioni in cui il personaggio muove solo una parte

del corpo (come quelle del parlato, in cui tipicamente muove solo la boc-

ca), possono essere suddivise tra due livelli: uno in cui viene mantenuta

la sagoma del personaggio; l’altro in cui viene animata la parte mobile.

In questa fase e anche possibile inserire qualche effetto, mediante luci,

cambio di lente, ecc.. Il limite fisico, al numero di livelli consentiti, e

costituito dalla trasparenza del lucido, infatti, all’aumentare del numero

di tavole sovrapposte, quelle che si trovano in secondo piano perdono di

definizione.

2.2 La presenza del digitale

Nel paragrafo precedente e stata descritta la maniera tradizionale di

realizzare un film di animazione. Oggi, grazie alle nuove tecnologie, il

7

Page 16: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

2. IL MONDO DELL’ANIMAZIONE

digitale interviene praticamente in tutte le fasi della lavorazione.

La realizzazione dello storyboard utilizza il digitale per una prima

valutazione delle animazioni e del sonoro. Si puo animare una scena

senza necessariamente arrivare a registrare su pellicola, questo semplifica

le correzioni e gli indispensabili aggiustamenti.

La registrazione della colonna sonora, come abbiamo visto, e effettua-

ta prima dello sviluppo dei disegni, per permettere la sincronizzazione tra

parlato e disegno. L’utilizzo del digitale, in questa fase, permette di rico-

noscere automaticamente il parlato, ricavando i fonemi che sono trascritti

nel foglio macchina e di associare tali fonemi con i frames che rappresen-

tano le posizioni della bocca di un personaggio. In quest’ultimo caso,

la sincronizzazione riutilizza i frames dell’animazione del parlato (mouth

shapes) in varie parti del film, senza che sia necessario ridisegnarli.

I disegni, dopo essere stati disegnati su carta, sono scannerizzati per

poter essere utilizzati in un contesto digitale. La scannerizzazione deve

essere realizzata in modo da evitare gli effetti di seghettatura, derivan-

ti da una bassa risoluzione; per questo viene spesso effettuata, con una

risoluzione che sia superiore rispetto a quella richiesta per le fasi suc-

cessive. Alcuni software permettono inoltre di vettorializzare il disegno

(parleremo piu estesamente in seguito di quale siano i vantaggi di questa

operazione). Le immagini, vengono esaminate per la rimozione di even-

tuali disturbi o imperfezioni che siano state introdotte nel processo di

digitalizzazione.

In seguito si puo procedere alla colorazione. Grazie ad opportuno

software, vengono individuate le regioni chiuse, che possono cosı essere

colorate sfruttando dei tools specializzati. Alcuni sistemi di animazione

computerizzata, permettono anche la colorazione automatica: zone di

disegno, che in tavole succesive risultano quasi allineate, possono essere

riempite dallo stesso colore utilizzato nella tavola in cui si sta lavorando.

Il foglio macchina e naturalmente rimpiazzato dal suo equivalente di-

8

Page 17: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

2. IL MONDO DELL’ANIMAZIONE

gitale, il cui utilizzo permette di facilitare la composizione delle immagini

per la fase di registrazione.

Il modello della camera utilizzato e ancora verticale, ma la sovrap-

posizione dei disegni e gestita utilizzando l’alpha-blending. Con tale de-

nominazione si indicano quelle tecniche che, oltre ad utilizzare il colore

(specificato per mezzo dell’intensita delle sue componenti di base rosso

verde e blu, R[ed]G[reen]B[lue]), sfruttano un campo alpha che ne indica

l’opacita, permettendo di sovrapporre diversi disegni e di realizzare effet-

ti di trasparenza. Come nel caso tradizionale, la camera non e fissa, sono

possibili tutti i movimenti che la mantengono perpendicolare ai piani in

cui sono poste le tavole (zoom, rotazioni, panoramiche, ecc.) ed, analo-

gamente, e possibile sia ruotare che traslare le tavole; inoltre, possiamo

aggiungere un vasta gamma di effetti speciali).

La registrazione permette infine di riversare il film sul supporto desi-

derato.

2.3 L’animazione 3D

Negli ultimi 20 anni la computer graphics ha permesso di fornire agli

animatori nuovi personaggi, non piu disegnati, ma modellati tridimen-

sionalmente. Accenniamo brevemente alla realizzazione di un film di

animazione tridimensionale.

In questo caso, i personaggi sono realizzati sfruttando dei programmi

software chiamati modellatori (qualche volta le sagome dei personaggi

possono essere prima scolpite su opportuni materiali e poi acquisite con

scanner tridimensionali). In questa fase (detta modelling), ad ogni model-

lo sono applicate le caratteristiche fisiche e cinematiche che lo caratteriz-

zeranno (come il colore, l’elasticita, i vincoli da rispettare nel movimento

di ogni sua parte, ecc.).

Sempre nel modelling si definiscono sia l’animazione (fase di anima-

9

Page 18: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

2. IL MONDO DELL’ANIMAZIONE

tion, dove si scelgono le pose chiave e si lascia che un software specializ-

zato si occupi dell’inbetweening), sia le proprieta dei materiali (che dei

programmi detti shaders, sfruttano per la fase di shading). Nello shading

e possibile riprodurre una grande varieta di materiali (come legno, stoffa,

metallo, capelli).

Si puo poi passare all’illuminazione, dove vengono definiti diversi con-

tributi di luce (ambiente, luci a bulbo, ecc.), necessari alla scena per

creare un umore ed un’emozione particolare (fase di lighting).

L’ultima fase e il rendering, per ogni frame sono calcolati tutti i con-

tributi (luci, ombre, riflessi, movimenti, ecc.) ed il risultato, infine, puo

essere registrato su un supporto (pellicola, DVD, ecc.).

2.4 L’animazione mista

Sempre piu spesso, il 2D ed il 3D vengono combinati in uno stesso film

di animazione.

Il 3D permette di creare gli sfondi e le animazioni su cui far muovere

i personaggi 2D, superando i limiti rappresentati dal modello a camera

verticale e rendendo l’azione piu simile a quella di un film live action (con

attori umani). A questo proposito possiamo citare, ad esempio, Anastasia

(Fox), La strada per Eldorado (DreamWorks), Titan A.E. (Fox), Tarzan

(Walt Disney).

E anche possibile sfruttare il 3D per creare personaggi da muovere in

scenari bidimensionali. Alcuni dei vantaggi che derivano da questa scelta

sono: la facilita di gestione dei movimenti del personaggio (i movimenti

sono gestiti da un programma software); la possibilita di muovere un

numero elevato di personaggi (scene di massa); la possibilita di realizzare

effetti speciali (come l’animazione dell’acqua). Riportando degli esempi

dell’utilizzo di tali tecniche possiamo citare: per il primo punto “Iron

Giant” (Warner Bros), in cui il personaggio (un robot d’acciaio alto 15

10

Page 19: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

2. IL MONDO DELL’ANIMAZIONE

metri) e gestito da un programma di modellazione e colorato con effetto

“a cartone animato”; per il secondo “Il Re Leone”, dove il computer

interviene nella carica delle antilopi, o “Hercules” (Walt Disney), dove

il digitale interviene nella gestione dei movimenti delle teste dell’Idra

di Lerna; per il terzo “La strada per Eldorado”, in questo film viene

utilizzato un sistema particellare per simulare i movimenti dell’acqua.

11

Page 20: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

Capitolo 3

Il progetto Paperless

Le fasi per lo sviluppo di un film di animazione, con tecniche tradizionali,

sono lunghe e costose. Il computer, come abbiamo visto, ha permesso

di migliorare molti aspetti, ma il suo utilizzo ha trovato poco spazio

nell’acquisizione diretta del disegno. Le tavole sono realizzate su carta

ed a mano. Un disegnatore e quindi limitato nella correzione (quando si

cancella, la carta si deteriora) e l’unica possibilita di manipolazione che

ha, e ridisegnare in modo diverso la scena o il personaggio.

L’innovazione tecnologica ci fornisce dei dispositivi, come le tavolet-

te grafiche con schermo (Fig. 3.1 a pag. 14), di cui possiamo estendere

le capacita, associandogli dei tools facili da utilizzare. Possiamo allo-

ra sfruttare l’integrazione tra tecnologia innovativa e tools user friendly,

per realizzare strumenti che facilitino il compito degli artisti e dei tecni-

ci che contribuiscono allo sviluppo di un film d’animazione (disegnatori,

intercalatori, inchiostratori).

Perseguendo l’obiettivo di fornire un ambiente di animazione avan-

zato ed integrato, la Digital Video S.r.l., ed altre aziende europee, sta

portando avanti il progetto Paperless.

12

Page 21: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

3. IL PROGETTO PAPERLESS

3.1 Obiettivi

I programmi tradizionali per il supporto dell’animazione cominciano il

loro compito subito dopo la fase di disegno a mano, permettendo la ge-

stione della scannerizzazione delle tavole. Questo passo rappresenta un

pesante limite sia per il tempo richiesto per acquisire le centinaia di mi-

gliaia di tavole necessarie, che per la limitata possibilita di modificare

quanto gia acquisito. In Paperless, questo stadio viene ad essere rimpiaz-

zato, realizzando il disegno direttamente utilizzando una speciale tavolet-

ta grafica; all’artista viene inoltre permesso di cancellare e, soprattutto,

di modificare quanto disegnato.

Cancellare un tratto di matita su un foglio di carta non e possibile

all’infinito, in quanto il supporto si deteriora e sicuramente non e facile

eliminare particolari o linee di piccole dimensioni.

La modifica di un tratto e invece qualcosa di assolutamente nuovo;

considerare i tratti come oggetti e permetterne la manipolazione, non e

fisicamente realizzabile in un contesto tradizionale.

La facilita di utilizzo e quella di manipolazione permettono a Paper-

less di aprire il mondo dell’animazione a nuove proposte come, l’anima-

zione di pagine Web o i videogiochi.

3.2 Tecnologie

Per conciliare le richieste degli utilizzatori, con gli obiettivi che si vogliono

raggiungere, il progetto dovra utilizzare diverse tecnologie, alcune nuove,

altre necessarie per l’integrazione con le attuali metodologie di sviluppo.

13

Page 22: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

3. IL PROGETTO PAPERLESS

3.2.1 Acquisizione dell’input da un dispositivo digi-

tale

Il disegno a mano libera trova il suo supporto naturale nella carta. L’e-

sperienza che si e ottenuta, nel disegno su carta, e preziosa per un dise-

gnatore e dovra essere mantenuta. Attualmente l’interazione digitale con

il disegno e possibile o dopo la scannerizzazione dei disegni o con l’acqui-

sizione da tavoletta grafica ([1], [2]). Della scannerizzazione abbiamo gia

parlato; per quello che riguarda l’acquisizione da tavoletta, l’utilizzatore

ha uno strumento simile a quello usuale (carta e matita), pero il dise-

gno non appare sotto la penna ma su un video e, spesso, il tratto non e

sensibile alla pressione che viene esercitata.

Utilizzando un display digitale ed una penna elettronica sensibile alla

pressione (Fig. 3.1), il disegnatore non deve cambiare la sua metodologia

di lavoro. Il disegno appare sul display seguendo la penna e le linee

Figura 3.1: Tavoletta Wacom

assumono uno spessore variabile in funzione della pressione esercitata.

14

Page 23: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

3. IL PROGETTO PAPERLESS

Al disegnatore viene poi fornita la liberta di manipolare il disegno, i cui

tratti non sono piu statici, ma interpretabili come oggetti, rigidi o elastici,

deformabili in modo intuitivo. Viene cosı facilitata la creazione di nuovi

frames da quelli esistenti.

Questa tesi trova la sua origine nell’introduzione di metodologie in-

tuitive per la manipolazione dei tratti e vedremo in seguito cosa e stato

proposto.

Per completezza, dobbiamo esporre qualche svantaggio derivante dal-

l’utilizzo della tavoletta. Il suo costo (una tavoletta costa quasi 5 milioni

di lire), che fino a quando non sara comparabile con i display tradizio-

nali, non la rendera immediatamente accessibile ad un vasto pubblico;

le sue dimensioni, che sono simili a quelle di un foglio di formato A4

e rendono necessaria l’implementazione di un contesto multi-risoluzione

per simulare un supporto di dimensioni maggiori; l’errore di parallasse

(che si presenta a causa dello spessore non nullo del vetro del display) e

non fa apparire il disegno esattamente sotto la penna, ma leggermente

piu in basso (questo potrebbe creare qualche difficolta per il disegnato-

re che non individua esattamente il punto iniziale della linea che va a

disegnare).

3.2.2 Vettorializzazione di immagini raster

Il passaggio ad un sistema innovativo sara graduale. Il supporto per le

tecniche esistenti dovra, necessariamente, essere mantenuto ed e per que-

sto che in Paperless e previsto il mantenimento dell’acquisizione tramite

scanner; cambia pero il formato uscente dalla scannerizzazione non piu

raster ma vettoriale.

15

Page 24: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

3. IL PROGETTO PAPERLESS

Raster vs Vettori

Su un computer e possibile memorizzare le immagini utilizzando due

diverse modalita: raster o vettoriale.

Se utilizziamo una modalita raster, possiamo pensare di sovrapporre

all’immagine una griglia rettangolare composta di celle quadrate. La di-

mensione di un’immagine sara data dal numero totale di celle. Quanto

piu le celle saranno piccole e numerose, tanto maggiore sara la risolu-

zione finale dell’immagine. Le celle vengono chiamate pixels (dall’inglese

picture elements) e ad ogni cella verra associato il colore dell’immagine.

Memorizzando tale informazione, il risultato che otterremo e una matrice

costituita da pixels.

Se utilizziamo una modalita vettoriale, possiamo pensare di fissare un

sistema di coordinate solidale con il disegno (lo chiameremo world coor-

dinates, coordinate mondo)1. Una volta scelte le primitive matematiche

a cui ricondurre ogni tratto del disegno (linee, cerchi, curve, ecc.), pos-

siamo memorizzarne i parametri (ad esempio un cerchio viene espresso

come raggio e centro). Il risultato che si ottiene e una lista di primitive

con i parametri necessari a identificarle univocamente.

Gli svantaggi derivanti dall’utilizzo di un formato vettoriale, posso-

no essere ricondotti alla necessita di operare una conversione nella fase

di visualizzazione; questo, in quanto i dispositivi di output attualmen-

te disponibili, sfruttano una tecnologia di tipo raster (sono capaci di

visualizzare efficientemente delle immagini di tipo raster).

I vantaggi di un formato vettoriale sono: permette un controllo asso-

luto delle primitive (al contrario di un formato raster in cui,conoscendo

solo il colore, non sappiamo nulla, circa quello che e rappresentato); ha

la possibilita di operare con funzioni continue e non con elementi finiti e

discreti come i pixels; e indipendente dalla risoluzione; occupa poca me-

1Il sistema world coordinates verra ricondotto al sistema window coordinatessolidale con la finestra della nostra applicazione

16

Page 25: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

3. IL PROGETTO PAPERLESS

moria, rendendolo adatto per il Web. Quest’ultimo aspetto permette di

effettuare le operazioni di zoom o di rotazione senza degrado di qualita.

3.2.3 Inbetweening

L’inbetweening e la realizzazione dei frames intermedi di un’animazione, a

partire da due posizioni chiave di un personaggio. Come accennato nel ca-

pitolo relativo al mondo dell’animazione, la realizzazione degli inbetweens

e delegata ad una gerarchia di animatori ed intercalatori che dovranno

realizzare numerose tavole molto simili tra loro. Per facilitare questa fa-

se, sono stati, quindi, realizzati dei sistemi automatici di inbetweening.

Questi sistemi hanno bisogno della presenza di un supervisore umano che

associ le curve corrispondenti in due frames chiave. Dopo questa fase, il

programma che realizza l’algoritmo d’inbetweening, e in grado di inserire

gli ulteriori frames, necessari al completamento dell’animazione.

In Paperless e previsto lo sviluppo di un algoritmo d’inbetweening. Il

nostro lavoro potrebbe essere utilizzato in tale fase, permettendo all’ani-

matore di applicare la manipolazione su di un frame, in modo progressivo

(memorizzando ogni passo intermedio) e considerando la successione di

frames ottenuta come gli inbetweens. In tal modo sara lo stesso animato-

re a realizzare e valutare l’animazione e non l’operatore che associa curva

a curva.

3.2.4 Colorazione e colorazione automatica

Colorazione

La realizzazione tramite programmi software della colorazione (fase in cui

vengono colorate le tavole), comporta la risoluzione di alcuni problemi

direttamente collegati al formato dell’immagine da colorare.

Il primo problema e la definizione di regione, cioe della zona limitata

di disegno che deve essere colorata. In ambito raster, si definisce regione

17

Page 26: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

3. IL PROGETTO PAPERLESS

un insieme di pixels dello stesso colore. La colorazione, comportera di

cambiare il colore di tutti i pixels della regione, con quello desiderato;

per far questo esistono degli algoritmi di campitura ben noti (algoritmi

di fill) su cui non ci soffermeremo.

La definizione di regione precedentemente data non vale nel caso d’im-

magini vettoriali. In immagini vettoriali, una regione viene definita come

una zona del piano racchiusa da curve; per una regione non e, allora,

noto il numero di curve che la racchiudono e non e detto che curve molto

vicine si incontrino in un punto, permettendo la chiusura. Il riconosci-

mento di una regione chiusa e stato trattato e risolto per Paperless da

[3] in un precedente lavoro di tesi; e previsto che la chiusura automatica

di regioni “quasi” chiuse verra implementata in Paperless.

Colorazione automatica

Un’animazione si compone di molte tavole che devono essere colorate.

Visto che queste sono poco differenti l’una dall’altra, si potrebbe uti-

lizzare un opportuno programma che permetta di colorare regioni della

prima tavola, gestendo automaticamente la colorazione della stessa re-

gione nelle tavole successive. Un programma di questo genere si basa

su un algoritmo di colorazione automatica. La colorazione automatica e

resa difficile da diversi problemi: si deve riconoscere una regione in una

tavola; la regione, che durante l’animazione puo essere stata modificata,

deve essere individuata nelle tavole successive. In Paperless e previsto

lo sviluppo di un modulo che permetta la colorazione automatica. Que-

sto modulo si potra avvantaggiare delle informazioni fornite dal modulo

di inbetweening. Partendo dall’idea che, una volta stabilita una corri-

spondenza curva a curva tra due tavole successive, il colore delle linee e

delle regioni resta individuato, e possibile (in linea di principio) colorare

le tavole interpolanti utilizzando le informazioni di colore associate alla

prima. Il modulo di inbetweening si occupera, allora, di associare curva a

18

Page 27: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

3. IL PROGETTO PAPERLESS

curva, mentre quello di colorazione aggiungera il colore negli inbetweens

via via generati.

19

Page 28: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

Capitolo 4

Stato dell’arte

4.1 Manipolare una curva

In Paperless e previsto un modulo di disegno che permetta la manipo-

lazione intuitiva di strokes.

Una stroke verra rappresentata con un’opportuna equazione mate-

matica; in questa equazione saranno presenti dei parametri (strettamen-

te collegati alla forma assunta dalla stroke) che chiameremo punti di

controllo1. La manipolazione diretta dei punti di controllo, permette al-

l’utente di avere la padronanza assoluta della forma assunta dalla curva,

ma operare sui punti di controllo, richiede la conoscenza dell’equazione

che descrive la curva e non risulta una scelta indicata per chi non e esper-

to. Inoltre, visto che il numero di curve che possono essere presenti in

un disegno e elevato, lo spostamento dei punti di controllo risulterebbe

estremamente noioso e difficile.

Il nostro approccio, quindi, e stato quello di cercare una metafora

del mondo reale. Se riconduciamo la manipolazione di una curva alla

manipolazione di un oggetto (come il filo del telefono, il tubo da giardino,

le molle, gli elastici, ecc.), il risultato che ci si aspetta sara quello derivato

1Parleremo piu estesamente dell’aspetto matematico nel capitolo 5.

20

Page 29: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

4. STATO DELL’ARTE

dall’esperienza quotidiana. Questa scelta comporta che non c’interessa

avere un controllo assoluto di ogni parametro (come nel caso di un utente

che utilizzi un CAD tecnico), ma avere un sistema che risponda in modo

coerente ad un modello.

Esaminiamo lo stato dell’arte, circa la manipolazione di curve bi-

dimensionali, analizzando alcuni programmi gia esistenti e le tecniche

proposte in letteratura.

4.2 Tecnologie e limiti

I programmi di manipolazione attualmente disponibili, oltre a fornire

avanzate funzioni di editing per le curve, permettono un controllo esat-

to della posizione dei punti di controllo; fra i piu noti possiamo citare

Flash[4] (vedere Fig. 4.1), o XFig[5] (vedere Fig. 4.2).

XFig fornisce molti strumenti per lo spostamento dei punti di con-

trollo e risulta piu indicato per un utente esperto.

Flash2, permette la manipolazione diretta di curve, ma l’utente non

ha la possibilita di muovere esattamente il punto selezionato, come vedia-

mo in Fig. 4.1,in cui, durante lo spostamento, il cursore si e allontanato

dal punto della curva.

Anche in letteratura sono stati proposti molti lavori per la risoluzione

del problema di manipolazione.

In [6] viene sviluppato un editor vettoriale, viene proposto un metodo

di manipolazione basato sulle wavelets. Questo metodo deriva da tecniche

usate nel trattamento dei segnali. I punti di controllo di una curva sono

visti come campioni di un segnale, tale segnale puo allora essere trattato

con dei filtri. I filtri consentono di modificare l’aspetto ed il carattere di

una linea.

2Prodotto della Macromedia e standard de facto per quello che riguarda la graficasu Web.

21

Page 30: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

4. STATO DELL’ARTE

Figura 4.1: Un esempio di utilizzo di Flash versione 4.0.

Figura 4.2: Una esempio di utilizzo di Xfig.

22

Page 31: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

4. STATO DELL’ARTE

Con aspetto, si intende la forma complessiva della curva e modifi-

candolo, possiamo effettuare la manipolazione di zone rappresentate da

curve con parametrizzazione particolare, o ottenere una versione meno

precisa, utile nel caso di stampa con bassa risoluzione (Fig. 4.3).

Figura 4.3: L’aspetto della linea viene variato, senza cambiarne ilcarattere.

Con carattere, si intende la forma del tratto con cui e realizzata la

curva; permetterne la modifica consente di realizzare una libreria di forme

possibili, da utilizzare sulla linea a video (Fig. 4.4).

Figura 4.4: Il carattere della curva viene variato, senza cambiarnel’aspetto.

L’utilizzo delle wavelets comporta, pero, delle difficolta di trattamento

in linee con discontinuita (caso frequente in disegni a mano), nonche per

operare in un contesto a risoluzione variabile (che vogliamo offrire ad un

disegnatore per correggere o migliorare dettagli).

In [7] viene proposto un approccio strettamente fisico. Come gia det-

to, la nostra idea di manipolazione deriva dagli oggetti quotidianamente

23

Page 32: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

4. STATO DELL’ARTE

utilizzati, perche allora non applicare i parametri descriventi l’elasticita,

la dimensione ecc, ad una curva per poi deformarla in funzione delle for-

ze che subisce? L’idea porta ad introdurre le tecniche agli elementi finiti

(FEM, Finit Elements Methods), queste risultano computazionalmente

onerose; il maggior limite e che non sono direttamente applicabili a curve

ma soltanto a segmenti.

In [8] troviamo una tecnica basata sulla Free Form Deformation che

permette di modificare una curva, agendo in zone del disegno, individuate

da primitive semplici (cerchi, segmenti, curve). L’azione deformante sara

funzione di un certo potenziale collegato alla primitiva. Questa tecnica

presenta un grosso problema da risolvere, le equazioni che sono utilizzate

per rappresentare le curve non sono invarianti, ne rispetto a deformazioni

prospettiche, ne rispetto a deformazioni non lineari (come quelle offerte

dalle funzioni potenziale).

Il nostro contributo alla manipolazione e presentato in questo lavoro,

dove la nostra attenzione e stata attratta dalle possibilita offerte dalle

funzioni potenziale. Grazie al loro utilizzo, abbiamo ottenuto uno stru-

mento di manipolazione nuovo che basa il suo funzionamento su quelle

che abbiamo definite funzioni di modellazione (che sono specifiche funzio-

ni potenziale); inoltre, abbiamo esteso il lavoro presentato in [8] (relativo

alla Free Form Deformation) al caso bidimensionale, rendendo possibile

utilizzare questo approccio per la manipolazione non di oggetti tridimen-

sionali ma di disegni; infine, abbiamo realizzato uno strumento inedito

che permette di piegare tratti di disegno3.

Dopo questa breve introduzione, possiamo addentrarci nel problema,

analizzando le primitive utilizzate (le splines e le curve di Bezier) e le

tecniche implementate, da un punto di vista piu strettamente matemati-

co.

3Lo strumento, il cui nome e Bender, permette anche di “stirare” le linee (vedipag. 56).

24

Page 33: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

Capitolo 5

Curve di Bezier e splines

5.1 Curve di Bezier e splines

5.1.1 Generalita

Quando abbiamo parlato dei formati raster e dei formati vettoriali 1, ab-

biamo fissato la nostra attenzione sul formato vettoriale, ma non ci siamo

soffermati sulle scelta delle primitive. In questo lavoro le primitive che

utilizzeremo saranno curve. Sorge allora la necessita di scegliere una rap-

presentazione che risulti compatta e permetta una facile manipolazione

dell’oggetto che descrive.

Una curva puo sempre essere ricondotta ad una linea spezzata, i cui

segmenti siano sufficientemente piccoli, da non dar luogo ad un effetto di

aliasing geometrico2 [9] (vedi Fig. 5.1). Descrivere una curva per mezzo

di punti e difficile, inefficiente e dispersivo, sia in termini di tempo da im-

piegare che per lo spazio di memoria da utilizzare (una buona definizione

comporta un elevato numero di punti). Sara allora preferibile utilizzare

1Si definiscono immagini raster quelle che sono descritte da una matrice di elementifondamentali detti pixels, vettoriali quelle i cui elementi sono primitive elementariquali linee, cerchi, ecc., vedi pag. 16.

2L’aliasing geometrico si presenta se riusciamo a distinguere i tratti dellapolinomiale che approssimano la curva.

25

Page 34: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

5. CURVE DI BEZIER E SPLINES

Figura 5.1: Una curva disegnata mediante tratti sempre piu numerosi.

una rappresentazione matematica che: approssimi i punti; richieda meno

informazioni da memorizzare; sia facile da gestire.

Possiamo pensare di descrivere una curva in modo esplicito. Con que-

sta scelta avremo funzioni del tipo y = f(x). Questa rappresentazione

ha pero tre svantaggi: e impossibile avere molteplici valori di y per la

stessa x (non si possono descrivere curve come cerchi ed ellissi); la ge-

stione di trasformazioni affini (come rotazioni,ecc.) richiede l’utilizzo di

classi di funzioni diverse; non e facile gestire curve con tangente verticale

(pendenza infinita della retta tangente).

Un’altra soluzione e utilizzare una rappresentazione implicita f(x, y) =

0. Anche in questo caso abbiamo qualche problema, mentre possiamo

descrivere senza difficolta cerchi ed ellissi (x2

a2 + y2

b2− c2 = 0), applicare

trasformazioni affini risulta ancora laborioso; inoltre non abbiamo la pos-

sibilita di fissare un verso per la tangente (molto utile, ad esempio, nel

calcolo delle intersezioni).

La soluzione puo essere trovata utilizzando una rappresentazione di ti-

po parametrico (x = x(t), y = y(t) dove t e il parametro). La rappresen-

26

Page 35: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

5. CURVE DI BEZIER E SPLINES

tazione parametrica non soffre delle limitazioni precedenti: la pendenza

geometrica (che puo essere infinita), e rimpiazzata dal vettore tangen-

te parametrico (che ha valori finiti); la curva puo passare piu volte per

lo stesso punto; siamo in grado di rappresentare senza difficolta cerchi,

semicerchi ed ellissi.

5.1.2 Curve di Bezier

Una curva di Bezier3, e una funzione continua b(t) ∈ <2 definita su di

un intervallo [0 ≤ t ≤ 1] ∈ < che puo essere scritta come:

b(t) =n∑

j=0

bjBnj (t). (5.1)

Nella Eq. 5.1, bj sono n + 1 punti che appartengono ad <2 e sono chia-

mati punti di controllo della curva; Bnj (t) risultano essere i polinomi di

Bernstein, definiti esplicitamente come:

Bni (t) =

n

i

ti(1− t)n−i (5.2)

con i coefficienti binomiali dati da:

n

i

=

n!

i!(n−i)!se 0 ≤ i ≤ n

0 altrimenti. (5.3)

La Eq. 5.1 rappresenta una curva di Bezier di grado n in forma

di Bernstein. Questa forma non e l’unica possibile, ma e utile per

le proprieta di cui gode che prima elencheremo e poi analizzeremo in

dettaglio:

• invarianza per trasformazioni affini;

3In seguito utilizzaremo curve bidimensionali e risultera <2, per il caso generalek-dimensionale avremmo dovuto scrivere <k.

27

Page 36: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

5. CURVE DI BEZIER E SPLINES

Figura 5.2: Esempi di curve di Bezier. Lo spostamento dei punti dicontrollo influenza la forma della curva.

• invarianza sotto trasformazioni affini del parametro;

• proprieta dell’involucro convesso;

• interpolazione dei punti finali;

• simmetria;

• invarianza per combinazioni baricentriche;

• precisione lineare;

• pseudo controllo locale.

Invarianza per trasformazioni affini

Una trasformazione Φ : <2 → <2 e detta affine se verifica:

Φ(∑

αiPi) =∑

αiΦ(Pi), (5.4)

dove αi ∈ < e Pi ∈ <2. Applicando una trasformazione affine ad una

curva di Bezier abbiamo:

Φ(b(t)) = Φ(n∑

j=0

bjBnj (t)) =

n∑j=0

Bnj (t)Φ(bj). (5.5)

28

Page 37: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

5. CURVE DI BEZIER E SPLINES

Applicare una trasformazione affine ad una curva4, significa, allora, tra-

sformare i soli punti di controllo e non ogni singolo punto della curva.

Invarianza sotto trasformazioni affini del parametro

Questo vuol dire che che l’intervallo [0, 1], del parametro t, puo essere

trasformato in [a, b] e viceversa:

n∑j=0

bjBnj (t) =

n∑j=0

bjBnj (

u− a

b− a). (5.6)

Questa proprieta permette di cambiare l’intervallo di definizione di una

curva senza cambiarne l’aspetto. L’utilizzo di questa proprieta ci per-

mette di effettuare facilmente la suddivisione di una curva in tratti di

lunghezza minore. Le curve che otteniamo risultano essere ancora curve

di Bezier il cui parametro e ricondotto a t ∈ [0, 1].

Proprieta dell’involucro convesso

Una curva di Bezier risulta sempre contenuta all’interno dell’involucro

convesso, costituito dai segmenti congiungenti i suoi punti di controllo.

Questo deriva dal fatto che i polinomi di Bernstein sono non negativi e

la loro somma risulta uguale ad 1. Il fatto che siano non negativi, nell’in-

tervallo [0, 1] di definizione, puo essere verificato analizzando il segno dei

singoli fattori della Eq. 5.7, che risultano positivi o nulli per t ∈ [0, 1]. Il

fatto che la somma dei polinomi sia 1 segue dalla definizione, infatti:

n∑i=0

n

i

(t)i(1− t)n−i = [(t) + (1− t)]n = 1. (5.7)

Una curva di Bezier e allora una combinazione lineare dei suoi punti

di controllo a coefficienti positivi e non maggiori di 1. Questa proprieta

risulta utile per operazioni di clipping, cioe, quando dobbiamo controllare

4Sono affini operazioni come lo zoom, la traslazione, la rotazione.

29

Page 38: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

5. CURVE DI BEZIER E SPLINES

se una curva e visibile o no. Nel caso in cui, tutti i punti di controllo

sono visibili, anche la curva lo sara e potra essere disegnata, viceversa,

se nessun punto e visibile, siamo sicuri che non lo sara neanche la curva.

Interpolazione dei punti finali

Essendo Bnj (0) = δj,0 e Bn

j (1) = δj,n con δj,i l’ordinaria funzione di

Kronecker e ricordando l’Eq. 5.1 segue:

b(0) =n∑

j=0

bjBnj (0) =

n∑j=0

bjδj,0 = b0, (5.8)

ed analogamente per t = 1, vediamo allora che i punti b0 e bn apparten-

gono alla curva.

Simmetria

Prendiamo una curva a(t) che sia descritta da n punti di controllo b0a ,

b1a , b(n−1)a , bna , e una curva b(t) che sia ottenuta dagli stessi punti di

controllo, presi pero in ordine inverso. Per i nuovi (che indichiamo con

pedice b) b0b, b1b

, b(n−1)b, bnb

, sara allora:

b0a = bnb,

b1a = b(n−1)b,

...,

b(n−1)a = b1b,

bna = b0b,

(5.9)

cioe:

bia = b(n−i)b. (5.10)

30

Page 39: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

5. CURVE DI BEZIER E SPLINES

Scriviamo l’equazione della curva b(t) in modo che il verso di percorrenza

sia lo stesso della curva a(t):

b(t) =n∑

j=0

bibBnn−j(1− t). (5.11)

Dall’Eq. 5.10 e dall’Eq. 5.11 abbiamo:

n∑j=0

bibBnn−j(1− t) =

n∑j=0

b(n−j)aBnn−j(1− t) (5.12)

risultando pero che:

Bnn−j(1− t) = Bn

j (t) (5.13)

ne deduciamo che:

n∑j=0

b(n−j)aBnj (1− t) =

n∑j=0

bjaBnj (t) = a(t), (5.14)

quindi le due curve sono uguali.

Invarianza per combinazioni baricentriche

In formule abbiamo:

n∑j=0

(αbj + βcj)Bnj (t) = α

n∑j=0

bjBnj (t) + β

n∑j=0

cjBnj (t), (5.15)

significa che possiamo costruire la media pesata di due curve, sia pren-

dendo la media pesata dei punti corrispondenti, sia facendo la media dei

punti di controllo e costruendo la curva. Questa proprieta risulta utile

per le superfici e non ci soffermeremo ulteriormente sopra.

31

Page 40: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

5. CURVE DI BEZIER E SPLINES

Precisione lineare

Questa proprieta comporta che risulti:

n∑j=0

j

nBn

j (t) = t. (5.16)

Possiamo allora dedurre che: se prendiamo due punti a,b e una curva di

Bezier con punti di controllo uniformemente spaziati sulla congiungente

ad a,b, la curva rappresentata sara esattamente il segmento individuato

da a,b.

Pseudo controllo locale

Dato che i polinomi di Bernstein hanno il massimo per t = in

si puo

pensare che la curva risentira di uno spostamento di un punto di con-

trollo quanto piu questo pesi (peso inteso come valore del massimo del

polinomio di Bernstein).

5.1.3 Spline e curve di Bezier

Alcuni algoritmi (come quelli di minimizzazione per un insieme di curve o

quelli d’interpolazione di un insieme di punti) sono facilmente ottenibili

sfruttando le proprieta delle spline ed e per questo che nel seguito ne

tratteremo le proprieta (in particolare delle B-spline) e vedremo come e

possibile ricondurre una B-Spline ad un insieme equivalente di curve di

Bezier.

Considerazioni generali

Le funzioni di Bezier sono un potente strumento per il disegno e la mani-

polazione di curve. Se, pero, vogliamo modellare una curva dalla forma

estremamente complessa, la rappresentazione che si ottiene utilizzando

i polinomi di Bezier risulta avere un grado troppo elevato. Possiamo

32

Page 41: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

5. CURVE DI BEZIER E SPLINES

allora pensare di utilizzare, invece di uno, un certo numero di polino-

mi di Bezier di grado minore (tipicamente grado 2 o 3). Chiameremo

curva B-spline la curva originata dall’utilizzo di tratti di curva polino-

miale di Bezier. I vantaggi che derivano da questo approccio possono

essere osservati, oltre che nell’interpolazione, anche nella manipolazione.

Nell’interpolazione: in quanto se volessimo interpolare n + 1 punti (con,

ad esempio, n ≥ 20) con un unico polinomio, questo presenterebbe un

comportamento eccessivamente oscillante che puo non essere accettabile;

mentre per una B-spline il grado e fisso e (tipicamente) basso5. Nella

manipolazione: in quanto se volessimo spostare uno dei punti interpolati

da un unico polinomio, questo spostamento si risentirebbe lungo tutta

la curva, mentre in una B-spline influenza la forma di un breve tratto

intorno al punto.

Caratteristiche e proprieta

Una spline6 e una funzione continua che trasforma ogni intervallo [ui, ui+1],

di un insieme u0 <, . . . , < uL in E2, in un tratto di curva polinomiale.

Ciascun numero reale ui e chiamato nodo e l’insieme degli intervalli e

detto sequenza dei nodi. Per ogni valore del parametro u abbiamo cosı

un corrispondente punto s(u) nella curva s. Ogni intervallo cosı definito

puo essere raffigurato da una curva di Bezier. Questo genere di rap-

presentazione e chiamato B-spline. La “B” sta per basis (base) e vuol

dire che una B-spline, puo essere rappresentata come somma pesata di

polinomi base (cosa non vera per le spline tradizionali).

Volendo descrivere una curva mediante una B-spline abbiamo bisogno

di fissare: il grado che desideriamo per la B-spline (lo indicheremo con

5A questo proposito notiamo che le B-spline godono della proprieta di minimo,sono le curve che minimizzano l’energia elastica del modello (vedi [10]), cioe sonoquelle che (a parita di grado) forniscono un’interpolazione che minimizza il quadratodell’integrale di curvatura, calcolato lungo la linea.

6In seguito con En indicheremo lo spazio euclideo n-dimensionale.

33

Page 42: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

5. CURVE DI BEZIER E SPLINES

Figura 5.3: B-spline: una B-spline cubica con i suoi punti di controllo equelli relativi alle curve di Bezier che la rappresentano

n e sara generalmente 2 o 3); un insieme di numeri reali non decrescenti

che chiameremo nodi; un insieme di punti di controllo (che indicheremo

con di). Esistono relazioni molto strette fra il numero dei nodi, quello dei

punti di controllo ed il grado della B-spline. Nella sequenza di nodi, che

ricordiamo essere decrescente, e possibile che un valore sia ripetuto piu

volte. La ripetizione di un nodo comporta che la sua molteplicita (che

indicheremo con mi e sara semplice se pari ad 1) aumenti di 1 per ogni

ripetizione.

Dovra risultare che :

L+n−1∑i=n−1

ri = L + 1. (5.17)

Introduciamo cosı L, che (nel caso in cui tutti i nodi siano semplici) rap-

presenta il numero di domini intervallo di una B-spline. Ogni dominio

intervallo, puo essere interpolato da una curva di Bezier (vedi Fig. 5.1.3)

che mantenga con quella precedente e quella seguente condizioni di con-

34

Page 43: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

5. CURVE DI BEZIER E SPLINES

tinuita; tali condizioni sono funzione del grado della B-spline (avremo

continuita C1 se di grado 2, C2 se di grado 3).

Con continuita di tipo C1 indichiamo l’uguaglianza, tra due curve,

dei vettori tangenti nel punto di giunzione. Se l’uguaglianza vale anche

per le derivate successive dn[b(t)]dtn

parleremo di continuita di tipo Cn. Pos-

siamo definire anche un’altro tipo di continuita, quella geometrica (Gn).

Quando due curve si incontrano in un punto (senza ulteriori condizioni)

avremo continuita geometrica G0. Se le tangenti nel punto di giunzio-

ne hanno stessa direzione, ma non necessariamente la stessa lunghezza,

allora parleremo di continuita geometrica di tipo G1.

Possiamo ora dare l’espressione completa per una B-spline:

s(u) =L+n−1∑

j=0

djNnj (u) (5.18)

dove: il parametro u puo assumere tutti i valori compresi tra i nodi

u0, · · · , uL+2n−2; n rappresenta il grado del polinomio di base Nnj (u); dj

sono i punti di controllo.

Il polinomio di base gode di alcune interessanti proprieta: e non nega-

tivo per qualsiasi valore di u, e (se i punti dj sono tutti pari ad 1) rende

la funzione s(u) identicamente uguale ad 1. Il valore di un polinomio in

un punto puo essere calcolato sfruttando delle formule di ricorsione.

Noi illustreremo quella di Cox, De Boor piu utile da un punto di vista

implementativo.

Definiamo una funzione di base per n = 0 come:

N0i (u) =

1 se ui−1 ≤ u < ui

0 altrove. (5.19)

In questo modo possiamo calcolare una funzione di grado qualsiasi uti-

35

Page 44: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

5. CURVE DI BEZIER E SPLINES

lizzando la ricorsione di Cox, de Boor:

Nnl (u) =

u− ul−1

ul+n−1 − ul−1

Nn−1l (u) +

ul+n − u

ul+n − ul

Nn−1l+1 (u). (5.20)

Il calcolo esplicito del valore per ux puo essere effettuato ricordando la

Eq. 5.19 e procedendo nel seguente modo. Noto il valore j per cui ux

e compreso nell’intervallo [ui−1, ui], andiamo a calcolare il valore delle

funzioni che sono non nulle, organizzandole in una matrice:

......

......

......

0 0 0 0 · · · 0

N0j (ux) = 1 N1

j−1(ux) N2j−2(ux) N3

j−3(ux) · · · Nkj−k(ux)

0 N1j (ux) N2

j−1(ux) N3j−2(ux) · · · Nk

j−(k−1)(ux)... 0 N2

j (ux) N3j−1(ux) · · · · · ·

... 0 N3j (ux) · · · ...

... 0. . . . . .

.... . . Nk

j (ux)... 0

...

.

(5.21)

La somma dei valori presenti su ogni colonna e pari ad uno ed il valore

della B-spline per ux puo essere ora calcolato come:

s(ux) =j∑

i=j−k

djNkj (ux). (5.22)

In precedenza abbiamo detto che dalle B-spline possono essere otte-

nute un certo numero di curve di Bezier (pari al valore dei domini inter-

vallo), ma non abbiamo specificata la dipendenza tra i punti di controllo

della B-spline e delle curve di Bezier. Questa relazione (che tratteremo

esclusivamente per il grado 3, ma puo essere facilmente estesa ad un gra-

do qualsiasi) e ottenuta considerando le relazioni di continuita esistenti

36

Page 45: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

5. CURVE DI BEZIER E SPLINES

tra due curve adiacenti. L’insieme dei dj prende il nome di poligono B-

Spline ed questo che in seguito verra ricondotto ad un insieme di curve

di Bezier (i cui punti di controllo indicheremo con bi). Nel seguito del

paragrafo utilizzeremo ∆i per indicare la differenza ui+1−ui tra due nodi.

Se tra due curve esiste una relazione di continuita di tipo C1 in ui il

punto di controllo nella giunzione deve rispettare una condizione di tipo

b3i =∆i

∆i−1 + ∆i

b3i−1 +∆i−1

∆i−1 + ∆i

b3i+1. (5.23)

Per esserci una continuita di tipo C2 dovra esistere un punto di, tale che

b3i−2,b3i−1,di e di,b3i+1,b3i+2, siano nel rapporto ∆i−1 : ∆i. La defini-

Figura 5.4: B-spline cubica con continuita C2: il punto ausiliario di

permette di definire il poligono B-spline della curva

zione di una B-spline (di grado 3) passa attraverso il posizionamento dei

punti di, che rappresentano il poligono B-spline. Quindi da un poligono

B-spline e dall’insieme dei nodi, ricaviamo facilmente i punti di controllo

37

Page 46: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

5. CURVE DI BEZIER E SPLINES

delle curve di Bezier equivalenti alla B-spline. Avremo allora:

b3i−2 =∆i−1 + ∆i

∆di−1 +

∆i−2

∆di (5.24)

e

b3i−1 =∆i

∆di−1 +

∆i−2 + ∆i−1

∆di (5.25)

per tutti i valori di i = 2, L− 1, dove

∆ = ∆i−2 + ∆i−1 + ∆i. (5.26)

Qualche attenzione e richiesta per i primi e gli ultimi punti di controllo

dell’insieme delle curve di Bezier. Per questi dovra risultare:

b0 = d0

b1 = d1

b2 = ∆1

∆0+∆1d0 + ∆0

∆0+∆1d1

· · ·

b3L−2 = ∆L−1

∆L−2+∆L−1dL−1 + ∆L−1

∆L−2+∆L−1dL

b3L−1 = dL

b3L = dL+1

(5.27)

5.2 L’algoritmo di de Casteljau

L’algoritmo di de Casteljau permette di calcolare semplicemente i pun-

ti di una curva parametrica, come combinazione convessa dei punti di

controllo della stessa. Facciamo prima un esempio, per poi presentare

l’algoritmo. Prendiamo tre punti b0, b1, b2 ∈ E2 e sia t ∈ <. Possiamo

38

Page 47: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

5. CURVE DI BEZIER E SPLINES

allora costruire:

b10 = (1− t)b0 + tb1,

b11 = (1− t)b1 + tb2,

b02 = (1− t)b1

0 + tb11.

(5.28)

Sostituendo le prime due equazioni nella terza otteniamo:

b02(t) = (1− t)2b0 + 2t(1− t)b1 + t2b2. (5.29)

Questa e l’espressione di una parabola. Al variare di t nell’intervallo

(−∞,∞), mediante un processo d’interpolazione lineare ripetuta, pos-

siamo ottenere (a partire da b0,b1,b2) tutti punti della parabola.

Poniamo ora, di voler calcolare il valore di una curva polinomiale di

grado n. Presi b0, b1,. . . , bn ∈ E3 punti e un parametro t ∈ <, sia:

bri = (1− t)br−1

i + tbr−1i+1

r = 1, . . . , n

i = 0, . . . , n− r, (5.30)

con bi0(t) = bi. Allora bn

0 (t) sara il punto di parametro t nella curva di

Bezier bn. Il poligono P formato dai b0, b1,. . . , bn e detto poligono di

Bezier o poligono di controllo. Da un punto di vista pratico, l’utilizzo

di questo algoritmo ci permette d’individuare:il punto di una curva per

un arbitrario valore del parametro; i punti di controllo delle sottocurve

relative a tale suddivisione.

5.3 Calcolo della distanza minima tra una

curva ed un punto del piano

Il problema di calcolare la distanza minima tra un punto del piano ed

una curva di Bezier puo essere riformulato come: trovare il valore del

39

Page 48: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

5. CURVE DI BEZIER E SPLINES

parametro tP della curva, per cui la distanza del punto dalla curva sia

minima. Una volta trovato il parametro e facile individuare il punto

corrispondente sulla curva e la distanza minima.

Nel seguito descriveremo due diversi algoritmi risolutivi che risolvono

il problema d’individuare il parametro. Il primo sfrutta le proprieta del-

l’involucro convesso, il secondo formula il problema in modo da ricondurlo

ad una forma facilmente trattabile algoritmicamente.

5.3.1 Risoluzione con la proprieta dell’involucro con-

vesso

L’involucro convesso, individuabile dai punti di controllo che descrivono

la curva, contiene tutta la curva. Questa proprieta, viene mantenuta

nelle curve generate dalla suddivisione, effettuata mediante l’algoritmo

di de Casteljau (vedi pag. 38). Dati i punti di controllo di una curva

parametrica, si possono individuare i punti di controllo delle due sotto-

curve (generate dalla suddivisione della curva originale) per un valore di

parametro pari ad 12

facendo:

L0 = b0

L1 = b0+b1

2

R3 = b3

R2 = b2+b3

2

H = b1+b2

2

L2 = L1+H2

R1 = H+R2

2

L3 = R0 = L2+R1

2

(5.31)

dove con L abbiamo indicati i punti di controllo della curva a sinistra, con

R quelli della curva a destra e con bi quelli della curva iniziale. Suppo-

niamo che il punto selezionato sia molto vicino alla curva (praticamente

40

Page 49: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

5. CURVE DI BEZIER E SPLINES

gli appartiene), effettuando un semplice test (controlliamo che il punto

sia contenuto nell’involucro convesso), potremmo facilmente trovare il piu

piccolo involucro che contiene il punto e, quindi, il corrispondente para-

metro, iterando l’algoritmo di de Casteljau sulla sottocurva in cui il test

e passato. Il metodo risulta essere abbastanza veloce, ogni volta dimez-

ziamo l’intervallo su cui effettuare la ricerca, ma presenta molti limiti.

Innanzi tutto, non e possibile trovare un punto che sia troppo distante

dalla curva (una delle ipotesi fatte e la vicinanza del punto alla curva), in

quanto, il test di appartenenza all’involucro, fallirebbe dopo pochi passi

dando un risultato errato, inoltre, puo accadere che il test di apparte-

nenza sia verificato per due poligoni contemporaneamente, rendendo la

ricerca complessa da gestire.

5.3.2 Risoluzioni con i polinomi di Bezier

La ricerca del parametro che individua il punto della curva piu vicino ad

un punto selezionato, puo essere posto formalmente dicendo: data una

curva parametrica B(t) ed un punto P, entrambi nel piano, trovare il

punto sulla curva B(t) piu vicino a P (o meglio il parametro relativo

a tale punto). La congiungente tra il punto di minimo e il punto P

sara necessariamente normale alla tangente. L’equazione, che vogliamo

risolvere rispetto a t, sara:

(B(t)−P) ·B′(t) = 0. (5.32)

Se B(t) e una curva parametrica di Bezier in forma di Bernstein (B(t) =∑ni=0 biB

ni (t)), possiamo indicare la derivata come:

B′(t) = nn−1∑i=0

(bi+1 − bi)Bn−1i (t). (5.33)

41

Page 50: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

5. CURVE DI BEZIER E SPLINES

Le curve che utilizziamo hanno grado 3, la derivata prima sara ovviamen-

te di grado 2, il polinomio 5.32 sara generalmente di grado 5. Per tale

grado non esiste una forma chiusa e, per la ricerca delle radici reali, si

dovra utilizzare qualche algoritmo. Nel seguito, ne presenteremo uno che

utilizza le proprieta delle curve di Bezier, preoccupiamoci di riportare il

nostro polinomio in tale forma.

Separiamo i due polinomi della 5.32, avremo:

B1(t) = B(t)−P, (5.34)

B2(t) = B′(t). (5.35)

Allora la 5.32 sara riscrivibile come:

B1(t) ·B2(t) = 0. (5.36)

Il primo polinomio sara riscrivibile come:

B1(t) =

= B(t)−P =

=∑n

i=0 biBni (t)−P =

=∑n

i=0 ciBni (t)

(5.37)

con ci = bi −P. Dall’espansione della 5.35 abbiamo:

B2(t) =

= n∑n−1

i=0 (bi+1 − bi)Bn−1i (t) =

=∑n−1

i=0 diBn−1i (t),

(5.38)

42

Page 51: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

5. CURVE DI BEZIER E SPLINES

dove abbiamo di = n(bi+1 − bi). Possiamo ora riscrivere la 5.36 come:

0 =∑n

i=0 ciBni (t) ·∑n

j=0 djBn−1j (t)

=∑n

i=0

∑n−1j=0 ci · djB

ni (t)Bn−1

j (t)

=∑n

i=0

∑n−1j=0 ci · dj

n

i

(1− t)(n−i)ti

n− 1

j

(1− t)(n−1−j)tj

=∑n

i=0

∑n−1j=0 ci · dj

n

i

n− 1

j

(1− t)(2n−1)(i−j))t(i + j)

=∑n

i=0

∑n−1j=0 ci · dj

n

i

n− 1

j

2n− 1

i + j

B2n−1

i+j

=∑n

i=0

∑n−1j=0 ci · djzi,jB

2n−1i+j

=∑n

i=0

∑n−1j=0 wi,jB

2n−1i+j ,

(5.39)

con zi,j =

n

i

n− 1

j

2n− 1

i + j

e wi,j = ci · djzi,j. Ora wi,j non sono punti,

ma numeri reali che descrivono una sola componente della curva parame-

trica (la y per l’esattezza). L’altra componente e ottenuta considerando i

punti di controllo wi,j ottenuti da i+j/n+(n−1) (semplice applicazione

della proprieta di precisione lineare di pag. 32). A questo punto l’equa-

zione di quinto grado e in forma di Bezier, possiamo, quindi, utilizzare

l’algoritmo di soluzione basato su questa particolare rappresentazione che

presentiamo nella nuova sezione.

43

Page 52: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

5. CURVE DI BEZIER E SPLINES

Metodo per il calcolo delle radici di un polinomio in forma di

Bezier

In [10], viene definito minmax box: “il piu piccolo rettangolo con i lati pa-

ralleli agli assi coordinati, che contiene l’involucro [convesso]”. Trovare la

minmax box e molto semplice, basta individuare i massimi dell’involucro

convesso e calcolare il rettangolo che li interpola. Se abbiamo bisogno di

calcolare le intersezioni di una curva planare (i cui valori delle coordinare

x dei punti di controllo, siano uniformemente spaziati sulle ascisse), con

un segmento S, basta controllare la presenza d’intersezioni tra minmax

box della curva e segmento. Se questa intersezione e trovata si puo uti-

lizzare l’algoritmo di de Casteljau, vedere quale delle due minmax box

ha ancora intersezione e ripetere il procedimento finche l’involucro con-

vesso della curva considerata non sia talmente piccolo da poter essere

considerato un punto. La suddivisione binaria, operata dall’utilizzo del-

l’algoritmo di de Casteljau, permette di avere un errore pari ad 12r dove r

e il passo di ricorsione. Al primo passo, infatti, avremo che il parametro

varia tra 0 ed 1 (t ∈ [0, 1]) e l’errore massimo che ci potremo aspettare

sara 0.5, al passo successivo l’errore che ci aspetteremo sara la meta 0.25

e cosı via. Questo algoritmo non e attendibile per la soluzione di un po-

linomio con un grado troppo elevato, in quanto c’e un accumulo di errori

derivanti dalle suddivisioni che potrebbero fornire una soluzione errata.

E bene notare il test della minmax box e formalmente analogo a quello

presentato nella sezione precedente. L’ipotesi che ora lo rende utilizzabile

e la planarita della curva (che non e assicurata nel caso precedente).

5.4 Curvatura

Nel nostro studio particolare importanza ha rivestito l’analisi della cur-

vatura di una curva parametrica. Una curva in E3 e ottenuta da una

44

Page 53: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

5. CURVE DI BEZIER E SPLINES

rappresentazione parametrica tipo

x = x(t) =

x(t)

y(t)

z(t)

, t ∈ [a, b] ⊂ < (5.40)

dove le coordinate cartesiane x, y, z, sono funzioni differenziabili di t e

x(t) e una curva del tipo descritto in precedenza, (curve di Bezier, curve

splines). Per evitare problemi relativi alla parametrizzazione della curva,

Figura 5.5: Una curva parametrica nello spazio.

assumiamo che risulti:

x′=

x′(t)

y′(t)

z′(t)

6= 0, t ∈ [a, b] ⊂ < (5.41)

denotando con l’apice la derivata prima rispetto a t. Una parametrizza-

zione di questo tipo e detta regolare. Effettuando un cambio di τ = τ(t)

45

Page 54: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

5. CURVE DI BEZIER E SPLINES

del parametro t, dove τ e una funzione differenziabile di t, non cambie-

remo l’aspetto della curva. Questa riparametrizzazione sara regolare se

τ′ 6= 0 per tutte le t ∈ [a, b], in tal caso infatti possiamo ricavare l’inversa

t = τ(t). Ponendo:

s = s(t) =∫ t

a‖x′‖dt, (5.42)

vediamo che tale risultato e indipendente da qualsiasi tipo di parame-

trizzazione infatti:

x′dt =

dx

dtdt =

dx

dτdτ . (5.43)

Questo parametro invariante s e detto lunghezza dell’arco.

5.4.1 Riferimento di Frenet

Introdurremo ora uno speciale sistema di coordinate (collegato al punto

x(t) della curva), che facilitera la descrizione di alcune proprieta della

curva. Effettuiamo l’espansione in serie di Taylor di x(t) :

x(t + ∆t) = x + x′∆t + x

′′ 1

2∆t2 + x

′′′ 1

6∆t3 + . . . (5.44)

Supponendo che le prime tre derivate x′,x

′′,x

′′′, siano linearmente indi-

pendenti possiamo fissare un sistema di riferimento basato sulle derivate

con origine in x(t). La curva x(t), in questo sistema, puo essere scritta

come: ∆t + . . .

∆t12

+ . . .

∆t16

+ . . .

(5.45)

dove con i puntini intendiamo i termini di ordine superiore. Riportan-

do il sistema di riferimento individuato in forma ortonormale, possiamo

46

Page 55: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

5. CURVE DI BEZIER E SPLINES

chiamare i tre assi individuati t, m, b e questi saranno dati da:

t = x′

‖x′‖

m = b ∧ t

b = x′∧x

′′

‖x′∧x′′‖

(5.46)

dove con∧

denotiamo l’usuale prodotto vettoriale. Il vettore t e detto

vettore tangente, il vettore m e detto normale principale e b e detto

vettore binormale. Il riferimento t, m, b, e detto riferimento di Frenet,

e varia il suo orientamento al variare del parametro t. La formulazio-

ne in termini di riferimento di Frenet e utilizzata in quanto si desidera

esprimere le variazioni locali del riferimento, in funzione del riferimento

stesso. In particolare utilizzando una parametrizzazione rispetto alla lun-

ghezza dell’arco le formule che rappresentano la curvatura e la torsione

sono semplici. Indicando la differenziazione rispetto all’arco con un apice

numerico, vediamo che x1 = t e un vettore unitario, e si trova inoltre che:

x1 · x1 = 1

x1 · x2 = 0.(5.47)

Possiamo ora ottenere le formule di Frenet− Serrel

t1 = km

m1 = −kt + τb

b1 = −τm

(5.48)

dove k e τ sono rispettivamente la curvatura e la torsione della curva in

questione.

Curvatura e torsione si calcolano mediante le

k = k(s) = ‖x2‖ (5.49)

47

Page 56: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

5. CURVE DI BEZIER E SPLINES

k = k(t) =‖x′ ∧ x

′′‖‖x′‖3 (5.50)

τ = τ(s) =1

k2det[x

′, x

′′, x

′′′] (5.51)

τ = τ(t) =det[x

′, x

′′, x

′′′]

‖x′ ∧ x′′‖2 . (5.52)

5.4.2 Algoritmi per il calcolo della curvatura

Per i nostri scopi l’aspetto della curva che ci preme maggiormente cono-

scere e manipolare e la curvatura. Questo perche due curve che appaiono

uguali possono avere differenti curvature e questo nasconde profonde dif-

ferenze di parametrizzazione. Il grafico di curvatura si ottiene come coor-

dinate (t, s(t)) al variare del parametro t ∈ [a, b]; questo comporta che

utilizzeremo la forma 5.50, che tradotta in termini di curve bidimensionali

si riduce a

k = k(t) =x′′(t)y

′(t)− x

′(t)y

′′(t)

[(x′(t))2 + (y′(t))2]32

(5.53)

questa formula non riveste un particolare interesse computazionale, in-

fatti la sua risoluzione comporta il calcolo di quattro derivate e la riso-

luzione della radice a denominatore, per noi e piu interessante utilizzare

la formula

k =n− 1

n

w0w2

w1

b

a2, (5.54)

(vedi [10]) dove con a, indichiamo la distanza tra i punti di controllo

b0 e b1, e con b la distanza tra b2 e la tangente individuata da b0b1

tale formula (di cui non riporteremo la dimostrazione) e valida per un

polinomio razionale di Bezier di grado 3 e ci restituisce il valore della

curvatura per il valore 0 del parametro. Un polinomio di tal genere si

esprime come

br(t) =

∑ni=0 wibiBi(t)∑ni=0 wiBr(t)

, (5.55)

48

Page 57: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

5. CURVE DI BEZIER E SPLINES

Figura 5.6: Riferimento di Frenet e significato di a e b

questa formulazione puo essere facilmente ricondotta al caso non ra-

zionale fissando i pesi wi = k, k 6= 0, in tal modo per la proprieta di

precisione lineare (vedere 5.1.2), la sommatoria del polinomio a denomi-

natore e uguale all’unita, e il polinomio a numeratore non e altro che la

rappresentazione di una curva parametrica non razionale. Se il grado e

tre otteniamo:

k =2

3

b

a2, (5.56)

o, in modo equivalente, 7

k =2 · 23

area[b0,b1,b2]

dist3[b0,b1], (5.57)

questa espressione e equivalente alla 5.54 perche indicando con b2t la

proiezione di b2 sull’asse t, l’area precedente puo essere calcolata come

differenza tra(b2t−a)·b

2e

b2t ·b2

da cui b2· b2t − (b2t − a) = a·b

2e sosti-

tuendo all’area quest’ultima espressione si ottiene esattamente la 5.54.

7 l’area nel nostro caso risulta essere il valore del seguente determinante

area(a,b, c) =ax bx cx

ay by cy

1 1 1

49

Page 58: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

5. CURVE DI BEZIER E SPLINES

E allora possibile calcolare la curvatura per ogni valore della curva, uti-

lizzando l’algoritmo di de Casteljau. Possiamo ricavare il poligono di

controllo per il valore di parametro che ci interessa ed applicargli la

5.57.Un solo caso sembrerebbe avere difficolta, il valore estremo t = 1

(x(1) = b2); sfruttando un’ulteriore proprieta delle curve di Bezier, la

simmetria (vedere 5.1.2), basta allora invertire le posizioni dei punti con-

trollo (b0r = b3, b1r = b2, b2r = b1, b3r = b0), e applicando la formula

si ottiene esattamente il risultato cercato.

50

Page 59: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

Capitolo 6

Utilizzo e progetto di tecniche

di manipolazione

In questo capitolo, parleremo delle tecniche realizzate per permettere la

manipolazione intuitiva di una curva. Nella prima parte presenteremo

gli strumenti ed il loro utilizzo, nella seconda gli algoritmi che ne hanno

reso possibile l’implementazione. Gli strumenti che tratteremo sono uti-

lizzati nel programma Fasped (un ambiente che e servito per il test e che

analizzeremo nel prossimo capitolo), ma la loro collocazione finale sara

all’interno di Paperless.

6.1 Gli strumenti

Fasped, analogamente ad altri programmi di disegno vettoriale, offre al-

cuni strumenti (tools) per disegnare e manipolare tratti di curva (nel

seguito considereremo un disegno, realizzato per mezzo di pennellate o

strokes), come, ad esempio, il tool Pencil, con cui possiamo tracciare una

linea a mano libera, o Arrow, con cui la possiamo muovere come se fosse

un filo. Il risultato dell’operazione eseguita da uno strumento, e ottenuto

grazie all’algoritmo che lo caratterizza.

Gli strumenti offerti da Fasped sono contenuti in diverse toolbars.

51

Page 60: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

6. UTILIZZO E PROGETTO DI TECNICHE DI MANIPOLAZIONE

Ogni toolbar raggruppa le icone dei tools che hanno funzionalita simili.

Abbiamo una toolbar di disegno; una di manipolazione ed una per il

controllo della visualizzazione. La selezione avviene clickando sull’icona

raffigurante il tool. L’utente interagisce con uno strumento, sfruttando

opportune combinazioni degli eventi (del mouse) di click, drag e release.

6.1.1 Strumenti di disegno

La toolbar di disegno (vedi Fig. 6.1), contiene degli strumenti che per-

mettono il disegno di una linea o di semplici figure geometriche.

Figura 6.1: La toolbar con gli strumenti di disegno

Le icone presenti in Fig. 6.1 corrispondono ai tools:

• Pencil, che permette il disegno di una curva a mano libera;

• Pen, che permette di disegnare una curva specificando i punti di

controllo;

• Rectangle, che permette di disegnare un rettangolo;

• Ellipse, che permette di disegnare un’ellisse.

Pencil

Pencil permette il disegno di una linea a mano libera. I punti sono

acquisti nella fase di click and drag e vengono interpolati al release. Du-

rante l’acquisizione viene mostrata la poligonale che passa per i punti

campionati dal mouse; questa viene sostituita al release dalla linea com-

posta dalle curve interpolanti. L’algoritmo d’interpolazione e descritto in

dettaglio a pag. 62. Pencil deve riuscire a convertire in curve di Bezier, li-

nee che potrebbero avere discontinuita (l’utente potrebbe disegnare delle

52

Page 61: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

6. UTILIZZO E PROGETTO DI TECNICHE DI MANIPOLAZIONE

cuspidi) e questo comporta di dover esaminare i punti per suddivider-

li in tratti “abbastanza” continui, da raccordare opportunamente dopo

l’interpolazione.

Pen

Pen e lo strumento per disegnare un arco di Bezier, posizionando i punti

di controllo. Al click viene lasciato il punto iniziale dell’arco, durante il

drag viene spostato il secondo punto, la cui posizione e fissata dall’azione

di release. Visto che le curve di Bezier, da noi utilizzate hanno bisogno di

quattro parametri, dovremo ripetere la procedura appena descritta per

completare l’arco.

Durante il drag sono mostrati due vettori, uno che va dal punto sele-

zionato al cursore ed un altro di verso opposto. Questi indicano all’utente

quale sara la posizione dei punti di controllo intermedi.

Possiamo costruire una linea costituita da tratti di curve, semplice-

mente iterando il procedimento di posizionamento. Le curve costrui-

te mantengono una continuita di tipo C1 (la tangente, nel punto di

giunzione, della curva che precede e uguale a quella della curva che segue).

Rectangle

Rectangle e uno dei tool realizzati al fine di facilitare il disegno di sem-

plici primitive. La costruzione del rettangolo avviene posizionando i due

estremi della diagonale, gli eventi utilizzati sono: click, drag e release. Al

click viene posizionato il primo estremo, durante il drag muoviamo la dia-

gonale e viene visualizzato il rettangolo costruito a partire dall’estremo

fissato e di diagonale variabile; al release rimane individuato il secondo

estremo ed il disegno finale.

53

Page 62: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

6. UTILIZZO E PROGETTO DI TECNICHE DI MANIPOLAZIONE

Ellipse

Ellipse viene impiegato per disegnare ellissi o cerchi. Il suo utilizzo e

uguale a Rectangle, l’unica differenza risiede nel fatto che, invece del

rettangolo, viene disegnata la curva in esso inscritta.

6.1.2 Strumenti di manipolazione

In Fasped, un disegno puo essere realizzato a mano, oppure caricato da

un file su cui era stato precedentemente salvato. Una volta che un di-

segno e presente nella finestra di lavoro, e possibile procedere alla sua

manipolazione.

Figura 6.2: La toolbar con gli strumenti di manipolazione

La modifica del disegno e resa possibile da (Fig. 6.7):

• ControlPoints, che permette di spostare i punti di controllo;

• Arrow, che permette di spingere o tirare una linea come se fosse un

filo;

• Bender, che permette di “piegare” o “stirare” una curva;

• Deformer, che permette di selezionare una zona di disegno e defor-

marla in modo intuitivo.

ControlPoints

ControlPoints e un tool che permette di modificare la posizione di un

punto di controllo di una linea. Quando il tool viene selezionato, so-

no mostrati tutti gli estremi1 delle curve del disegno. Clickando su uno

1Per la proprieta di pag. 30 gli estremi sono punti di controllo.

54

Page 63: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

6. UTILIZZO E PROGETTO DI TECNICHE DI MANIPOLAZIONE

di questi punti, sono mostrati i vettori che collegano l’estremo ai punti

di controllo intermedi. Effettuando il drag i vettori sono traslati nella

posizione voluta. Al successivo release i vettori continuano ad essere mo-

strati, in questo modo l’utente puo cambiare la direzione della tangente

(vedi Fig. 6.3).

Figura 6.3: In 1) la curva come appare dopo la selezione del tool; in 2) eavvenuta la selezione e vengono mostrati i segmenti; in 3) “bilancino” eruotato; in 4) il risultato finale.

Arrow

L’Arrow e uno strumento che permette di manipolare una singola pen-

nellata. La deformazione e ottenuta clickando un punto della linea e

Figura 6.4: Un esempio del’utilizzo di arrow: a sinistra l’immagineoriginale; a destra e stata “tirata” una linea del cappello.

55

Page 64: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

6. UTILIZZO E PROGETTO DI TECNICHE DI MANIPOLAZIONE

spostandolo. La linea, durante il movimento manterra la sua continuita.

L’operazione effettuata da Arrow ha un carattere “locale”, agisce solo su

un breve tratto di linea. La lunghezza di questo tratto e fissata automa-

ticamente dal programma e varia al variare della risoluzione del disegno.

Questa astrazione comporta, da un punto di vista implementativo, di

dover risolvere il problema di rendere una linea indipendente dalla sua

parametrizzazione; per far questo abbiamo realizzato un algoritmo (che

presenteremo in seguito), che permette la parametrizzazione uniforme

mediante suddivisioni ricorsive.

Bender

Il Bender e uno strumento che lascia manipolare le linee di un disegno

in due modi: “piegandole” o “stirandole” (vedi Fig. 6.5). Diversamente

Figura 6.5: Un esempio di utilizzo del bender. A sinistra l’immagine ori-ginale mentre viene posizionato lo strumento, in centro abbiamo ruotatoparte del braccio, a destra il risultato finale.

dall’Arrow, il Bender permette di considerare come un oggetto fisico, non

piu un contorno, ma un pezzo di disegno. In questo modo siamo in grado

di spostare delle aree di disegno opportunamente individuate.

Il Bender richiede d’individuare un segmento di “taglio” che divida

la finestra di disegno in due semipiani e che intersechi le linee formanti

la zona da muovere. Questo segmento e ricavato dalla combinazione

56

Page 65: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

6. UTILIZZO E PROGETTO DI TECNICHE DI MANIPOLAZIONE

dell’azione di click, in cui viene posizionato un estremo, di drag, che

permette di fissarne la lunghezza e di release, che rilascia il secondo. Una

volta che il segmento sia stato posizionato lo possiamo muovere in due

modi o spostando un estremo, o trasclando.

Nel primo caso, le linee che si trovano nel semipiano, verso cui avviene

lo spostamento, sono “piegate” rispetto all’estremo fisso; nel secondo caso

vengono invece “stirate” nella direzione del movimento.

Il Bender, come gia detto, permette di agire su intere zone di disegno,

questo comporta di dover raccordare in modo opportuno le regioni mobili

con quelle ferme e questo puo essere fatto solo inserendo nuove linee la

cui forma sia opportunamente controllata.

Deformer

Il Deformer permette di modificare una zona del disegno che e individuata

dalla forma di un’area semplice (nel nostro caso un cerchio). Il tool,

una volta selezionato, viene visualizzato in finestra per mezzo di una

circonferenza, il cui centro segue il cursore.

All’evento di click and release la circonferenza viene lasciata sul dise-

gno e tutte le linee che hanno intersezioni o si trovano nel cerchio vengono

selezionate e colorate di rosso; una volta posizionata la possiamo traslare

o aumentarne il raggio.

Nel primo caso basta clickare all’interno del cerchio e fare drag, in

questo modo la regione individuata dal tool viene traslata ed il disegno

selezionato deformato, mantenendo alcune caratteristiche (in particolare

viene mantenuta la continuita nella regione anulare esterna); nel secondo

caso, dobbiamo clickare in prossimita del cerchio e fare drag; l’area si

allarga ed un numero maggiore di curve sono selezionate.

Il Deformer sfrutta le potenzialita offerte dalle funzioni potenziale.

Questo (come vedremo in seguito) comporta di dover suddividere la curva

in tratti di lunghezza molto piccola, muoverli e cercare di ridurli.

57

Page 66: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

6. UTILIZZO E PROGETTO DI TECNICHE DI MANIPOLAZIONE

Figura 6.6: Un esempio del’utilizzo di Deformer. A sinistra il tool vie-ne posizionato, in centro il tool e attivo ed e stato spostato, a destra ilrisultato della deformazione.

6.1.3 Strumenti per il controllo della visualizzazio-

ne

In questo paragrafo presentiamo alcuni tools che servono per gestire la

visualizzazione del disegno; nella toolbar (Fig. ??) troviamo:

Figura 6.7: La toolbar con gli strumenti di controllo visualizzazione.

• Zoom IN, gestisce lo zoom per visualizzare particolari;

• Zoom OUT, gestisce lo zoom per dare una vista d’insieme;

• Pan, che permette di fare una panoramica del disegno;

• FrameManager, che permette di cambiare la tavola su cui si sta

lavorando.

Zoom IN/OUT

Zoom IN/OUT gestisce lo zoom, permette cosı di esaminare particolari

o di avere una vista d’insieme. Diversamente dagli altri tool basta solo

selezionare l’icona per ingrandire o rimpicciolire il disegno.

58

Page 67: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

6. UTILIZZO E PROGETTO DI TECNICHE DI MANIPOLAZIONE

Pan

Pan si occupa di traslare il disegno, all’interno della finestra video. Al

click viene agganciato il punto in cui si trova il cursore, durante il drag

il disegno viene traslato ed al release viene rilasciato.

FrameManager

Nel nostro programma, abbiamo fornito all’utente, la possibilita di ope-

rare con piu di un disegno in una stessa finestra; questa scelta, e dovuta

al fatto che un’animazione e composta da una sequenza di disegni. Fra-

meManager permette di passare da uno all’altro. Quando lo strumento

viene selezionato e mostrata una griglia le cui celle possono essere piene

o vuote (questa griglia, per ora, consente di gestire fino a 20 disegni con-

temporaneamente). Ogni cella e l’indice di una struttura dati contenente

le tavole di disegno. Se un cella e vuota, in quella posizione non c’e un

disegno. Quelle piene possono essere gialle o viola: se sono gialle ci sono

disegni a cui accedere; se viola il disegno della cella e quello a video (per

adesso e possibile visualizzare un solo disegno alla volta, non viene gesti-

to l’alpha-blending, vedi pag. 9). Le funzionalita potrebbero essere estese

in futuro, per consentire la copia di tavole e la preview dell’animazione

di quelle presenti.

6.2 Gli Algoritmi

In questo seconda parte del capitolo presentiamo gli algoritmi che hanno

reso possibile la realizzazione dei tools precedenti; in seguito vedremo:

• ricerca di una curva;

• suddivisione di una curva in tratti di lunghezza fissata;

• minimizzazione del numero di curve di una linea.

59

Page 68: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

6. UTILIZZO E PROGETTO DI TECNICHE DI MANIPOLAZIONE

6.2.1 Ricerca di una curva

L’algoritmo che, all’interno del disegno, individua una curva che si trovi

a distanza minima da un punto e uno dei piu importanti, in quanto ogni

tool ha bisogno di conoscere dove l’utente desidera sia applicata l’azione.

Il nostro algoritmo prende in ingresso le curve che compongono il disegno,

il punto in cui si vuole effettuare la ricerca ed il raggio di pick.

Il raggio di pick, fissa la distanza massima per cui il punto clickato

riesce a selezionare un oggetto; linee, curve o punti a distanza maggiore

di tale valore non verranno trovati.

In uscita avremo la curva selezionata; inoltre, viene restituito il va-

lore del parametro per cui la curva ha distanza minima dal punto. Lo

pseudocodice e mostrato in Algoritmo

Algoritmo 1: Selezione

procedure Selectioninput: listOfCurves /*elenco di curve*/

point /*punto del piano che e stato selezionato*/pickRay /*raggio di pick*/

output: curve /*curva a distanza minima*/[1] for each curva di listOfCurves[2] Controlla che il punto appartenga alla minmax box

della curva, allargata di pickRay[3] if e all’interno[4] then calcola la curva a distanza minima dal punto[5] curve=curva trovata in 4

Spieghiamo meglio alcune fasi. Un disegno e composto da molte cur-

ve, abbiamo bisogno di effettuare la ricerca nel modo piu rapido possibile.

Sappiamo che una curva risulta completamente contenuta all’interno del-

l’involucro formato dai suoi punti di controllo (proprieta a pag. 29). Effet-

tuare un test che controlli se un punto appartenga all’involucro convesso

richiede numerosi calcoli; preferiamo allora utilizzare, al posto dell’invo-

60

Page 69: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

6. UTILIZZO E PROGETTO DI TECNICHE DI MANIPOLAZIONE

lucro, la minmax box, una maggiorazione molto facile da individuare (e

il rettangolo che contiene l’involucro) e che richiede pochi confronti per

stabilire se un punto si trova all’interno o no. La minmax box e allargata

delle dimensioni del “raggio di pick”, (questo permette la selezione an-

che se il punto di click non e vicinissimo alla curva). Sulla minmax box

allargata viene effettuato il test di appartenenza e, se ha esito positivo,

si passa al calcolo del minimo vero e proprio (effettuato in linea 4) che

viene eseguito utilizzando la procedura presentata a pag. 41. Infine, e

restituita la curva che ha distanza minima ed il parametro che compete

al minimo2.

6.2.2 Suddivisione di una curva in tratti di lunghez-

za fissata

Nel nostro studio abbiamo trovato che l’utilizzo di opportune funzioni

potenziale, permette di realizzare tools di manipolazione dal risultato

intuitivo e facili da usare (come l’Arrow o il Deformer). Le funzioni

potenziale non sono, pero, trasformazioni affini ed il risultato della tra-

sformazione dei soli punti di controllo della curva, non e quello esatto

(che potrebbe essere ottenuto solamente trasformando ogni punto della

curva secondo la funzione prescelta). Nella realta non potremo utilizzare

gli infiniti punti della curva, possiamo pero pensare di dividerla, in seg-

menti di lunghezza pari alla dimensione di un pixel e muovere gli estremi

di ogni segmento (vedi [10], [1], [8]). In questo modo riusciremo ad indi-

viduare l’effetto della deformazione, anche se poi rimane il problema di

ridurre il numero di punti necessari a descrivere la linea deformata.

Nasce l’esigenza di trovare un algoritmo che permetta di suddividere

la curva in tratti di lunghezza costante. Questo non puo essere fatto,

2In alcuni casi sono restituiti anche gli indici che permettono d’individuare la curvaall’interno delle strutture dati utilizzate (indice della linea, nella lista di linee di unframe; indice della curva, nella lista di curve di una linea).

61

Page 70: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

6. UTILIZZO E PROGETTO DI TECNICHE DI MANIPOLAZIONE

semplicemente prendendo i punti ottenuti dal campionamento uniforme

del parametro t, in quanto non abbiamo una relazione lineare tra curva

e parametro. L’algoritmo di suddivisione, da noi individuato, passa per

il calcolo della lunghezza della curva.

La lunghezza di una curva parametrica dovrebbe essere calcolata me-

diante un integrale del tipo: l =∫ 10 s(t)dt, dove s e la lunghezza dell’arco

(vedi pag. 46). Possiamo pero approssimare l’integrale con segmenti, uti-

lizzando lo stesso principio ed algoritmo della fase di disegno (de Castel-

jau): se un segmento si discosta talmente poco dalla curva da poter essere

considerato coincidente (approssimiamo la lunghezza dell’arco con la cor-

da) la sua lunghezza sara circa quella dell’arco che sottende. L’algoritmo

che abbiamo realizzato prende in ingresso:

• la curva da suddividere;

• la lunghezza del tratto in cui viene suddivisa la curva;

• la tolleranza di disegno.

La tolleranza di disegno indica il valore limite della lunghezza di un seg-

mento al di sotto del quale possiamo considerarlo un punto. L’Algoritmo

mostra lo pseudocodice che risolve il problema.

L’algoritmo restituisce un vettore contenente i valori del parametro

in cui devono essere effettuate le suddivisioni. Usando un’opportuna

funzione di suddivisione, otteniamo la poligonale costituita da tratti di

lunghezza costante.

6.2.3 Minimizzazione del numero di curve di una

linea

La ricerca di una algoritmo di riduzione nasce da almeno due necessita:

quella di interpolare i punti acquisiti durante la fase di disegno; quella di

ridurre a curva, la poligonale creata per applicare le funzioni potenziale.

62

Page 71: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

6. UTILIZZO E PROGETTO DI TECNICHE DI MANIPOLAZIONE

Algoritmo 2: Suddivisione in tratti di lunghezza fissa

procedure Subdivideinput: t0 /*parametro che individidua il primo arco*/

t1 /*parametro che individua il secondo arco*/segmentLenght /*lunghezza del tratto in cui si desidera

suddividere la curva*/output: td /*parametro di suddivisione*/

[1] if (t1 − t0 < EPSILON) /*se i due parametri sonotalmente prossimi da non essere distinguibili*/

[2] then return[3] Calcola l’arco L0 che va t = 0 a t0[4] Calcola l’arco L1 che va t = 0 a t1[5] Calcola quanti tratti sono stati individuati e

la lunghezza totale osservata.[6] if l’arco L1 ha lunghezza minore della lunghezza

totale osservata[7] then return[8] if la differenza tra la lunghezza di arco L1 e lunghezza

totale osservata e minore di tolleranza.[9] then calcola il parametro linearizzato[10] td=parametro trovato in 9[11] return[12] else la curva e ancora troppo lunga[13] Calcola tm = t1+t0

2[14] subdivide(t0, tm, segmentLenght)[15] subdivide(tm, t1, segmentLenght)

63

Page 72: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

6. UTILIZZO E PROGETTO DI TECNICHE DI MANIPOLAZIONE

L’algoritmo di riduzione da noi utilizzato (e mostrato in Algoritmo ),

si ispira al metodo di [11], ripreso nel lavoro di [12]. Questo algoritmo

permette di trovare una linea che interpola un insieme ordinato di punti

(a meno di una tolleranza fissata dall’utente), sfruttando un metodo che

minimizza la somma dei quadrati delle distanza tra punti e linea. In in-

gresso avremo il set di punti da interpolare e il valore di distanza minima

che desideriamo sussista tra punti e curva; in uscita l’insieme di curve

interpolanti.

Indichiamo con Pi = (xi, yi) (i = 1, . . . , n) i punti da interpolare e

fissiamo il grado del polinomio della curva parametrica da utilizzare a 3;

riconduciamo la curva di Bezier in forma di polinomio:

B(t) = b0(1− t)3 + b13t(1− t)1 + b23t2(1− t) + b3t

3 =

=

axt3 + bxt

2 + cxt + dx

ayt3 + byt

2 + cyt + dy

.(6.1)

Il problema sara d’individuare i punti di controllo della curva o, in

modo equivalente, i coefficienti del polinomio in Eq. 6.1. I coefficienti

ax,bx,cx,dx,ay,by,cy,dy sono collegati ai punti di controllo, mediante:

ax = −b0x + 3b1x − 3b2x + b3x

bx = 3b0x − 6b1x + 3b2x

cx = −3b0x + 3b1x

dx = b0x

ay = −b0y + 3b1y − 3b2y + b3y

by = 3b0y − 6b1y + 3b2y

cy = −3b0y + 3b1y

dy = b0y.

(6.2)

Per calcolare le posizioni dei punti Pi sulla curva, avremo bisogno di una

64

Page 73: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

6. UTILIZZO E PROGETTO DI TECNICHE DI MANIPOLAZIONE

parametrizzazione iniziale che possiamo ottenere come:

ti =

0, i = 1

lenght(P1P2...Pi)lenght(P1P2...Pn)

, 1 < i ≤ n. (6.3)

Questo tipo di parametrizzazione non e pero molto buona e sara neces-

sario calcolarne una migliore in seguito.

La somma delle distanze al quadrato e data da:

S =∑n

i=1 ‖B(ti)−Pi‖2 =

=∑n

i=1(axt3i + bxt

2i + cxti + dx − xi)

2+

+∑n

i=1(ayt3i + byt

2i + cyti + dy − yi)

2

.. (6.4)

I coefficienti di Eq. 6.2 possono essere ricavati dalla Eq. 6.4 calcolando

gli zeri delle derivate rispetto ad ax, . . . , dx e ay, . . . , dy e risolvendo il

sistema cosı ottenuto:

ax∑n

i=1 t6i + bx∑n

i=1 t5i + cx∑n

i=1 t4i + dx∑n

i=1 t3i =∑n

i=1 xit3i

ax∑n

i=1 t5i + bx∑n

i=1 t4i + cx∑n

i=1 t3i + dx∑n

i=1 t2i =∑n

i=1 xit2i

ax∑n

i=1 t4i + bx∑n

i=1 t3i + cx∑n

i=1 t2i + dx∑n

i=1 t1i =∑n

i=1 xiti

ax∑n

i=1 t3i + bx∑n

i=1 t2i + cx∑n

i=1 ti + ndx =∑n

i=1 xi

(6.5)

(analogamente per gli ay, . . . , dy). Il sistema in Eq. 6.5 puo essere risolto

utilizzando il metodo delle eliminazioni di Gauss. La parametrizzazione

scelta inizialmente comporta che il risultato ottenuto e, generalmente,

poco significativo. Possiamo, allora, calcolarne una nuova utilizzando

la curva appena trovata; utilizzeremo i parametri relativi alla distanza

minima dei punti da interpolare rispetto alla curva.

Il ciclo effettuato in linea 7 di Algoritmo limita il numero di volte per

cui viene effettuata la riparametrizzazione; questo perche, dopo qualche

iterazione, non abbiamo piu un miglioramento dell’errore quadratico. Se

dopo aver riparametrizzato, non abbiamo ancora trovato un valore del-

65

Page 74: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

6. UTILIZZO E PROGETTO DI TECNICHE DI MANIPOLAZIONE

Algoritmo 3: Interpolazione di un set di punti

procedure Interpolateinput: vectOfPoints /*vettori di punti da interpolare*/

maxError /*errore massimo ammissibile*/output: curve /*curva interpolata*/

[1] Calcola una parametrizzazione iniziale ti basata sulla lunghezza dell’arco.[2] Interpola una curva di Bezier usando il metodo ai minimi quadrati.[3] if l’interpolazione e buona (errore massimo < maxError)[4] then poni curve=curva calcolata in 2[5] return[6] else[7] for numero di ripetizioni consentito[8] Riparametrizza e ricalcola una curva ai minimi quadrati.[9] if la parametrizzazione e buona[10] then poni curve=curva calcolata in 8[11] return[12] else dividi vectOfPoints in v1, v2

[13] Interpolate(v1, maxError)[14] Interpolate(v2, maxError)

66

Page 75: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

6. UTILIZZO E PROGETTO DI TECNICHE DI MANIPOLAZIONE

l’errore quadratico, minore della distanza minima desiderata, dobbiamo

suddividere in due il set di punti e richiamare la procedura (linea 12).

Otteniamo, cosı, due curve a cui dovremo far mantenere relazioni di con-

tinuita. Indicando con l’apice (l) la curva che interpola il primo set di

dati e con (r) quella del secondo, possiamo scrivere:

B(l)(t) =

a(l)x t3 + b(l)

x t2 + c(l)x t + d(l)

x

a(l)y t3 + b(l)

y t2 + c(l)y t + d(l)

y

, 0 ≤ t ≤ 1

B(r)(t) =

a(r)x t3 + b(r)

x t2 + c(r)x t + d(r)

x

a(r)y t3 + b(r)

y t2 + c(r)y t + d(r)

y

, 0 ≤ t ≤ 1

. (6.6)

In [12] viene proposto di mantenere una continuita di tipo G1 fissando:

B(l)(1) = B(r)(0)

αB(l)′(1) = B(r)′(0), (6.7)

con α = lenght(Pm...Pn)lenght(P1...Pm)

(m e l’indice che segnala in quale punto e stata

trovato la massima distanza dalla curva). Il nostro apporto, nel miglio-

rare tale algoritmo, consiste nell’individuare una stima di α. Invece di

utilizzare il valore tangente dell’ Eq. 6.7, ricaviamo un versore (che ci

indica la direzione della tangente in B(l) per t = 1) e ne stimiamo il

modulo; in questo modo riguadagniamo un grado di liberta da utilizzare

nelle formule ai minimi quadrati. Il sistema che proponiamo e:

ax

∑ni=1 t6i + bx

∑ni=1 t5i + αtx

∑ni=1 t4i =

∑ni=1(xi − dx)t

3i

ax∑n

i=1 t5i + bx∑n

i=1 t4i + αtx∑n

i=1 t3i =∑n

i=1(xi − dx)t2i

ax∑n

i=1 t4i + bx∑n

i=1 t3i + αtx∑n

i=1 t2i =∑n

i=1(xiti − dx)tx

(6.8)

dove con α indichiamo il modulo della tangente e con tx la componente

x del suo versore (un sistema simile puo essere utilizzato per la compo-

nente y). Particolare attenzione meriteranno i casi limite di set di punti

costituiti da 1,2 o 3 punti, in quanto il sistema risulta singolare. Il ca-

67

Page 76: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

6. UTILIZZO E PROGETTO DI TECNICHE DI MANIPOLAZIONE

so di punto unico deve essere evitato controllando la suddivisione; per 2

punti possiamo calcolare, come interpolazione, il segmento che li ha come

estremi; per il caso di 3 punti possiamo utilizzare condizioni di curvatura.

6.2.4 Taglio e rotazione

Taglio

L’operazione effettuata dal Bender, permette di ruotare una parte di

disegno, mantenendo la continuita tra le linee della zona di taglio (come

e mostrato in Fig. 6.5). Per effettuare quest’operazione e stato necessario

individuare un algoritmo d’intersezione tra curva e retta che mostriamo

in Algoritmo

Algoritmo 4: Intersezioni con una retta

procedure Intersectinput: curve /*curva con cui calcolare le intersezioni*/

segment /*segmento da intersecare*/output: var /*valore del parametro nel punto d’intersezione*/

[1] for ogni tratto di curve ottenuto usando de Casteljau[2] Calcola l’intersezione tra tratto e segment[3] if c’e intersezione[4] then calcola il parametro esatto che compete all’intersezione[5] var=parametro calcolato in 2

L’ Algoritmo non presenta particolari difficolta d’implementazione,

prende una curva, la tolleranza di disegno, il segmento da intersecare e

ritorna i punti in cui avviene l’intersezione (o i parametri che gli com-

petono). Il passo in linea 4 richiede una spiegazione piu dettagliata.

L’indicazione di esatto e dovuta al fatto che le curve non hanno, in ge-

nere, una parametrizzazione uniforme. Questo, come gia detto, dipende

dalla relazione tra parametro e punto corrispondente che non e lineare;

68

Page 77: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

6. UTILIZZO E PROGETTO DI TECNICHE DI MANIPOLAZIONE

il calcolo del valore esatto richiederebbe di risolvere l’equazione:

b0(1− t)3 + b13t(1− t)2 + b23t2(1− t) + b3t

3 = P, (6.9)

ed il controllo delle soluzioni. Noi abbiamo preferito utilizzare un’altro

sistema.

L’aver applicato l’algoritmo di de Casteljau comporta che di ogni,

ogni tratto, conosciamo i parametri t0, t1 che lo individuano. Se un

tratto interseca il segmento di taglio possiamo semplicemente riapplicare

l’AlgoritmoQuesta volta l’algoritmo viene fatto partire dai valori t0, t1 del

segmento e la lunghezza sara pari alla distanza tra il punto di parametro

t0 e l’intersezione. Il risultato fornito da Algoritmo sara il parametro

cercato.

Rotazione

L’algoritmo di rotazione e mostrato in Algoritmo

Algoritmo 5: Rotazione

procedure Rotateinput: vector /*vettore prima della rotazione*/

vectorRotate /*vettore ruotato*/listOfCurves /*lista di curve di raccordo*/

output: listOfCurves /*la stessa lista con le curve ruotate*/[1] Da vector e vectorRotate ricava l’angolo ed il verso di rotazione.[2] Calcola la matrice di rototraslazione.[3] Calcola il modulo della tangente.[4] for each curva in listOfCurves.[5] Applica la matrice di rototraslazione agli estremi che si trovano

nel verso di rotazione ed alle rispettive tangenti.

Il calcolo del verso di rotazione (in linea 1) ci permette di stabilire

quali sono i punti di controllo della curva di raccordo che devono ruotare.

69

Page 78: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

6. UTILIZZO E PROGETTO DI TECNICHE DI MANIPOLAZIONE

La matrice di rototraslazione e individuata dall’angolo e dal punto rispet-

to a cui stiamo facendo la rotazione. Ci soffermiamo sulla linea 3 dove

abbiamo indicato di calcolare il modulo della tangente. Questo modu-

lo viene ricavato come funzione dell’angolo di rotazione e della distanza

dal centro di rotazione. La funzione indicata e del tipo z = k · x · y

(con k > 0 costante arbitraria), questo permette che, durante il movi-

mento, il raccordo nei punti di giunzione sia morbido e la deformazione

progressiva.

70

Page 79: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

Capitolo 7

Il programma Fasped

7.1 Il programma Fasped

Fasped1 e l’ambiente di test che abbiamo realizzato al fine di provare gli

algoritmi trovati. Fasped e un editor vettoriale (con limitate funzionalita)

che permette di disegnare delle linee, di manipolarle, di salvare il risultato

della manipolazione su un file e di ricaricarlo in seguito.

Il linguaggio di programmazione utilizzato per la realizzazione di Fa-

sped e stato il C++. Per la realizzazione di alcune strutture dati ab-

biamo utilizzato le librerie STL[13]; la gestione della grafica ha richiesto

l’utilizzo delle librerie OpenGL[14]; nella gestione dell’interfacciamento

abbiamo utilizzato le librerie MFC2 [15] (versione per sistema operativo

Windows) e Qt3[16] (versione per sistema operativo Linux). Particolare

attenzione e stata posta per realizzare un programma: multipiattafor-

ma, indipendente da una specifico ambiente a finestre e da uno specifico

compilatore.

Per realizzare la versione di Fasped, presentata in questo lavoro, ab-

1Fasped e l’acronimo di Fabrizio spline editor.2Le MFC (Microsoft Foundation Class) sono delle librerie C++, utilizzate in

ambiente Windows per la gestione di finestre e degli eventi ad esse associati.3Le Qt sono delle librerie C++, di gestione finestre, utilizzabili su diverse

piattaforme. Sono sviluppate dalla Trolltech.

71

Page 80: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

7. IL PROGRAMMA FASPED

biamo scritto circa 20.000 linee di codice. Il nostro programma e in grado

di leggere files di diversi formati4; permette di salvare il disegno realiz-

zato su un files; permette l’editing e la manipolazione di linea con i tool

presentati nel capitolo precedente; funziona su due diverse piattaforme.

In Fasped e stata utilizzata una programmazione orientata agli og-

getti. Ogni oggetto e rappresentato da una classe che racchiude al suo

interno le strutture dati che la caratterizzano e le funzioni (chiamate

metodi in un linguaggio ad oggetti) necessarie a manipolarle.

In questo capitolo ci prefiggiamo di fornire al lettore una guida all’uti-

lizzo del codice redatto per lo sviluppo di algoritmi di manipolazione. La

descrizione delle classi e delle funzioni riportate non sara, quindi, esausti-

va, ma approfondiremo solo quegli aspetti che riteniamo possano essere

utili per operare ed estendere quanto redatto5.

7.2 La struttura delle classi per l’interfac-

cia

Cominciamo l’analisi delle classi utilizzate per l’interfacciamento. Queste

classi servono per visualizzare un oggetto, raffigurante un disegno, in una

finestra.

7.2.1 fbGrOb

Nel nostro progetto, l’oggetto base e stato chiamato fbGrOb che e l’acro-

nimo di Graphic Object (in Fig. 7.1 il grafico delle classi derivate). Un

Graphic Object contiene al suo interno le strutture ed i metodi necessari

4I formati supportati sono tutti di tipo vettoriale e sono: fse, fasped spline editor;tzv, toonz vector. Abbiamo inoltre due formati grezzi: dat, punti per la costruzionedi una b-spline; frp, (fasped raw points) un’unica successione di punti (utilizzato peril testing di alcune routines.).

5Fasped e dotato di documentazione in formato html con la descrizione dettagliatadi ogni classe, a cui si rimanda per ulteriori approfondimenti

72

Page 81: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

7. IL PROGRAMMA FASPED

Figura 7.1: Gerarchia delle classi originate da fbGrOb

73

Page 82: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

7. IL PROGRAMMA FASPED

per: essere inizializzato (l’inizializzazione e necessaria prima della visua-

lizzazione per settare alcune variabili OpenGL e calcolare la “Bounding-

Box” dell’oggetto6); visualizzare un disegno in una finestra; modificare

le dimensioni; associargli un colore; descrivere alcuni particolari (come il

tipo di tratteggio delle linee); etc.7.

7.2.2 fbWindow

Un oggetto fbWindow, deriva da un oggetto di tipo em fbGrOb. Que-

sto oggetto racchiude in se le funzionalita che permettono d’interagire

con un gestore di finestre; reagisce agli eventi input (quelli provenienti

da mouse e tastiera), notificandoli all’interno dell’applicazione ed effet-

tua la conversione tra coordinate window a coordinate world (permette

l’interazione con gli oggetti del disegno, nel loro sistema di riferimento).

7.2.3 fbFasped

L’oggetto fbFasped deriva dall’oggetto fbWindow (vedi Fig. 7.2). Il fatto

di ereditare i metodi di fbWindow lo rende in grado di ricevere eventi

dall’esterno e di notificarli ai tools, inoltre, ha delle funzionalita d’inter-

facciamento che permettono: di cambiare il tool attualmente in uso; di

modificare le coordinate finestra correnti nelle azioni di zoom e di pan-

ning (vedi pag. 53); di selezionare il disegno attivo, tra quelli disponibili

in una lista. fbFasped contiene al suo interno una struttura “lista di fb-

Frame”. Ogni oggetto fbFrame e in grado di contenere ed interagire con

un disegno (vedremo piu dettagliatamente in seguito). fbFasped gestisce

il salvataggio ed il caricamento da file degli fbFrame. Queste operazio-

ni sono effettuate con le classi fbSaver e fbLoader. Per default fbFasped

visualizza e rende attivo (cioe manipolabile) l’ultimo fbFrame aperto;

6La “BoundingBox” e un rettangolo in cui l’oggetto e inscritto, per le curve diBezier coincide con la minmax box.

7Per gli altri metodi e variabili si rimanda all’header o alla documentazione html.

74

Page 83: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

7. IL PROGRAMMA FASPED

Figura 7.2: Interazione tra l’oggetto fbFasped con fbTool e fbFrame.

questo comportamento puo essere aggirato utilizzando fbFrameManager

(vedi pag. 59).

7.3 La struttura delle classi dei tools

La manipolazione delle linee e resa possibile dall’utilizzo dei tools che so-

no stati presentati nel capitolo precedente. La classe da cui viene derivato

ogni tool e fbTool.

7.3.1 fbTool

fbTool deriva da em fbGrOb (questo perche ogni tool ha proprio curso-

re OpenGL) ed e una classe astratta (serve come modello di riferimen-

to), non potra essere istanziata direttamente (allocata della memoria per

75

Page 84: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

7. IL PROGRAMMA FASPED

creare un oggetto) ma solo usata come “contenitore” per le classi figlie8.

fbTool gestisce l’interazione tra tool ed eventi di input (tastiera e mouse),

comunicando con fbFasped.

Facciamo un esempio. La pressione del pulsante sinistro del mouse

(notificata dal gestore di finestre) viene intercettato dal metodo fbFa-

sped::OnLMouseDown di fbFasped. Questo metodo converte le coordina-

te finestra, nel sistema di coordinate solidale con il disegno e richiama il

metodo che gestisce il click del pulsante sinistro in fbTool. Questo meto-

do, formalmente uguale a quello di fbWindow, in funzione del tool che e

stato precedentemente selezionato, gestisce l’evento. Ogni tool (presen-

tato nel capitolo precedente), e contenuto in una classe, nel seguito ne

vedremo qualcuno.

7.3.2 fbCursor

All’avvio del programma il tool di default e fbCursor il cui unico compito

e quello di visualizzare un cursore a video. A questo tool non corrisponde

nessuna azione, serve solo come riferimento per l’utente.

7.3.3 fbFrameManager

fbFrameManager visualizza una griglia in cui e possibile selezionare una

tavola di disegno da manipolare.

7.4 La struttura delle classi per la grafica

In questo paragrafo presenteremo le classi che permettono la visualizza-

zione di linee e disegni.

8Questa proprieta e chiamata polimorfismo. Il polimorfismo e definito come: “lacapacita di chiamare una molteplicita di funzioni, usando la stessa interfaccia (cosıcome fornita dalle funzioni virtuali)” (vedi [17]).

76

Page 85: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

7. IL PROGRAMMA FASPED

7.4.1 fbFrame

Come detto in precedenza, una finestra fbFasped gestisce il disegno degli

oggetti fbFrame in essa contenuti. Un oggetto fbFrame deriva da em

fbGrOb, quindi al suo interno sono presenti i metodi necessari per il

disegno (derivati da em fbGrOb). C’e, inoltre, una lista di oggetti di

tipo fbPolyLine (che rappresentano una linea) ed i metodi per gestire la

selezione.

7.4.2 fbPolyLine

Un oggetto fbFrame e costituito da una lista di oggetti di tipo fbPolyLine.

fbPolyLine permette di gestire e visualizzare una linea che rispetti una

continuita di tipo C0, e costituito da una lista di fbCurve e gestisce la

selezione di una curva. Una fbPolyLine e in grado di restituire (dato un

vettore arbitrario di punti), la linea che li interpola (con l’algoritmo ai

minimi quadrati visto a pag.

7.4.3 fbCurve

fbCurve e una delle classi piu importanti di Fasped, rappresenta l’elemen-

to grafico di base della nostra applicazione: ogni disegno da visualizzare,

deve essere convertito in fbCurve. fbCurve (come le altre classi fino ad

ora descritte) deriva da em fbGrOb, e quindi possiede le funzioni neces-

sarie per la visualizzazione; inoltre, contiene tutti i metodi e le strutture

dati che permettono la gestione di una curva di Bezier di grado 3: dalla

selezione del parametro relativo al punto piu vicino, alla visualizzazione.

In fbCurve troviamo una struttura “vettore di punti fbPoint” (fbPoint e

una classe che gestisce un punto del piano con coordinate di tipo dou-

ble). Questo vettore contiene i punti di controllo di una curva di Bezier

in forma di polinomi di Bernstein. Sono inoltre presenti altre variabili

per la gestione della selezione e dell’algoritmo di suddivisione.

77

Page 86: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

7. IL PROGRAMMA FASPED

Il disegno di una curva di Bezier puo essere fatto in diversi modi (diffe-

renze finite, de Casteljau), noi abbiamo utilizzato l’algoritmo di de Caste-

ljau che in fbCurve si trova implementato nel metodo fbCurve::subdivide.

I parametri utilizzati in questo metodo sono:

• quattro punti;

• due valori estremi del parametro;

• un puntatore ad un oggetto di tipo fbOperation.

fbOperation (di cui tratteremo piu estesamente in seguito) e un ogget-

to che implementa un’operazione matematica restituendo un valore. Il

metodo fbCurve::subdivide, controlla che la distanza dei punti di control-

lo intermedi, dalla congiungente gli estremi, non ecceda la tolleranza;

se e nei limiti effettua l’operazione descritta da fbOperation, altrimen-

ti divide ulteriormente la curva iterando de Casteljau. L’aver separato

l’algoritmo dalla funzione specifica permette di aggiungere nuove fun-

zioni, semplicemente realizzando la classe che le implementa. In Fasped

abbiamo:

• fbCurveMeasure: permette di misurare la lunghezza di una curva;

• fbCurveDraw: permette il disegno passando le posizione degli estre-

mi dei segmenti ad OpenGL;

• fbIntersectCircle: permette di ricavare i valori del parametro in cui

una curva interseca una circonferenza;

• fbIntersectStraightLine: permette di ricavare i valori del parametro

in cui una curva interseca una retta;

• fbCurveSubdivideForLenght: restituisce i valori del parametro in

cui una curva ha una lunghezza stabilita;

78

Page 87: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

7. IL PROGRAMMA FASPED

• fbCurveSubdividePixelSize: restituisce i valori del parametro in cui

una curva viene suddivisa dall’algoritmo di de Casteljau;

• fbCurveSubdivideUniform: restituisce i valori del parametro neces-

sari per suddividere una curva in tratti di lunghezza fissa.

Come fbPolyLine anche in fbCurve abbiamo la possibilita di trovare

la curva che interpoli un vettore di punti dati. Questo e reso possibile in

un costruttore di fbCurve che prende come parametri:

• un vettore di punti;

• le direzioni delle tangenti nei due estremi;

• la tolleranza desiderata.

Se le direzioni delle tangenti non sono note (vettori di modulo nullo),

viene effettuata una normale ricerca ai minimi quadrati, altrimenti (ver-

sori di tangenza) si cerca di stimare il modulo del vettore in modo da

rispettare condizioni di continuita di tipo G1.

Altri metodi presenti in fbCurve permettono di conoscere, per un

fissato valore del parametro: il punto corrispondente; la curvatura; il

vettore tangente e la derivata seconda.

Il punto corrispondente ad un dato parametro e una semplice appli-

cazione del ripetuto algoritmo di de Casteljau.

Di come venga calcolata la curvatura abbiamo parlato in un para-

grafo nei capitoli precedenti (vedi pag. 44) e si puo sfruttare l’algoritmo

presentato a pag. 48. E possibile tracciare un grafico di curvatura, cam-

pionando il parametro e utilizzandone i valori per estrarre dei punti da

unire con una poligonale9.

Il calcolo del valore tangente e della derivata seconda puo essere af-

frontato in due modi: possiamo ricavare il polinomio esplicito dalla for-

9Il grafico di curvatura puo essere utile per analizzare la dipendenza dallaparametrizzazione (vedi [10]).

79

Page 88: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

7. IL PROGRAMMA FASPED

ma di Bernstein e calcolarne il valore per il parametro che ci interessa;

possiamo applicare le proprieta dei polinomi di Bernstein. Data la no-

stra rappresentazione la seconda modalita e senz’altro piu semplice ed

efficiente. La derivata di una funzione di Bernstein e data da:

d

dtBn

i (t) = n[Bn−1i−1 (t)−Bn−1

i (t)]. (7.1)

L’equazione della tangente allora sara: b′(t) = b01(1−t)2+b112t(1−t)+

b21t2 cioe, un polinomio di Bernstein di grado 2, con punti di controllo

che sono rispettivamente b01 = 3(b1 − b0), b11 = 3(b2 − b1), b21 =

3(b3 − b2). L’equazione della derivata seconda b′′(t) = b02(1− t) + b12t

e ottenuta semplicemente ripetendo il procedimento, con punti ottenuti

come b02 = 2(b01 − b11), b12 = 2(b11 − b21).

7.5 La struttura delle classi per l’analisi

numerica

La necessita di gestire trasformazioni, calcolare radici di polinomi, ri-

solvere semplici sistemi lineari, ci ha condotto a realizzare una piccola

libreria matematica, di cui analizzeremo qualche classe.

Le classi che seguono, oltre a gestire le operazioni matematiche tra

loro esistenti, permettono la visualizzazione delle primitive che imple-

mentano.

7.5.1 fbPoint

In Fasped e stato deciso di tenere separati, in due classi diverse, i punti

ed i vettori. Da un punto di vista informatico le informazioni ed i metodi

necessari per la gestione di questi due oggetti sono simili (dobbiamo me-

morizzare le posizioni di due coordinate, fornire dei metodi per la somma

80

Page 89: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

7. IL PROGRAMMA FASPED

la differenza il prodotto, etc.), ma l’aspetto matematico e differente (un

vettore e dato come differenza tra due punti, la somma di un punto ed

un vettore restituisce un vettore, tra punti non sono possibili operazio-

ni di somma10, etc.) vedi [10]. Un punto e stato quindi implementato

utilizzando una classe template (che rende possibili mantenere l’interfac-

cia della classe e specificare il tipo di cui si ha bisogno). Abbiamo cosı

fornito: punti con due coordinate (fbPoint2), con tre (fbPoint3) e con

quattro (fbPoint4)11. Abbiamo poi definito il tipo fbPoint come:“punto

bidimensionale con coordinate di tipo double”. In fbPoint sono disponi-

bili metodi per accedere alle coordinare e fare il prodotto con uno scalare.

Il calcolo del vettore che passa per due punti e delegato ad una funzione

esterna, cosı come sono esterne le funzioni per calcolare la distanza, fare

la combinazione baricentrica, il disegno e l’input/output.

7.5.2 fbStraightLine

fbStraightLine implementa una retta (rappresentata in forma implicita

con coefficienti a, b, c) ed ha i metodi necessari per: calcolare la retta

normale in un punto; le intersezioni (con altre rette, segmenti, o curve);

il disegno; etc..

7.5.3 fbVector

fbVector permette di effettuare tutte le operazioni su un vettore di di-

mensione arbitraria.

7.5.4 fbMatrix

fbMatrix e stato realizzato per operare con matrici di dimensione massima

di 4 × 4. Permette di calcolare il determinante e l’inversa; gestisce il

10E, pero, permessa l’operazione di combinazione baricentrica (vedi [10]).11I punti tri e quadridimensionali sono stati resi disponibili per eventuali estensioni

future.

81

Page 90: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

7. IL PROGRAMMA FASPED

prodotto con i vettori (distinguendo un vettore riga da uno colonna).

La struttura dati utilizzata per la memorizzazione delle componenti e

compatibile con quella utilizza da OpenGL (le operazioni con fbMatrix

possono essere passate in modo coerente ad OpenGL).

7.5.5 fbOperation

In precedenza e stato detto che, per l’algoritmo di de Casteljau, abbiamo

voluto separare l’algoritmo dalla particolare operazione. Questo e reso

possibile dalla classe astratta fbOperation. fbOperation obbliga le classi

da lei derivate ad implementare un metodo che restituisce un valore di

tipo double. Le classi derivate da fbOperation, che calcolano il valore

di una particolare operazione (ad esempio un potenziale), possono, cosı,

essere facilmente sostituite.

82

Page 91: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

Capitolo 8

Lavori futuri

Durante la presentazione del lavoro svolto per questa tesi, abbiamo sug-

gerito le possibili estensioni che potrebbero essere fatte in futuro. In

questo capitolo ci proponiamo di riassumerle e spiegare le linee guida che

potrebbero essere seguite.

8.1 Line Library

Lo strumento Arrow permette la manipolazione di una singola linea

sfruttando delle funzioni potenziali semplici (famiglia a coseno rialzato,

funzioni esponenziali). Si potrebbe pensare di utilizzare delle funzioni

con forme complesse che, invece di spostare la linea. la deformino pro-

gressivamente. Potremmo cosı riuscire a fornire una libreria di linee,

(linee arricciate, linee a dente di sega, etc.) da utilizzare per il disegno,

analogamente a quella offerta dall’utilizzo delle wavelets.

8.2 Feature del disegno

Un’altra strada da percorrere e quella di fornire strumenti associati alle

“feature” del disegno. Analogamente al Bender questi strumenti per-

mettono di effettuare manipolazioni di “oggetti grafici”. L’idea che si

83

Page 92: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

8. LAVORI FUTURI

vorrebbe portare avanti e di associare un movimento prestabilito a par-

ticolari caratteristiche del disegno (come le cuspidi o gli archi). Volendo

realizzare uno strumento di questo genere, il primo passo sarebbe di ri-

conoscere la forma assunta dal tratto che si vuole manipolare e quindi

muoverlo, riconducendosi al modello generale.

84

Page 93: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

Appendice A

Appendice A

A.1 Codice Sorgente

In questa appendice sono presenti i file delle dichiarazioni (header) del-

le classi utilizzate in Fasped. Il codice completo puo essere richiesto

all’autore presso l’indirizzo di posta elettronica: [email protected].

A.1.1 fbArrow//———————————————————//// FILENAME : fbArrow.h//// CLASS(ES) : fbArrow//// DESCRIPTION : Tool per la gestione delle linee senza// modificare i pti di controllo//// DATE : 12/11/2000// COPYRIGTH : (C) 2000 by Fabrizio Morciano// E MAIL : [email protected]////———————————————————#ifndef FB ARROW H#define FB ARROW H

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000

#include fbTool.h

#include fbPolyLine.h

#include fbConfig.h

#include fbCurveHierarchical.h

/∗!fbArrow: Tool per la gestione delle linee senza

modificare i pti di controllo∗/

class fbArrow : public fbTool{private:

//! Valore del minimo della curva selezionatafbDouble m dTOfMinimum;

//! Iteratore alla SetLine da spostare (offset rispetto al SetLine in cui si trova)itSetLine m itSLToMove;

fbPolyLine∗ m pPLLeft;

85

Page 94: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

fbPolyLine∗ m pPLLeftCopy;fbPolyLine∗ m pPLRight;fbPolyLine∗ m pPLRightCopy;fbInt

m nCurveToReduceLeft ,m nCurveToReduceRight;

public:void ReplaceCurves();void MoveCurves();void FindCurves();

fbArrow(fbFasped∗ pFasped);

virtual ∼fbArrow();

void HandleMouse(const fbUInt nButtonPressedAndStatus,const fbDouble x,const fbDouble y);

void HandleMouseMove(const fbUInt nButtonPressedAndStatus,const fbDouble x,const fbDouble y);

void Clear();

void InitGL();

void Draw();};

#endif // !defined( FB ARROW H )//———————————————————// End Of File//———————————————————

A.1.2 fbAutoSwitch//———————————————————//// FILENAME : fbAutoSwitch.h//// CLASS(ES) : fbCursor//// DESCRIPTION : La forza della rete neurale//// HISTORY : ??/??/2000//———————————————————#ifndef FB AUTOSWITCH H#define FB AUTOSWITCH H

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000

#include fbTool.h

class fbAutoSwitch : public fbTool{public:

// trova il quadrato opportuno dalla posizione del mouse

void InitGL();void Clear();

void HandleMouse (const fbUInt nButtonPressed, const fbDouble dPositionX, const fbDouble dPositionY);void HandleMouseMove (const fbUInt nButtonPressed, const fbDouble x, const fbDouble y);void Draw();

fbAutoSwitch(fbFasped∗);virtual ∼fbAutoSwitch();

private:

fbFloat m pCursor[4];};

#endif // !defined( FB AUTOSWITCH H )//———————————————————// End Of File//———————————————————

A.1.3 fbBender//———————————————————//// FILENAME : fbBender.h//// CLASS(ES) : fbBender//

86

Page 95: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

// DESCRIPTION : Il piegatore//// HISTORY : 03/11/2000//———————————————————#ifndef FB BENDER H#define FB BENDER H

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000

#include fbConfig.h

#include fbPoint.h

#include fbTool.h

#include fbStraightLine.h

#include fbCircle.h

#include fbPolyLine.h

#include <vector>

//!fbBender :Il Piegatore/∗!

Si occupa di piegare le curve intersecate dal segmento che lo descrive∗/class fbBender : public fbTool{

//! Vettore di offset di disegnofbFloat m pCursor[6];

//! Bilancino selezionato al clickfbInt m nSelectedCircle;

//! Due bilancini per il disegnofbCircle m Anchors[2];

//! Posizione del II pto clickatofbPoint m SecondPoint[2];

//! Quante volte e’ stato fatto clickfbInt m nClickCounter;

//! Corregge la selezione non perfetta del toolfbVector m VectorOfCorrection;

//! Vettore per la direzione dell’alto rispetto al toolfbVector m Up;

//! Puntatori alle curve di raccordo sul linkPolyLine m lCurveForLink;

//! Puntatori alle curve di raccordo sul linkPolyLine m lCurveForLinkCopy;

//! Puntatori alle curve da muoverePolyLine m lCurveToMove;

//! Puntatori alle curve da muoverePolyLine m lCurveToMoveCopy;

//! iteratore alla polyline nel frameitSetLine m itToPolyLineInFrame;

//! Controlla che sia avvenuta almeno una rotazione (trascinamento del mouse)fbBool m bIsRotated;

public:

//! Trova e sposta le curve individuate dal bendervoid FindAndMoveCurves();

//! Divide la curva e aggiunge i valori modificati alle curve di Link e di MovimentofbDouble SplitCurve(fbCurve∗ pCurve,std::vector<fbDouble>& vT, PolyLine& PLine);

//! Trova le curve di raccordo e di movimentovoid FindCurves();

enum{

FB BENDER ANCHOR 1 = 0, // etichetta per il cerchietto a sxFB BENDER ANCHOR 2 = 1, // etichetta per il cerchietto a dxFB BENDER ANCHOR = 3, // etichetta per la traslazioneFB BENDER SHAPE CIRCULAR , // rimpiazza le curve con le ruotateFB BENDER SHAPE SUBDIVIDED , // rimpiazza le curve con le suddiviseFB BENDER SHAPE INTERPOLATED, // rimpiazza le curve con una versione che media tra i pti di

controllo};

//! Ritorna il bilancino selezionato al clickfbInt FindAnchor(const fbPoint& Point);

void InitGL();

87

Page 96: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

void Draw();void HandleMouseMove (const fbUInt nButtonPressed, const fbDouble x, const fbDouble y);void HandleMouse (const fbUInt nButtonPressed, const fbDouble dPositionX, const fbDouble dPositionY);void Clear();fbBender(fbFasped∗);virtual ∼fbBender();

};

#endif // !defined( FB BENDER H )//———————————————————// End Of File//———————————————————

A.1.4 fbBSpline//———————————————————//// FILENAME : fbBSpline.h//// CLASS(ES) ://// DESCRIPTION ://// DATE : Sun Mar 11 2001// COPYRIGTH : (C) 2001 by Fabrizio Morciano// E MAIL : [email protected]////———————————————————

#ifndef FB BSPLINE H#define FB BSPLINE H

#include fbConfig.h

#include fbGrOb.h

#include fbPoint.h

#include fbPolyLine.h

#include <vector>

/∗∗Classe per la gestione di una BSpline∗@author Fabrizio Morciano∗/

class fbBSpline : public fbGrOb{private:

/∗∗ Nodi della spline ∗/std::vector<fbDouble> m vKnots;/∗∗ Punti di controllo ∗/std::vector<fbPoint> m vCtrlPnts;/∗∗ Grado della BSpline ∗/fbInt m nDegree;/∗∗ Domini intervallo ∗/fbInt m nL;/∗∗ Flag di controllo dati ∗/fbBool m bIsValid;/∗∗ Vettore con le componenti della base∗/fbVector m vBasisValue;

public:fbBSpline();

fbBSpline( const fbInt nDegree ,\const fbInt nL ,\const fbDouble∗ px ,\const fbDouble∗ py ,\const fbDouble∗ pKnots );

fbBSpline( const fbInt nDegree ,\const fbInt nL ,\const fbFloat ∗ px ,\const fbFloat ∗ py ,\const fbFloat ∗ pKnots );

fbBSpline( const fbInt nDegree ,\const std::vector<fbPoint> &vPnts ,\const std::vector<fbDouble> &vKnotw );

∼fbBSpline();

/∗∗ Metodo di display ∗/void Draw();

/∗∗ Metodo di inizializzazione ∗/void InitGL();

/∗∗ Ritorna il pto il cui parametro e’ dD o infinito se errore∗/fbPoint GetPoint(const fbDouble dD);

/∗∗ Ritorna il valore della base per dD o infinito se errore∗/

88

Page 97: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

fbDouble GetBasis(const fbDouble dD);

/∗∗ Ritorna il valore della base per dD o infinito se errore∗/fbDouble GetBasis(const fbDouble dD,const fbInt nL, const fbInt nDegree);

/∗ Dovrebbe ritornare la derivata parziale della Bspline∗/fbDouble GetDerivateBasis(const fbDouble dD,fbInt& nL);

/∗∗ Ritorna il valore delle basi non nulle per dD selezionando il grado da (0 a 3)∗/fbVector& GetColumnOfBasis(const fbDouble dD, fbInt& nP,const fbInt nColumn=3);

/∗∗ Ritorna l’indice dell’intervallo ∗/inline fbInt findL(const fbDouble dU){

if(dU >= 0 && dU < m vKnots[0] )return 0;

fbUInti;

for(i=1; i<m vKnots.size() ; i++){

if ( dU >= m vKnots[i-1] && dU < m vKnots[i])return i;

}

if( dU == m vKnots.back() ){

for(i=m vKnots.size() - 1 ; i > 0 ; i– –){

if ( dU != m vKnots[i])return i;

}}

return FB ERROR;}

/∗∗ Ritorna il punto di indice i o il primo ∗/fbPoint& CtrlPoint(const fbUInt i);

/∗∗ Ritorna il nodo di indice i o il primo ∗/fbDouble& GetKnot(const fbUInt i);

/∗∗ Fissa il grado ∗/inline void SetDegree(const fbInt nDegree);/∗∗ Ritorna il grado ∗/inline fbInt GetDegree() const ;

/∗∗ Fissa i numeri di intervalli base∗/inline void SetInterval(const fbInt nL);/∗∗ Ritorna il numero di intervalli base∗/inline fbInt GetInterval() const;

/∗∗ Fissa i punti di controllo di una BSpline ∗/void SetCtrlPoints ( const std::vector<fbPoint>& vCtrlPnts );

/∗∗ Ritorna i punti di controllo della BSpline∗/std::vector<fbPoint>& GetCtrlPoints ();

/∗∗ Fissa i nodi di una BSpline ∗/void SetKnots ( const std::vector<fbDouble>& vKnots );

/∗∗ Ritorna il vettore dei nodi∗/std::vector<fbDouble>& GetKnots ();

void InitBSpline();/∗∗ Metodo per prendere il punto derivato in dD ∗/fbPoint GetDerivatePoint(const fbDouble dD);

friend std::ostream& operator �(std::ostream &os, fbBSpline∗ pCurve);friend std::ostream& operator �(std::ostream &os, fbBSpline& pCurve);friend std::istream& operator �(std::istream &is, fbBSpline∗ pCurve);friend std::istream& operator �(std::istream &is, fbBSpline& pCurve);

};

/∗∗ Fissa il grado ∗/inline void fbBSpline::SetDegree(const fbInt nDegree){

this→m nDegree = nDegree;}

/∗∗ Fissa il grado ∗/inline fbInt fbBSpline::GetDegree() const{

return this→m nDegree;}

89

Page 98: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

/∗∗ Fissa il grado ∗/inline void fbBSpline::SetInterval(const fbInt nL){

this→m nL = nL;}

/∗∗ Fissa il grado ∗/inline fbInt fbBSpline::GetInterval() const{

return this→m nL;}

inline std::vector<fbPoint>& fbBSpline::GetCtrlPoints (){

return this→m vCtrlPnts;}

inline std::vector<fbDouble>& fbBSpline::GetKnots (){

return this→m vKnots;}

#endif

//———————————————————// End Of File//———————————————————

A.1.5 fbCircle//———————————————————//// FILENAME : fbCircle.h//// CLASS(ES) : fbCircle//// DESCRIPTION : classe per la gestione di un cerchio//// HISTORY ://———————————————————#ifndef FB CIRCLE H#define FB CIRCLE H

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000

#include fbGrOb.h

#include fbConfig.h

#include fbPoint.h

#include fbPolyLine.h

#include <vector>

/∗!fbCircle Classe per la gestione di un cerchio∗/

class fbCircle : public fbGrOb{private:

//!Centro del cerchiofbPoint m Center ;

//! raggiofbDouble m dRadius;

//!Passo a cui viene effettuato il disegnofbDouble m dStep;

// raggio al quadratofbDouble m dRadius 2;

//! Disegna i pti simmetricivoid drawSimmetricPoints(const fbDouble& ,const fbDouble& ,const fbDouble& ,const fbDouble& );

public:

fbCircle();

//! Costruttore: il raggio se negativo viene preso il valore assolutofbCircle(const fbPoint& Center,const fbDouble dRadius);

virtual ∼fbCircle();

/∗! 2 2 2ritorna la soluzione di x +y -r + tol se < 0 internose > 0 esterno se ==0 sulla circonferenzaN.B e’ al quadrato∗/

fbDouble metaCheckPointInCircle(const fbPoint& Point) const;

90

Page 99: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

fbDouble metaCheckPointInCircle(const fbDouble x,const fbDouble y) const;

//! Fissa il raggio se negativo viene preso il valore assolutovoid SetRadius(const fbDouble& dRadius);

//! Ritorna il centroinline fbPoint GetCenter() const;

//! Fissa la posizione del centroinline void SetCenter(const fbPoint& Center);

//! Ritorna il raggioinline fbDouble GetRadius() const;

//! Fa accedere il visitorvoid AcceptVisitor(fbVisitor∗ pVisitor);

void Draw();

/∗!Effettua le inizializzazioni necessarie persettare le dimensioni in funzione della scala

∗/void InitGL();

/∗! Funzione che ritorna l’intersezione di una cerchio con una retta i valori ottenutipossono essere 0 1 o 2 e possono essere testati dalla dimensione del vettore di pti in uscita

∗/friend void fbCircleIntersectionWithStraightLine(const fbCircle& Circle,const fbStraightLine

StraightLine,std::vector<fbPoint>& vecRes);};

/∗———————————————————∗\|∗ Espansione inline per la class fbCircle ∗||∗ BEGIN ∗|\∗———————————————————∗/

inline void fbCircle::SetCenter(const fbPoint& Center){

m Center=Center;}

inline fbDouble fbCircle::GetRadius() const{

return m dRadius;}

inline fbPoint fbCircle::GetCenter() const{

return m Center;}

/∗———————————————————∗\|∗ END ∗||∗ Espansione inline per la class fbCircle ∗|\∗———————————————————∗/

/∗!Converte un cerchio in una polyline

∗/void fbCircleToPolyLine(const fbCircle& Circle,PolyLine & PLine,const fbDouble dAngle0,const fbDoubledAngle1,const fbDouble dTolerance);

#endif // !defined( FB CIRCLE H )//———————————————————// End Of File//———————————————————

A.1.6 fbClamp//———————————————————//// FILENAME : fbClamp.h//// CLASS(ES) ://// DESCRIPTION://// DATE : Wed Feb 28 2001// COPYRIGTH : (C) 2001 by Fabrizio Morciano// E MAIL : [email protected]////———————————————————

#ifndef FBCLAMP H#define FBCLAMP H

91

Page 100: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

/∗∗Classe per la gestione di valori di campo∗@author Fabrizio Morciano∗/

template <class T> class fbClamp{private :

//! Valore assegnatoT m Val;//! Valore di minimoT m Minimum;//! Valore di massimoT m Maximum;

inline T test(T Min, T Val, T Max ){

return (Val < Min) ? Min : (Val > Max) ? Max : Val;}

public :

fbClamp():m Val ( 0 ),m Minimum( 0 ),m Maximum( 0 ){}

fbClamp(T val):m Val ( val ),m Minimum( val ),m Maximum( val ){}

fbClamp(T min, T val, T max ):m Val ( val ),m Minimum( min ),m Maximum( max ){

val = test( min, val, max );}

fbClamp(const fbClamp& pToCopy){

if( &pToCopy == this )return;

m Val = pToCopy→m Val ;m Minimum = pToCopy→m Minimum ;m Maximum = pToCopy→m Maximum ;

}

∼fbClamp(){}

fbClamp& operator=(const fbClamp& pToCopy){

if( &pToCopy == this )return ∗this;

m Val = pToCopy.m Val ;m Minimum = pToCopy.m Minimum ;m Maximum = pToCopy.m Maximum ;

return ∗this;}

T& operator=(const T& val){

return ( this→m Val = test( m Minimum, val, m Maximum ) );}

T& operator∗(){

return this→m Val;}

T& operator()(){

return this→m Val;}

T& Max(){

return this→m Maximum;}

T& Min(){

return this→m Minimum;}

};

92

Page 101: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

template <class T> std::ostream& operator�(std::ostream &os, fbClamp<T>& val){

return os�∗val;}

template <class T> std::ostream& operator�(std::ostream &os, fbClamp<T>∗ val){

return os�∗∗val;}

template <class T> std::istream& operator�(std::istream &is, fbClamp<T>& val){

return os�∗val;}

#endif // FBCLAMP H//———————————————————// End Of File//———————————————————

A.1.7 fbConfig//———————————————————//// FILENAME : fbConfig.h//// CLASS(ES) ://// DESCRIPTION : File di configurazione per le piattaforme//// HISTORY : 18/08/2000// 06/01/2001 inserita macro FB WIN32 LIB per problemi// d’inclusione con Matrix Template Library//———————————————————#ifndef FBCONFIG H#define FBCONFIG H

// Definizione di tipotypedef bool fbBool ;typedef char fbChar ;typedef short fbShort ;typedef int fbInt ;typedef long fbLong ;typedef float fbFloat ;typedef double fbDouble;typedef unsigned short fbUShort;typedef unsigned int fbUInt;typedef unsigned long fbULong;

const fbInt FASPED MINOR VERSION = 0;const fbInt FASPED MAJOR VERSION = 0;

// Dichiarazioni di MACRO per i controlli matematica#ifdef WIN32

#define FB NAMESPACE SUPPORT 1

#if MSC VER > 1000// disabilito i warning di template troppo lunghi#pragma warning( disable : 4786 )

#endif

# ifdef FB MFC PROJECT# include stdafx.h

# elif FB WIN32 LIB# include <windows.h># endif

#include <float.h>#include <limits.h>

const fbDouble FB DOUBLE MAX = DBL MAX;const fbDouble FB DOUBLE MIN = DBL MIN;

const fbFloat FB FLOAT MAX = FLT MAX;const fbFloat FB FLOAT MIN = FLT MIN;

const fbInt FB INT MAX = INT MAX;const fbInt FB INT MIN = INT MIN;

#elif defined( GNUC ) // else WIN32 if GNUC

#include <limits.h>#include <cstdio>#include <cstdlib>

#if defined(LINUX) // if LINUX

93

Page 102: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

#include <values.h>#include <cstdio>#include <cstdlib>

const fbDouble FB DOUBLE MAX = DBL MAX;const fbDouble FB DOUBLE MIN = DBL MIN;

const fbFloat FB FLOAT MAX = FLT MAX;const fbFloat FB FLOAT MIN = FLT MIN;

#else // if ! LINUX

const fbDouble FB DOUBLE MAX = 1E 128 ;const fbDouble FB DOUBLE MIN = 1E-128 ;

const fbFloat FB FLOAT MAX = 1E 64 ;const fbFloat FB FLOAT MIN = 1E-64 ;

#endif // end LINUX

const fbInt FB INT MAX = INT MAX;const fbInt FB INT MIN = INT MIN;

#elif // If Unkown

#error Inserire il codice per le altre piattaforme

#endif // end WIN32

const fbUInt FB NULL = 0x0000;const fbInt FB ERROR =-1 ;

// I valori si trovano in fbFasped.cpp

extern const fbDouble FB PICK RAY ; //= 10.0 Raggio di pick (N.B. in pixel)extern const fbDouble FB EPSILON ; //= 1.0E-6 Tolleranza di defaultextern const fbDouble FB TOLERANCE ; //= .01extern const fbDouble FB PIXEL SIZE ; //= .01 Dimensione di un pixel (pixel / cm)extern const fbDouble FB RENDER QUALITY MAX; //= 0.125 Limiti di qualita’ di disegno (non usati)extern const fbDouble FB RENDER QUALITY MIN; //= 2.0extern const fbDouble FB MINIMUM DIVISION NUMBER; //= 15.0

// Dichiarazioni di MACRO per gli eventi del Mouseconst fbUInt FB MOUSE LEFT = 0x0001;const fbUInt FB MOUSE MIDDLE = 0x0002;const fbUInt FB MOUSE RIGHT = 0x0004;

const fbUInt FB MOUSE UP = 0x0010;const fbUInt FB MOUSE DOWN = 0x0020;

const fbUInt FB MOUSE MASK = 0x00FF;const fbUInt FB MOUSE MASK STATUS = 0x00F0;const fbUInt FB MOUSE MASK BUTTON = 0x000F;

// Dichiarazioni di MACRO per gli eventi di Keyboardconst fbUInt FB KEY UP = 0x0100;const fbUInt FB KEY DOWN = 0x0200;const fbUInt FB KEY CTRL = 0x0400;const fbUInt FB KEY ALT = 0x0800;const fbUInt FB KEY SHIFT = 0x0A00;

const fbUInt FB KEY MASK = 0x0F00;

// Qualche Macro per accelerare la scrittura di un coloreconst fbFloat FB RED [ ] = {1.0f,0.0f,0.0f,1.0f};const fbFloat FB GREEN [ ] = {0.0f,1.0f,0.0f,1.0f};const fbFloat FB BLUE [ ] = {0.0f,0.0f,1.0f,1.0f};const fbFloat FB YELLOW [ ] = {1.0f,1.0f,0.0f,1.0f};const fbFloat FB CYAN [ ] = {0.0f,1.0f,1.0f,1.0f};const fbFloat FB MAGENTA[ ] = {1.0f,0.0f,1.0f,1.0f};

const fbFloat FB WHITE [ ] = {1.0f,1.0f,1.0f,1.0f};const fbFloat FB BLACK [ ] = {0.0f,0.0f,0.0f,1.0f};const fbFloat FB GRAY1 [ ] = {0.9f,0.9f,0.9f,1.0f};const fbFloat FB GRAY2 [ ] = {0.7f,0.7f,0.7f,1.0f};const fbFloat FB GRAY3 [ ] = {0.5f,0.5f,0.5f,1.0f};const fbFloat FB GRAY4 [ ] = {0.3f,0.3f,0.3f,1.0f};const fbFloat FB GRAY5 [ ] = {0.1f,0.1f,0.1f,1.0f};

#ifdef WIN32# define FB SLASH \\\\# define FB RESOURCES res

#else

# define FB SLASH /

# define FB RESOURCES ../res

#endif // ifdef WIN32

// Dichiarazioni di MACRO per il debug

94

Page 103: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

#if defined( DEBUG) || defined (DEBUG)# define FB DEBUG 1#endif // if defined( DEBUG) || defined (DEBUG)

#ifdef WIN32

# if defined(FB DEBUG)&& defined(FB MFC PROJECT)# define FB TRACE TRACE# else

# define FB TRACE(a) {fprintf(stderr,a);}# endif //if defined(FB DEBUG)&& defined(FB MFC PROJECT)

#else

# ifdef FB DEBUG# define FB TRACE printf# else

# define FB TRACE printf# endif //ifdef FB DEBUG

#endif //ifdef WIN32

#ifdef FILE# define FB STUB FILE FILE#else

# define FB STUB FILE ((const char ∗)0L)#endif // ifdef FILE

#ifdef LINE# define FB STUB LINE LINE#else

# define FB STUB LINE 0#endif // ifdef LINE

#ifdef FUNCTION# define FB STUB FUNC FUNCTION#else

# define FB STUB FUNC ((const char ∗)0L)#endif // ifdef FUNCTION

/∗FB STUB(): this is the method which prints out stubinformation. Used where there is functionality missing.

∗/

#if FB DEBUG

# define FB STUB() \do { \

(void)fprintf(stderr, STUB: functionality not yet completed); \if (FB STUB FILE) { \

(void)fprintf(stderr, at %s, FB STUB FILE); \if (FB STUB LINE > 0) (void)fprintf(stderr, :line %u, FB STUB LINE); \if (FB STUB FUNC) (void)fprintf(stderr, :[%s], FB STUB FUNC); \

} \(void)fprintf(stderr, \n); \

} while (0)

#else

# define FB STUB() do { } while (0)

#endif // if FB DEBUG

#endif //!defined( FBCONFIG H )//———————————————————//End Of File//———————————————————

A.1.8 fbCursor//———————————————————//// FILENAME : fbCursor.h//// CLASS(ES) : fbCursor//// DESCRIPTION : classe per la gestione del cursore openGL//// HISTORY : 07/09/2000//———————————————————#ifndef FB CURSOR H#define FB CURSOR H

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000

95

Page 104: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

#include fbConfig.h

#include fbPoint.h

#include fbTool.h

#include fbStraightLine.h

#include fbCircle.h

#include <vector>#include fbPolyLine.h

class fbPolyLine;/∗!

fbCursor Classe che gestisce un cursore video di forma opportuna∗/

class fbCursor : public fbTool{

//! Pti che descrivono il toolfbDouble m pCursor[4];

public:void Clear();

fbCursor(fbFasped∗ pAppl);

virtual ∼fbCursor();

void HandleMouseMove(const fbUInt nButtonPressed,const fbDouble dXPosition,const fbDoubledYPosition);

void HandleMouse(const fbUInt nButtonPressed,const fbDouble dPositionX,const fbDouble dPositionY);

void Draw();

void InitGL();

};

#endif // !defined( FB CURSOR H )//———————————————————// End Of File//———————————————————

A.1.9 fbCurve//———————————————————//// FILENAME : fbCurve.h//// CLASS(ES) : fbCurve//// DESCRIPTION : classe per la gestione di una cubica OpenGL//// HISTORY : 09/08/2000// 13/08/2000 cambiato il tuipo di m nShowCtrlPoints GLenum -> fbLong// rinominate le funzioni To -> Of// rimosso codice gestione linea spessore// 08/09/2000 codice gestione curve multiple//———————————————————#ifndef FB CURVE H#define FB CURVE H

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000

#include fbGrOb.h

#include fbPoint.h

#include fbConfig.h

#include fbStraightLine.h

#include <vector>#include <list>

class fbCurve;

typedef std::list<fbCurve∗> PolyLine;/∗!fbCurve: classe di gestione per un arco di spline∗/

class fbOperation;class fbRectangle;

class fbCurve : public fbGrOb{protected:

fbDouble ∗Reparametrize(const std::vector<fbPoint>& p,const fbDouble ∗v1);

void setMinMaxBox();

static fbInt s nSubdivisionCounter;

96

Page 105: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

//! Retta per i vari controllistatic fbStraightLine m ManagementStraightLine;

//! Pti di controllo per la gestione della lineafbPoint ∗m pCtrlPoints;

//! Pto aggiuntivo che fissa il bottom left del minmax della curvafbPoint m MinMaxBottomLeft;

//! Variabile per il grado della curvafbInt m nOrder;

//! Variabile di gestione del tipo di oggetto da disegnare (tangente - poliedro -minmax)fbInt m nObjectType;

//! Lungezza della curvafbDouble m dLenght;

//! Distanza dell’ultimo pto testato dalla curvafbDouble m dPointDistance;

//! Valore della t che compete al pto della curva piu’ vicino al pto testatofbDouble m dTValue;

//! Valore dell’indice del vettore per cui si registra il massimo errorefbInt m nIndexOfMaxSqrError;

//! Valore del massimo errore quadratico trovatofbDouble m dMaxSqrError;

//! Valore di soglia per il calcolo delle curvefbDouble m dThreshold;

void subdivide(const fbDouble p1x,const fbDouble p1y,\const fbDouble p2x,const fbDouble p2y,\const fbDouble p3x,const fbDouble p3y,\const fbDouble p4x,const fbDouble p4y,\const fbDouble t0 ,const fbDouble t1,fbOperation∗ Op);

public:

inline fbInt GetIndexOfMaxSqrError() ;

inline fbDouble GetMaxSqrError() ;

fbDouble ComputeMaxError(const std::vector<fbPoint>& vPnts,const fbDouble∗ );

void GenerateCubic(const std::vector<fbPoint>& vPnts,fbDouble∗& dt ,const fbVector&,const fbVector&);

void GenerateCubicMinSqr(const std::vector<fbPoint>& vPnts, fbDouble∗& dt);

void GenerateCubicWithG1Condition(const std::vector<fbPoint>& vPnts,fbDouble∗& dt ,const fbVector& TangentLeft );

void GenerateCubicWithTangentCondition(const std::vector<fbPoint>& vPnts,fbDouble∗& dt ,const fbVector& TangentLeft ,\const fbVector& TangentRight );

fbDouble GetAlpha(const std::vector<fbPoint>& vLeft,const std::vector<fbPoint>& vRight);

//! Ritorna la curvatura con segno nel parametrofbDouble GetCurvature(const fbDouble dTVal);

//! Ritorna la lunghezza del piu’ piccolo segmento di poligonalefbDouble GetMinimumSegment(const fbDouble dTol = FB ERROR);

void InitGL();

//! Ritorna il rettangolo di MinMaxBoxfbRectangle GetMinMaxBox() const;

//! ritorna l’arco a dx rispetto a dValuefbCurve∗ GetLeftArc(const fbDouble dValue);

//! ritorna l’arco a dx rispetto a dValuefbCurve∗ GetRightArc(const fbDouble dValue);

//! Ritorna la lunghezza della curva con una precisione fissata (se default quella video)fbDouble GetLenght(const fbDouble dPrecision=FB ERROR);

//! Ritorna la t che compete al pto della curva piu’ vicino a PointfbDouble SelectPoint(const fbPoint& Point, const fbDouble dPickRay);

//! Fissa il tipo di oggetto da disegnare per la curva/∗!Metodo che in funzione del tipo nType (tra quelli presenti in fbCurve)

97

Page 106: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

disegna oltre alla curva elementi aggiuntivi (MINMAX,CONTROL POINTS, TANGENTI,ETC)∗/inline void SetObjectType(const fbInt nType);

//! Visualizza vari oggett in funzione del tipo correntemente settatovoid DrawObjects();

//! Tipo per la selezione del tipo di oggetti da visualizzareenum{

FB CURVE P1 = 0, //! Riferimento al primo pto di controlloFB CURVE P2 = 1,FB CURVE P3 = 2,FB CURVE P4 = 3,FB CURVE NOT OBJECT , //! Nessun oggetto da visualizzareFB CURVE TAN 1 , //! Visualizza la tangente per P0 P1FB CURVE TAN 2 , //! Visualizza la tangente per P2 P3FB CURVE TAN ALL , //! Visualizza entrambe le tangentiFB CURVE CONVEX HULL, //! Visualizza l’involucro convessoFB CURVE MINMAX , //! Visualizza la minmax boxFB CURVE CTRL PNTS ALL , //! Visualizza tutti i pti di controlloFB CURVE CTRL PNTS F L , //! Visualizza il primo e l’ultimoFB CURVE CTRL PNTS AND TAN ,FB CURVE SUBDIVISION PIXEL SIZE , //! Divide la curva in pezzi di lunghezza pari alla

poligonale a videoFB CURVE SUBDIVISION UNIFORM , //! Divide la curva in pezzi pari al passo selezionatoFB CURVE SUBDIVISION FOR LENGHT , //! Divide la curva rispetto in 2 rispetto alla lunghezza

desiderataFB CURVE IS IN REGION = -1, //! Ritorna se la curva e’ interna ad una regioneFB CURVE INTERSECT REGION = -2, //! Ritorna se la curva interseca una regioneFB CURVE IS OUT REGION = -3 //! Ritorna se la curva e’ completamente esterna ad una regione

};

//! Seleziona un pto di controllo della curva/∗! Ritorna un offset o FB ERROR se il pto e’ piu’ distante di dPickRay da PointN.B. dPickRay e’ assunto essere il quadrato del valore di raggio di pickin tal modo le distanze sono controllate senza calcolare le radici∗/fbInt SelectByControlPoint(const fbPoint& Point,const fbDouble dPickRay);

fbPoint GetPoint(const fbDouble tVal) const;

//! CostruttorefbCurve();

//! Costruttore per 4 tpifbCurve(const fbPoint& p1,const fbPoint& p2,const fbPoint& p3,const fbPoint& p4);

//! Costruttore per 4 tpi e dimensione pixelfbCurve(const fbPoint& p1,const fbPoint& p2,const fbPoint& p3,const fbPoint& p4,const fbDouble

dPixelSize);

//! Costruttore di copiafbCurve(const fbCurve& Curve);

//! Costruttore pe interpolazione ai minimi quadratifbCurve(const std::vector<fbPoint>& vPnts,\

const fbVector& TangentLeft,\const fbVector& TangentRight,const fbDouble dTolerance);

//! Distruttorevirtual ∼fbCurve();

//! Metodo che disegna le curvevirtual void Draw();

//! Ritorna i pti di controllo della lineavoid GetCtrlPoints(fbPoint& p1,fbPoint& p2,fbPoint& p3,fbPoint& p4);

//! Ritorna i pti di controllo della curvainline fbPoint∗ GetCtrlPoints();

//! Fissa i pti di controllo della lineainline void SetCtrlPoints(const fbPoint& p1,const fbPoint& p2,const fbPoint& p3,const fbPoint& p4);

inline void SetCtrlPoints(const fbPoint ∗p);

void SetCtrlPoints(const fbDouble p1x,const fbDouble p1y,const fbDouble p2x,const fbDouble p2y, constfbDouble p3x,const fbDouble p3y, const fbDouble p4x,const fbDouble p4y);

//! Ritorna il grado della curvainline fbInt GetOrder() const;

//! Fissa il grado della curva (se il grado viene alzato i pti sono estrapolati in modo opportuno,// se abbassato li risultato e’ indefinito solo i pti iniziali sono garantiti)void SetCurveOrder(const fbInt nVal);

//! Metodo per controllare che il pto sia nel minmax della curva a meno di FB PICK RAY

98

Page 107: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

fbBool CheckPointInMinMax(const fbPoint &Point,const fbDouble RayOfPick) const;

//! Metodo per controllare che il pto sia nel convex hull della curva a meno di FB PICK RAYfbBool CheckPointInConvexHull(const fbPoint& Point,const fbDouble RayOfPick);

//! Metodo di copiafbCurve& operator=(const fbCurve&);

void AcceptVisitor(fbVisitor ∗ pVisitor);/∗!Metodo che calcola i valori di t che delimitano le parti strettamente convessedi una curva( cubica o quadrica ) i valori estratti sono tutti quelli validi in \f$\forall t \in [0,1]\f$Viene utilizzata la condizione che una curva descritta da \f$x(t),y(t)\f$e’ monotona rispetto agli assi se risulta che \f$x∧{’}(t)\cdot y∧{’}(t)>0\f$\f$ \forall t \in [\hat{t} 0,\hat{t} 1] \f$ in tale intervallo la curva puo’ essereconsiderata funzione strettamente monotona sia come \f$ x=x(t)\f$ sia come \f$ y=y(t) \f$.In un sotto intervallo \f$[\hat{t} 0,\hat{t} 1]\f$ di \f$[t 0,t 1]\f$ la curva e’ strettamenteconvessa se \f$ y∧{’}(t) \cdot x∧{”}(t) -y∧{”}(t) \cdot x∧{’}(t) > 0 (<0)\f$\f$\forall t \in [\hat{t} 0,\hat{t} 1]\f$ per la condizione di non annullamento della derivata seconda.Allora le radici delle 3 equazioni\f$x∧{’}(t)=0 \f$,\f$ y∧{’}(t)=0\f$, \f$y∧{’}(t) \cdot x∧{”}(t) -y∧{”}(t) \cdot x∧{’}(t) = 0 \f$ cherispettano il vincolo \f$\forall t \in [0,1]\f$ sono tutti i sotto intevalli in cui la curva e’ monotonae convessa.∗/void SplitInConvexInterval(std::vector<fbDouble>& vpTValues);

/∗∗ Calcola i coefficienti del polinomio di gradoopportuno equivalente a quello rappresentatoin polinomi di Bezier ∗/void BezierToPoly(std::vector<fbPoint>& vdCoeff) const ;

void BezierToPoly(std::vector<fbDouble>& vdCoeffX,std::vector<fbDouble>& vdCoeffY) const ;

fbPoint GetAcceleration(const fbDouble tVal);

fbPoint GetSpeed(const fbDouble tVal);

fbPoint GetTangent(const fbDouble tVal);

/∗!Calcola i valori del parametro in cui la curva deve essere suddivisasecondo il metodo stabilito in nTypeOfSubdivision∗/void GetValuesForSubdivision(std::vector<fbDouble>& vVectorOfValue,const fbInt

nTypeOfSubdivision,const fbDouble dInit,const fbDouble dTol = FB ERROR);

void IntersectionWithStraightLine (const fbStraightLine & StraightLine , std::vector<fbDouble>&vTOfIntersection);

void IntersectionWithSegment (const fbSegment& Segm , std::vector<fbDouble>& vTOfIntersection);

fbInt IntersectionWithCircle (const fbCircle & Circle, std::vector<fbDouble>& vTOfIntersection);

fbPoint& operator [ ](const fbInt nCtrlPnt);

friend std::ostream& operator �(std::ostream &os, fbCurve ∗pCurve);friend std::ostream& operator �(std::ostream &os, fbCurve &pCurve);friend std::istream& operator �(std::istream &is, fbCurve ∗pCurve);friend std::istream& operator �(std::istream &is, fbCurve &pCurve);

private:

/∗!Metodo privato per inizializzare la procedura di suddivisione

∗/inline void subdivideInit(const fbDouble dTol = FB ERROR);

fbDouble m dVideoTolerance;};

/∗———————————————————∗\|∗ Espansione inline per la class fbCurve ∗||∗ BEGIN ∗|\∗———————————————————∗/

inline void fbCurve::SetObjectType(const fbInt nType){

m nObjectType = nType;}

inline fbPoint∗ fbCurve::GetCtrlPoints(){

SetInitGL(false);return &m pCtrlPoints[0];

}

inline void fbCurve::SetCtrlPoints(const fbPoint& p1,const fbPoint& p2,const fbPoint& p3,const fbPoint& p4){

SetCtrlPoints(p1.X,p1.Y,p2.X,p2.Y,p3.X,p3.Y,p4.X,p4.Y);}

inline void fbCurve::SetCtrlPoints(const fbPoint ∗p)

99

Page 108: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

{SetCtrlPoints(p[0].X,p[0].Y,p[1].X,p[1].Y,p[2].X,p[2].Y,p[3].X,p[3].Y);

}inline fbInt fbCurve::GetOrder() const{

return m nOrder ;}

inline void fbCurve::subdivideInit(const fbDouble dTol){

if(dTol == FB ERROR)m dVideoTolerance = GetTolerance() ∗ 0.5;

elsem dVideoTolerance = dTol;

s nSubdivisionCounter = 0;

}

inline fbInt fbCurve::GetIndexOfMaxSqrError(){

return m nIndexOfMaxSqrError;}

inline fbDouble fbCurve::GetMaxSqrError(){

return m dMaxSqrError;}/∗———————————————————∗\|∗ END ∗||∗ Espansione inline per la class fbCurve ∗|\∗———————————————————∗/

/∗!Restituisce un vettore con i valori del parametro in cui la curvae approssimabile ad una poligonale spezzata

FbErase:E’ orribile deve essere eliminata e rimpiazzata da un metodo

∗///void fbCurveRetrieveSubdivisionForTolerance(const fbCurve∗ pCurve,const fbDoubledTolerance,std::vector<fbDouble>& vInterval);

/∗!Confronta 2 curve e vede la posizione per cui differiscono per piu di tolviene utilizzata per il confronto la curva che maggior numero di suddivisioniFbErase:E’ orribile deve essere eliminata e rimpiazzata da un metodo

fbDouble fbCurveToCurveDistance(fbCurve∗ pCurve 1,fbCurve∗ pCurve 2,const fbDouble dTol);∗/

/∗! Raccorda la continuita’ fra 2 curve fissandola a nValFIXMEvoid fbCurveFixContinuity(fbCurve∗ pCurve left,fbCurve∗ pCurve right,const fbInt nVal,const fbDouble dTolerance);∗/

/∗! Cerca di ricondurre due archi in uno soloReturn:NULL se non e’ possibilenew fbCurve puntatore con la nuova curva∗/fbCurve∗ fbCurveTwoToOne( fbCurve∗ pCurve left,fbCurve∗ pCurve right,const fbDouble dTolerance);

/∗!Ritorna il valore di continuita’ mantenuto dalle due curveritorna FB ERROR se non c’e’ continuita’ o una delle 2 curve e NULLun valore tra 0 e 2∗/fbInt fbCurveGetContinuity(fbCurve∗ pCurve left,fbCurve∗ pCurve right,const fbDouble dTolerance);

/∗!Calcola le intersezioni tra 2 curve∗/fbBool fbCurveIntersectionWithCurve(fbCurve& pCurve,const fbCurve& Curve,const fbDoubledTolerance,std::vector<fbDouble>& vTOfIntersection);

#endif // !defined( FB CURVE H )//———————————————————// End Of File//———————————————————

A.1.10 fbDrawingPin//———————————————————

100

Page 109: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

//// FILENAME : fbDrawingPin.h//// CLASS(ES) : fbDrawingPin//// DESCRIPTION : Tool per la gestione del blocco e suddivisione di una curva//// HISTORY : 29/09/2000//———————————————————#ifndef FB DRAWING PIN H#define FB DRAWING PIN H

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000

#include fbConfig.h

#include fbTool.h

#include <list>#include fbPoint.h

/∗!fbDrawingPin: classe Tool che si occupa di gestire gli eventi del tool puntinaNel pto in cui viene inserita una puntina divide la curva in 2 partie fissa l’attivita’ del pto in modo tale da venir riconosciuto comevincolo dagli altri tool (quelli di spostamento)

∗/class fbDrawingPin : public fbTool{private:

//! Punti che descrivono il disegnofbFloat m pDrawingPin[6];

public:void Clear();

fbDrawingPin(fbFasped∗);virtual ∼fbDrawingPin();

//! Metodo di inizializzazionevoid InitGL();

void Draw();

void HandleMouseMove (const fbUInt nButtonPressed, const fbDouble dPositionX, const fbDoubledPositionY);

void HandleMouse (const fbUInt nButtonPressed, const fbDouble dPositionX, const fbDouble dPositionY);};

#endif // !defined( FB DRAWING PIN H )//———————————————————// End Of File//———————————————————

A.1.11 fbEllipse//———————————————————//// FILENAME : fbEllipse.h//// CLASS(ES) : fbEllipse//// DESCRIPTION : classe per la gestione di un’ellisse//// HISTORY : 14/11/2000//———————————————————#ifndef FB ELLIPSE H#define FB ELLIPSE H

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000

#include fbGrOb.h

#include fbPoint.h

#include fbConfig.h

#include fbStraightLine.h

class fbRectangle;

#include <vector>/∗!

fbEllipse : classe per la gestione di un’ellisseFIXME manca la gestione per mezzo dei fuochi

∗/class fbEllipse :public fbGrOb{

//! Baricentro

101

Page 110: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

fbPoint m Barycenter;

//! Vertici dell’ellissefbDouble m da;

//! Vertici dell’ellissefbDouble m db;

//! Tolleranza al quadratofbDouble m dSqrTolerance;

//! Disegna segmenti nei 4 quadrantivoid drawSimmetricPoints(const fbDouble x, const fbDouble y,const fbDouble x1, const fbDouble y1);

//! Si occupa di fare la suddivisione ed il disegnovoid subdivideAndDraw(const fbDouble dAngle0,const fbDouble dAngle1);

public:

fbEllipse();fbEllipse(const fbDouble a,const fbDouble b);fbEllipse(const fbDouble a,const fbDouble b,const fbPoint Barycenter);

virtual ∼fbEllipse();

//! Massimo grado di annidamento nella suddivisionestatic fbDouble s MaxDepth;

//! Fissa i valori dei vertici per l’ellisseinline void SetVertex(const fbDouble a,const fbDouble b);

//! Ritorna i valori correntir per i vertici dell’ellisseinline void GetVertex(fbDouble& a,fbDouble &b) const;

//! Fissa la posizione del baricentroinline void SetBarycenter(const fbPoint& p);

//! Ritorna la posizione del baricentroinline fbPoint GetBarycenter() const;

void Draw();void InitGL();

//! funzione che si occupa della divisione ricorsivafriend void subdivideEllipse(const fbEllipse& Ellipse,const fbDouble dAngle0,const fbDouble

dAngle1,void(∗MyFunc)(fbPoint&,fbPoint&,void∗),void∗ pUserData);};

inline void fbEllipse::SetVertex(const fbDouble a,const fbDouble b){

m da = a; m db = b;}

inline void fbEllipse::GetVertex(fbDouble& a,fbDouble &b) const{

a= m da; b=m db;}

inline void fbEllipse::SetBarycenter(const fbPoint& p){

m Barycenter = p;}

inline fbPoint fbEllipse::GetBarycenter() const{

return m Barycenter;}

/∗!Converte un’ ellisse in una polylineFIXME: E’ tremendamente ridondante

∗/void fbEllipseToPolyLine(const fbEllipse& Ellipse,PolyLine& PLine,const fbDouble dAngleFirst = 0,constfbDouble dAngleLast = FB 2 PI);

/∗!Converte un’ ellisse in una polylineFIXME: E’ tremendamente ridondante

∗/void fbEllipseToPolyLine(const fbRectangle& BBoxOfEllipse,PolyLine& PLine,const fbDouble dAngleFirst =0,const fbDouble dAngleLast = FB 2 PI);#endif // !defined( FB ELLIPSE H )//———————————————————// End Of File//———————————————————

A.1.12 fbException//———————————————————

102

Page 111: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

//// FILENAME : fbException.h//// CLASS(ES) : fbException//// DESCRIPTION : Classe per la gestione delle eccezioni//// HISTORY : 23/08/2000//———————————————————#ifndef FB EXCEPTION H#define FB EXCEPTION H

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000#include <string>

/∗!fbException Classe base per la gestione delle eccezioni

∗/class fbException{protected:

//! Stringa di messaggiostd::string m ExceptionMessage;

public:

fbException();fbException(const std::string sMessageError);virtual ∼fbException();

//! Metodo per mostrare l’eccezionevoid ShowException();

//! Metodo che contiene l’eventuale stringa informativa aggiuntivavirtual void ExceptionPrint() =0;

};

/∗!fbRangeException Classe per la gestione di eccezione di range

∗/class fbRangeException : public fbException{public:

fbRangeException();fbRangeException(const std::string&);virtual ∼fbRangeException();

void ExceptionPrint();};

#endif // !defined( FB EXCEPTION H )//———————————————————// End Of File//———————————————————

A.1.13 fbFasped//———————————————————//// FILENAME : fbFasped.h//// CLASS(ES) : fbFasped//// DESCRIPTION ://// HISTORY : ??/??/2000//———————————————————#ifndef FB FASPED H#define FB FASPED H

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000

#include fbPoint.h

#include fbWindow.h

#include fbConfig.h

#include fbClamp.h

#include <list>

class fbFrame;

typedef std::list<fbFrame∗> SetFrame;typedef SetFrame::iterator itSetFrame;typedef SetFrame::const iterator citSetFrame;

103

Page 112: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

class fbFasped : public fbWindow{

//! Lista di puntatori a FrameSetFrame m lpFrame;

//! Frame CorrentefbFrame∗ m pCurrentFrame;

//! Pagina di riferimento A4fbRectangle m A4Page;

//! Raggio di Pick in coordinate mondofbDouble m dPickRay;

//! Lunghezza di azione per gli algoritmi che non dipendono dalla parametrizzazionefbDouble m dLenghtForAction;

//! Parametro di controllo qualita’ di riduzionefbClamp<fbDouble> m dReductionQuality;

//! Numero che forza la divisione per curve troppo lunghefbInt m nNumberOfMinimumDivision;

//! Flag per l’algoritmo di riduzionefbBool m bReductionFlag;

public:

fbFasped();

virtual ∼fbFasped();

void InitGL();

/∗!La riduzione deve essere attiva o no

∗/inline void SetReductionFlag(const fbBool);

/∗!Stato del flag di riduzione

∗/inline fbBool GetReductionFlag() const;

/∗!Ritorna il valore di qualita’ di divisione

∗/inline fbDouble GetReductionQuality();

/∗!Fissa il valore di qualita’ di divisione

∗/inline void SetReductionQuality(const fbDouble dDivisions);

/∗!Ritorna la lunghezza su cui propagare lo spostamento per gli algoritmiindipendenti dalla parametrizzazione.

∗/inline fbDouble GetLenghtForAction() const;

/∗!Ritorna la lunghezza su cui propagare lo spostamento per gli algoritmiindipendenti dalla parametrizzazione.

∗/inline void SetLenghtForAction(const fbDouble dLofA);

/∗!Ritorna il raggio di pick per i tools di selezione

∗/inline fbDouble GetPickRay() const;

/∗!Fissa il frame corrente per la visualizzazione

∗/void SetCurrentFrame(fbFrame∗ pFrame);

/∗!Ritorna la lista dei frame caricati

∗/inline SetFrame& GetSetFrame();

/∗!Carica un frame nell’applicazione.∗/

void AddFrame(fbFrame∗ pFrame);

/∗!Ritorna un puntatore al frame corrente attivo∗/

104

Page 113: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

inline fbFrame∗ GetFrame() const;

//! Sostituisce pFrameToChange con pNewFrame altimenti aggiunge alla finevoid ChangeFrame(fbFrame ∗pFrameToChange,fbFrame∗ pNewFrame);

/∗!controlla se il frame pFrame deve essere aggiunto o sostituito nellalista dei frame correnti

∗/void AddOrChange(fbFrame∗ pFrame);

/∗!La lista dei frame ha l’ultimo frame vuoto o no(decide se rimpiazzare un frame vuoto o aggiungerne)FBErase ( si puo’ utilizzare GetSetFrame)

∗/fbBool IsEmpty() ;

/∗!Elimina tutti i frame dall’ applicazione

∗/void ClearAll();

virtual void OnLMouseMove (const fbInt,const fbInt);virtual void OnLMouseDown (const fbInt,const fbInt);virtual void OnLMouseUp (const fbInt,const fbInt);virtual void OnRMouseMove (const fbInt,const fbInt);virtual void OnRMouseDown (const fbInt,const fbInt);virtual void OnRMouseUp (const fbInt,const fbInt);virtual void OnMouseMove (const fbInt,const fbInt);

void OnResize (const fbInt nW,const fbInt nH);void Draw ();void UpdateGLProjection(const fbDouble& CenterOfWindowX,const fbDouble& CenterOfWindowY);

friend std::ostream& operator�(std::ostream& os,fbFasped∗ pFasped);friend std::istream& operator�(std::istream& is,fbFasped∗ pFasped);

};

/∗———————————————————∗\|∗ Espansione inline per la class fbFasped ∗||∗ BEGIN ∗|\∗———————————————————∗/

inline void fbFasped::SetLenghtForAction(const fbDouble dLofA){

this→m dLenghtForAction = dLofA;}

inline fbDouble fbFasped::GetLenghtForAction() const{

return this→m dLenghtForAction;}

/∗!Ritorna il valore di qualita’ di divisione

∗/inline fbDouble fbFasped::GetReductionQuality(){

return this→m dReductionQuality();}

/∗!Fissa il valore di qualita’ di divisione

∗/inline void fbFasped::SetReductionQuality(const fbDouble dQuality){

this→m dReductionQuality = dQuality;}

/∗!Stato del flag di riduzione

∗/inline fbBool fbFasped::GetReductionFlag() const{

return m bReductionFlag;}/∗!

∗/inline void fbFasped::SetReductionFlag(const fbBool bVal){

m bReductionFlag = bVal;}

/∗!Ritorna il raggio di Pick

∗/inline fbDouble fbFasped::GetPickRay() const

105

Page 114: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

{return m dPickRay;

}

/∗!Ritorna un riferimento alla lista dei frames a video

∗/inline SetFrame& fbFasped::GetSetFrame(){

return m lpFrame;}

/∗!Ritorna un puntatore al frame corrente attivo

o a quello selezionato∗/

inline fbFrame∗ fbFasped::GetFrame() const{

return m pCurrentFrame;}

/∗———————————————————∗\|∗ END ∗||∗ Espansione inline per la class fbFasped ∗|\∗———————————————————∗/

#endif // !defined( FB FASPED H )//———————————————————// End Of File//———————————————————

A.1.14 fbFrameManager//———————————————————//// FILENAME : fbFrameManager.h//// CLASS(ES) : fbFrameManager//// DESCRIPTION : Classe per la gestione di set di frame//// HISTORY : 28/10/2000//———————————————————#ifndef FB FRAME MANAGER H#define FB FRAME MANAGER H

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000

#include fbConfig.h

#include fbGrOb.h

class fbFrameManager : public fbTool{

fbInt m pPattern[7][5];fbFloat m pCursor[4];

// fbInt m nFrameNumber;public:

void ResetLattice();fbFrameManager(fbFasped∗);virtual ∼fbFrameManager();

void FindQuad(const fbDouble x,const fbDouble y,int &i1, int &j1);void DrawFullQuad(fbDouble x,fbDouble y);void InitGL();void Draw();void Clear();void HandleMouseMove (const fbUInt nButtonPressed, const fbDouble x, const fbDouble y);void HandleMouse (const fbUInt nButtonPressed, const fbDouble x, const fbDouble y);

};

#endif // !defined( FB FRAME MANAGER H )//———————————————————// End Of File//———————————————————

A.1.15 fbFrame//———————————————————//// FILENAME : fbFrame.h//

106

Page 115: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

// CLASS(ES) : fbFrame//// DESCRIPTION : classe di gestione di una sessione di disegno//// HISTORY : 26/07/2000// 29/09/2000 cambiata struttura di visualizzazione vector<list<fbCurve∗> >// un vettore di liste//———————————————————#ifndef FB FRAME H#define FB FRAME H

#if MSC VER > 1000#pragma once

//disabilito il warning di campi nome troppo lunghi nei template#endif // MSC VER > 1000

#include fbGrOb.h

#include fbCurve.h

#include <iostream>#include <vector>#include <list>#include fbConfig.h

#include fbPolyLine.h

//! Iteratori per la gestione di un insieme di lineetypedef std::list<fbPolyLine∗> SetLine;typedef SetLine::iterator itSetLine;typedef SetLine::reverse iterator ritSetLine;

//! Funzione per pulire una setlinevoid fbSetLineClear(SetLine& SLine);

//! Funzione per pulire una setlinevoid fbSetLineClear(SetLine∗ SLine);

//———————————————————

/∗!template SetLineBackInsertIterator permette di copiare i contenuti dei frame

∗/template <class Container> class SetLineBackInsertIterator{

Container& container;public:

explicit SetLineBackInsertIterator(Container& Line):container(Line)

{};

SetLineBackInsertIterator& operator=(const fbPolyLine∗ value ){

container.push back(new fbPolyLine(∗value));return (∗this);

};

SetLineBackInsertIterator& operator∗() {return (∗this); }SetLineBackInsertIterator& operator++() {return (∗this); }SetLineBackInsertIterator operator++(int) {return (∗this); }

};

//———————————————————

/∗!fbFrame : Classe che descrive una scena composta da una lista

di linee∗/

class fbFrame :public fbGrOb{protected:

private:

/// Fissa a runtime la qualita’ videofbDouble m dRenderQuality;

//! Database delle curve (lista di liste di cubiche (m l(ist)l(ist)fbCurve)SetLine m llfbCurve;

public:

fbFrame();

virtual ∼fbFrame();

fbFrame(const fbFrame& pFrame);

//! Fissa il tipo dell’ultima curva (FB POLYLINE OPENED / FB POLYLINE CLOSED )/∗!

Fissa il tipo dell’ultima curva-# FB POLYLINE OPENEDPer default le curve sono aperte

107

Page 116: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

-# FB POLYLINE CLOSEDL’ultimo pto coincide con il primo

∗/void SetLineType(const fbInt nType);

//! Metodo di disegnovoid Draw();

//Aggiunge una curve alla listavoid AddCurve(fbCurve∗ pCurve);

//! Metodo che ritorna la polyline che contiene la curva altrimenti end()void Select(const fbCurve ∗pCurve,itSetLine& itSL,itPolyLine& itPL);

//! Seleziona la curva con il pto di controllo piu’ vicino al pto Point a meno di dPickRay/∗!

Ritorna l’iteratore che indirizza la polyline e di quella polyline l’iteratoreche indirizza la curva che soddisfa il minimoPer valore di ritorno un valore tra FB CURVE P1-4 o FB ERROR se errore

∗/fbInt SelectCurveByCtrlPoint(const fbPoint& pPoint,const fbDouble dPickRay,itSetLine& itSL,itPolyLine&

itPL);

//! Seleziona la curva con il pto piu’ vicino al pto Point a meno di dPickRay/∗!

Ritorna l’iteratore che indirizza la polyline e di quella polyline l’iteratoreche indirizza la curva che soddisfa il minimoPer valore di ritorno un valore tra 0-1 o FB ERROR se errore

∗/fbDouble SelectCurveByPoint(const fbPoint& pPoint,const fbDouble dPickRay,itSetLine& itSL,itPolyLine&

itPL);

//! Aggiunge una nuova linea alla listavoid AddPolyLine(fbPolyLine∗ Line);

//! Elimina tutte le curve della listavoid DeleteAllCurves();

/// Metodo per la gestione del visitatorevoid AcceptVisitor(fbVisitor∗);

//! Riferimento alla lista contenutainline SetLine& GetSetLine();

//! Funzione per la riduzione delle linee a videovoid ReduceLines(void (∗RedFunc)(PolyLine&,const fbDouble) = 0 );

//! InizializzazionefbFrame& operator =(const fbFrame &Frame);

friend std::ostream& operator�(std::ostream &os, fbFrame∗ pFrame);friend std::ostream& operator�(std::ostream &os, fbFrame& pFrame);friend std::istream& operator�(std::istream &is, fbFrame ∗pFrame);friend std::istream& operator�(std::istream &is, fbFrame &pFrame);

};

/∗——————————————————-∗\|∗ Espansione inline per la classe fbFrame ∗||∗ BEGIN ∗|\∗——————————————————-∗/

inline SetLine& fbFrame::GetSetLine(){

return m llfbCurve;}

/∗——————————————————-∗\|∗ END ∗||∗ Espansione inline per la classe fbFrame ∗|\∗——————————————————-∗/

#endif // !defined( FB FRAME H )//———————————————————// End Of File//———————————————————

A.1.16 fbFunction//———————————————————//// FILENAME : fbFunction.h//// CLASS(ES) : fbFunction//// DESCRIPTION : classe di gestione di una funzione//// HISTORY : 09/12/2000

108

Page 117: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

//———————————————————#ifndef FB FUNCTION H#define FB FUNCTION H

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000

#include fbMath.h

#include fbConfig.h

#include <functional>#include <cmath>

template <class T> class fbFactors{

// Vettore di fattori su cui operarestd::vector<T> m vFactors;

public:

fbFactors(){}

fbFactors(T Factor){

m vFactors.push back(Factor);}

fbFactors(std::vector<T> vFactor){

copy(vFactor.begin(),vFactor.end(),std::back inserter(m vFactors));}

fbFactors(const fbFactors& Factors){

std::copy(Factors.m vFactors.begin(),Factors.m vFactors.end(),std::back inserter(this→m vFactors));}

fbFactors& operator=(const fbFactors<T>& vFactor){

if(&vFactor == this)return ∗this;

std::copy(vFactor.m vFactors.begin(),vFactor.m vFactors.end(),std::back inserter(m vFactors));

return ∗this;}

std::vector<T>& GetFactors(){

return m vFactors;}

};

template <class T> std::ostream& operator�(std::ostream& os, fbFactors<T>& Factors){

for(fbUInt i = 0 ;i<Factors.GetFactors().size();i++)os�Factors.GetFactors()[i]�’ ’;

return os;

}

template <class T> std::ostream& operator�(std::ostream& os, fbFactors<T>∗ Factors){

for(fbUInt i = 0 ;i<Factors→GetFactors().size();i++)os�Factors→GetFactors()[i]�’ ’;

return os;}

template <class T> class fbFunction{public:

fbFunction(){};

virtual ∼fbFunction(){};

virtual T operator()( const T& Factor) {return 0;}

virtual T operator()( const T& Factor1,const T& Factor2) {return 0;}

virtual T operator()( fbFactors<T> & Factors) {return 0;}

109

Page 118: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

};

typedef fbFactors<fbDouble> fbFactorsDouble;typedef fbFactors<fbFloat> fbFactorsFloat;typedef fbFactors<fbInt> fbFactorsInt;

typedef fbFunction<fbDouble> fbFunctionDouble;typedef fbFunction<fbDouble> fbFunctionFloat;typedef fbFunction<fbDouble> fbFunctionInt;

template <class T> class fbSin :public fbFunction<T>{

public:

T operator()( const T& Factor ){

return sin(Factor);}

};

/∗!fbPolynomious: Classe per la gestione di un polinomio i valori sono memorizzati in ordinedecrescente con il grado:an x∧n + ...+ a0v[0] = an....v[n] = a0

∗/class fbPolynomious :public fbFunction<fbDouble>{

std::vector<fbDouble> m PolyCoeff;

public:

fbPolynomious(){}

fbPolynomious(const std::vector<fbDouble>& PolyCoeff){

std::copy(PolyCoeff.begin(),PolyCoeff.end(),std::back inserter(m PolyCoeff));}

fbPolynomious(const fbDouble p1,const fbDouble p0){

m PolyCoeff.push back(p1);m PolyCoeff.push back(p0);

}

fbPolynomious(const fbPolynomious& Poly){

std::copy(Poly.m PolyCoeff.begin(),Poly.m PolyCoeff.end(),std::back inserter(m PolyCoeff));}

virtual ∼fbPolynomious(){

m PolyCoeff.clear();}

inline std::vector<fbDouble>& GetCoeff();fbPolynomious& operator=(const fbPolynomious& Poly);

fbPolynomious operator+(const fbPolynomious& Poly);

fbDouble operator()( fbFactorsDouble& Factors) ;

fbPolynomious operator∗(const fbPolynomious& Poly) const;fbPolynomious operator∗(const fbDouble dVal) const;

};

fbPolynomious operator∗(const fbDouble dVal,const fbPolynomious& Poly);std::ostream& operator�(std::ostream& os, fbPolynomious& Poly);std::ostream& operator�(std::ostream& os, fbPolynomious∗ Poly);

inline std::vector<fbDouble>& fbPolynomious ::GetCoeff(){

return m PolyCoeff;}

#endif // !defined( FB FUNCTION H )//———————————————————// End Of File//———————————————————

110

Page 119: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

A.1.17 fbGeometric//———————————————————//// FILENAME : fbGeometric.h//// CLASS(ES) : fbGeometric//// DESCRIPTION : Wrapper per tutti gli oggetti geometrici//// HISTORY : 28/10/2000//———————————————————#include <fbException.h>#include <fbConfig.h>#include <fbMath.h>#include <fbPoint.h>#include <fbPolyLine.h>#include <fbCurve.h>#include <fbStraightLine.h>#include <fbRectangle.h>#include <fbCircle.h>#include <fbTriangle.h>#include <fbUtil.h>

A.1.18 fbGeoObj//———————————————————//// FILENAME : fbGeoObj.h//// CLASS(ES) : fbGeoObj//// DESCRIPTION : Tool per il disegno di oggetti// geometrici (cerchi,ellissi,rettangoli,etc..)//// HISTORY : 09/11/2000//———————————————————#ifndef FB GEOOBJ H#define FB GEOOBJ H

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000

#include fbTool.h

#include fbPoint.h

#include fbFrame.h

#include <list>#include fbConfig.h

#include fbPolyLine.h

#include fbRectangle.h

/∗!fbGeoObj: fbGeo(metric)Obj(ect)Tool per il disegno di oggetti geometrici (cerchi,ellissi,rettangoli,etc..)

∗/class fbGeoObj : public fbTool{private:

//! Oggetto a videoPolyLine m ComplexObject;

//! Variabile che contiene il tipo di oggetto graficofbInt m nGeoObj;

//! Bounding Box per gli oggetti da rappresentarefbRectangle m BBox;

public:inline fbInt GetGeoObj() const;

enum{

FB GEO OBJ RECTANGLE,FB GEO OBJ ELLIPSE,FB GEO OBJ CIRCLE,FB GEO OBJ LINE

};

fbGeoObj(fbFasped∗);fbGeoObj(fbFasped∗,fbInt);

virtual ∼fbGeoObj();

void InitGL();void Draw();void HandleMouseMove (const fbUInt nButtonPressed, const fbDouble x, const fbDouble y);

111

Page 120: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

void HandleMouse (const fbUInt nButtonPressed, const fbDouble x, const fbDouble y);void Clear();

//! Fissa il tipo di oggtto che il tool deve rappresentarevoid SetGeoObj(const fbInt nTypeOfGeoObj);

};

inline fbInt fbGeoObj::GetGeoObj() const{

return m nGeoObj;}

#endif // !defined( FB GEOOBJ H )//———————————————————// End Of File//———————————————————

A.1.19 fbGrOb//———————————————————//// FILENAME : fbGrOb.h//// CLASS(ES) : fbGrOb//// DESCRIPTION : f(a)b(rizio)Gr(aphic)Ob(ject)// classe di gestione di un generico oggetto grafico//// HISTORY : 26/07/2000// 11/08/2000 Cambiate le dimensioni da fbInt a fbDouble per poterle// usare anche negli oggetti curva e pto// Aggiunto metodo per l’accesso mediante visitor// 13/08/2000 Aggiunto metodo per controllo colore// 27/09/2000 Cambiato Draw=0 con Draw(const fbRectangle&) per tener conto// del disegno fuori dalla BBox// 14/10/2000 Rimosso Draw(cons fbRectangle&) gli aggiornamenti// sono eseguiti al resize// 15/11/2000 Aggiornate le funzioni inline// 23/05/2001 Rinominati :// m bInit -> m bInitGL// Init() -> InitGL()// GetInit() -> GetInitGL()// SetInit() -> SetInitGL()//———————————————————#ifndef FB GROB H#define FB GROB H

#include fbConfig.h

#include fbVisitor.h

#include <iostream>

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000

//! fbStipple descrive la struttura di una linea tratteggiata (vedi OpenGL glLineStipple)struct fbStipple{

fbInt m nFactor; //! Fattore di stipple (piu’ e’ grande piu’ il tratteggio e’ largo)fbUShort m nPattern; //! Maschera descrittiva

fbStipple():m nFactor (1),m nPattern (0xAAAA)

{}

fbStipple(const fbInt nFact,const fbUShort nPatt):m nFactor (nFact),m nPattern (nPatt)

{}};

/∗!fbGrOb classe base di ogni oggetto grafico

∗/class fbGrOb{

//! Flag di visibilita’ per l’oggetto graficofbBool m bVisibility;

//! Flag di disponibilita’ dell’oggetto (se e’ attivo fa qualcosa altrimenti no)fbBool m bActivity;

//! Flag di inizializzazione contesto OpenGLfbBool m bInitGL;

//! Colore dell’oggetto attivo

112

Page 121: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

fbFloat m pdColor[4];

//! Colore dell’oggetto non attivofbFloat m pdColorNoActive[4];

//! Larghezza dell’oggetto graficofbDouble m dWidth;

//! Altezza dell’oggetto graficofbDouble m dHeight;

//! Tolleranza del disegno/∗!

Fissa la tolleranza di disegno.N.B.

(Questo valore non e’ comune ma specifico per ogni oggetto puo’essere variato in funzione delle necessita’ dell’oggetto)

∗/fbDouble m dTolerance;

//! GLenum per il disegnofbLong m nDrawType;

//! Stile della lineafbStipple m nStipplePattern;

//! Puntatore a funzione di callback pre drawvoid (∗m pPreDrawFunction) (fbGrOb∗);

//! Puntatore a funzione di callback post drawvoid (∗m pPostDrawFunction) (fbGrOb∗);

public:

fbGrOb();fbGrOb(const fbDouble,const fbDouble);fbGrOb(const fbGrOb&);

virtual ∼fbGrOb();

enum{

FB COLOR ACTIVE ,//! Macro per settare il colore attivoFB COLOR NOT ACTIVE //! Macro per settare il colore non attivo

};

//! Fissa il valore della tolleranza del disegnoinline void SetTolerance(const fbDouble dVal);

//! Ritorna il valore della tolleranza del disegnoinline fbDouble GetTolerance() const;

//! Fissa GLenum per il disegno correnteinline void SetDrawType(const fbLong nVal);

//! Ritorna GLenum per il disegno correnteinline fbLong GetDrawType() const;

//! Linka una funzione alla callback di predisegno/∗!

Questa funzione sovrascrive le proprieta’ precedentementefissate nella Init tenetene conto nel suo utilizzo

∗/inline void SetPreDrawFunction(void (∗func)(fbGrOb∗));

//! Linka una funzione alla callback di postdisegnoinline void SetPostDrawFunction(void (∗func)(fbGrOb∗));

//! Inizializzazionevirtual fbGrOb& operator=(const fbGrOb &GraphiObject);

//! Metodo di inizializzazionevirtual void InitGL();

//! Metodo di gestione disegnovirtual void Draw()=0;

//! Wrapper per il metodo Drawvoid Display();

//! Fissa il flag di visibilita’inline void SetVisibility(const fbBool bVal=true);

//! Ritorna il flag di visibilita’inline fbBool GetVisibility() const;

//! Fissa il flag di attivita’inline void SetActivity(const fbBool bVal=true);

113

Page 122: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

//! Ritorna il flag di attivita’inline fbBool GetActivity() const;

//! Fissa il flag di inizializzazione del contesto OpenGLinline void SetInitGL(const fbBool bVal);

//! Ritorna il flag di inizializzazione del contesto OpenGLinline fbBool GetInitGL() const;

//! Fissa le dimensioni dell’oggettoinline void SetSize(const fbDouble dW, const fbDouble dH);

//! Ritorna le dimensioni dell’oggettoinline void GetSize(fbDouble & dW, fbDouble& dH) const;

//! Ritorna la largezza dell’oggettoinline fbDouble H() const;

//! Fissa l’altezza dell’oggettoinline void H( const fbDouble dVal);

//! Ritorna l’altezza dell’oggettoinline fbDouble W() const;

//! Fissa la largezza dell’oggettoinline void W( const fbDouble dVal);

//! Ritorna lo stile della lineainline fbStipple GetStipplePattern();

//! Fissa lo stile della lineainline void SetStipplePattern(const fbStipple nStipple);

//! Ritorna il colore dell’oggettovoid GetColor(fbFloat& dR,fbFloat& dG,fbFloat& dB,fbFloat& dA,fbInt

nActive=FB COLOR ACTIVE) const;const fbFloat∗ GetColor(fbInt nActive = FB COLOR ACTIVE) const;

inline void GetColorActive (fbFloat& dR,fbFloat& dG,fbFloat& dB,fbFloat& dA) const ;inline const fbFloat∗ GetColorActive () const { return &m pdColor[0];}inline void GetColorNoActive(fbFloat& dR,fbFloat& dG,fbFloat& dB,fbFloat& dA) const;inline const fbFloat∗ GetColorNoActive() const { return &m pdColorNoActive[0];}

//Fissa il colore dell’oggettovoid SetColor (fbFloat dR,fbFloat dG,fbFloat dB,fbFloat dA,fbInt nActive=FB COLOR ACTIVE);void SetColor (const fbFloat∗ dVectorColor4D,fbInt nActive=FB COLOR ACTIVE);

inline void SetColorActive (fbFloat dR,fbFloat dG,fbFloat dB,fbFloat dA) ;inline void SetColorActive (const fbFloat∗ dVectorColor4D);inline void SetColorNoActive(fbFloat dR,fbFloat dG,fbFloat dB,fbFloat dA);inline void SetColorNoActive(const fbFloat∗ dVectorColor4D);

//! Metodo visitatore per l’accesso ai sottocampivirtual void AcceptVisitor(fbVisitor∗);

friend std::ostream& operator�(std::ostream &os, fbGrOb∗ pObj);friend std::ostream& operator�(std::ostream &os, fbGrOb& pObj);

};

/∗—————————————-∗\|∗ Espansione inline per la class fbGrOb ∗||∗ BEGIN ∗|\∗—————————————-∗/

inline void fbGrOb::SetTolerance(const fbDouble dVal){

m dTolerance = dVal;}

inline fbDouble fbGrOb::GetTolerance() const{

return m dTolerance ;}

inline void fbGrOb::SetDrawType(const fbLong nVal){

m nDrawType = nVal;}

inline fbLong fbGrOb::GetDrawType() const{

return m nDrawType ;}

inline void fbGrOb::SetPreDrawFunction(void (∗func)(fbGrOb∗)){

m pPreDrawFunction=func;}

inline void fbGrOb::SetPostDrawFunction(void (∗func)(fbGrOb∗)){

m pPostDrawFunction=func;}

114

Page 123: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

inline void fbGrOb::SetVisibility(const fbBool bVal){

m bVisibility=bVal;}

inline fbBool fbGrOb::GetVisibility() const{

return m bVisibility;}

inline void fbGrOb::SetActivity(const fbBool bVal){

m bActivity=bVal;}inline fbBool fbGrOb::GetActivity() const{

return m bActivity;}

inline void fbGrOb::SetInitGL(const fbBool bVal){

m bInitGL = bVal;}

inline fbBool fbGrOb::GetInitGL() const{

return m bInitGL;}

inline void fbGrOb::SetSize(const fbDouble dW, const fbDouble dH){

m dWidth = dW; m dHeight= dH;}

inline void fbGrOb::GetSize(fbDouble & dW, fbDouble& dH) const{

dW = m dWidth ; dH = m dHeight ;}

inline fbDouble fbGrOb::H() const{

return m dHeight;}

inline void fbGrOb::H( const fbDouble dVal){

m dHeight=dVal;}

inline fbDouble fbGrOb::W() const{

return m dWidth;}

inline void fbGrOb::W( const fbDouble dVal){

m dWidth =dVal;}

inline void fbGrOb::GetColorActive (fbFloat& dR,fbFloat& dG,fbFloat& dB,fbFloat& dA) const{

dR= m pdColor[0]; dG= m pdColor[1];dB= m pdColor[2]; dA= m pdColor[3];}

inline void fbGrOb::GetColorNoActive(fbFloat& dR,fbFloat& dG,fbFloat& dB,fbFloat& dA) const{

dR= m pdColorNoActive[0]; dG= m pdColorNoActive[1];dB= m pdColorNoActive[2]; dA=m pdColorNoActive[3];}

inline void fbGrOb::SetColorActive (fbFloat dR,fbFloat dG,fbFloat dB,fbFloat dA){

m pdColor[0]=dR; m pdColor[1]=dG; m pdColor[2]=dB; m pdColor[3]=dA;

}

inline void fbGrOb::SetColorActive (const fbFloat∗ dVectorColor4D){

m pdColor[0]=dVectorColor4D[0]; m pdColor[1]=dVectorColor4D[1];m pdColor[2]=dVectorColor4D[2]; m pdColor[3]=dVectorColor4D[3];

}

inline void fbGrOb::SetColorNoActive(fbFloat dR,fbFloat dG,fbFloat dB,fbFloat dA){

m pdColorNoActive[0]=dR; m pdColorNoActive[1]=dG;m pdColorNoActive[2]=dB; m pdColorNoActive[3]=dA;

}

115

Page 124: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

inline void fbGrOb::SetColorNoActive (const fbFloat∗ dVectorColor4D){

m pdColorNoActive[0]=dVectorColor4D[0]; m pdColorNoActive[1]=dVectorColor4D[1];m pdColorNoActive[2]=dVectorColor4D[2]; m pdColorNoActive[3]=dVectorColor4D[3];

}

inline fbStipple fbGrOb::GetStipplePattern(){

return m nStipplePattern;}

void fbGrOb::SetStipplePattern(const fbStipple nStipple){

m nStipplePattern.m nFactor = nStipple.m nFactor;m nStipplePattern.m nPattern= nStipple.m nPattern;

}

/∗—————————————-∗\|∗ END ∗||∗ Espansione inline per la class fbGrOb ∗|\∗—————————————-∗/

//! Funzione per il disegno di un oggettoinline fbGrOb∗ fbGrObDraw(fbGrOb∗ pObj){

pObj→Display();return pObj;

}

//! Funzione per la distribuzione di visitorinline fbGrOb∗ fbGrObVisit(fbGrOb∗ pObj,fbVisitor∗ pVisitor){

pObj→AcceptVisitor(pVisitor);return pObj;

}

//! Funzione di preDraw per l’abilitazione dello stipplevoid fbDrawEnableStipple (fbGrOb∗);

//! Funzione di postDraw per la disabilitazione dello stipplevoid fbDrawDisableStipple(fbGrOb∗);

#endif // !defined( FB GROB H )//———————————————————// End Of File//———————————————————

A.1.20 fbLoader//———————————————————//// FILENAME : fbLoader.h//// CLASS(ES) ://// DESCRIPTION ://// DATE : Wed Oct 4 2000// COPYRIGTH : (C) 2000 by Fabrizio Morciano// E MAIL : [email protected]////———————————————————#ifndef FB LOADER H#define FB LOADER H

#include fbWindow.h

#include fbConfig.h

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000

class fbLoader{

fbBool LoadFSE(const fbChar∗ pFileName);fbBool LoadTZV(const fbChar∗ pFileName);fbBool LoadDAT(const fbChar∗ pFileName);fbBool LoadFRP(const fbChar ∗pFileName);

#ifdef SVG ENABLEDfbBool LoadSVG(const fbChar ∗pFileName);

#endif

public:fbBool LoadFile(const fbChar∗ pFileName);fbLoader(fbFasped∗);virtual ∼fbLoader();/∗∗ Metodo per centrare il disegno in finestra ∗/void MaximizeAndCenter(const fbPoint& tL,const fbPoint& bR);

116

Page 125: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

private:fbFasped∗ m pApplicationReference;

};

#endif // !defined( FB LOADER H )//———————————————————// End Of File//———————————————————

A.1.21 fbMath//———————————————————//// FILENAME : fbMath.h//// CLASS(ES) : fbMatrix.fbVector,fbVector2D//// DESCRIPTION : f(a)b(rizio)Math// qualche funzione per la gestione matematica//// HISTORY : 16/08/2000// 08/09/2000 aggiunto vettore 2D ma la politica di// gestione ancora non l’ho fissata// 15/05/2000 aggiunto codice gestione angoli//———————————————————#ifndef FBMATH H#define FBMATH H

#include <vector>#include <iostream>#include <algorithm>#include <cmath>#include fbException.h

#include fbConfig.h

#include fbPoint.h

/∗!Libreria matematica

∗/

// Qualche costante sempre comoda

//! P grecoconst fbDouble FB PI = 3.1415926535897932384626433832795;

//! P greco ∗2const fbDouble FB 2 PI = 6.283185307179586476925286766559;

//! P greco /2const fbDouble FB PI 2 = 1.5707963267948966192313216916398;

//! P greco /3const fbDouble FB PI 3 = 1.0471975511965977461542144610932;

//! P greco /4const fbDouble FB PI 4 = 0.78539816339744830961566084581988;

//! 180 / P grecoconst fbDouble FB RAD ANGLE = 57.295779513082320876798154814105;

//! P greco /180const fbDouble FB ANGLE RAD = 1.74532925199432957692369076848e-2;

//! econst fbDouble FB E = 2.71828182846;

//! 1/3const fbDouble FB 1 3 = 0.33333333333333333333333333333333;

//! 2/3const fbDouble FB 2 3 = 0.66666666666666666666666666666667;

//! Formule di conversione angoli radianti e viceversainline fbDouble fbRadToAngle(const fbDouble& dVal){

return FB RAD ANGLE∗dVal;}

inline fbDouble fbAngleToRad(const fbDouble& dVal){

return FB ANGLE RAD∗dVal;}

//! Valore assolutotemplate <class T> inline T fbAbs(T val){ return(val > 0 ? val : -val);}

//! Tipo di range:enum fbRangeType{

117

Page 126: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

fbRangeAllIncluded,fbRangeLeftIncluded,fbRangeRightIncluded,fbRangeNotIncluded

};

template <class T> inline T fbMin(T fv,T sv ){

return fv < sv ? fv : sv ;}

template <class T> inline T fbMax(T fv,T sv ){

return fv > sv ? fv : sv ;}

//! Check nel range/∗!

Il caso particolare in cui minVal e maxVal coincidono e’ risoltoverificando l’uguaglianza tra (minVal=maxVal) e testVal se e’ verificataritorna true

∗/template <class T> inline fbBool fbRange(const T minVal,\

const T testVal,\const T maxVal,\const fbRangeType RangeType=fbRangeAllIncluded)

{T tempMin=minVal,

tempMax=maxVal ;

// se gli ho passato i valori in ordine errato aggiustaif( tempMin>tempMax)

swap(tempMin,tempMax);

if(tempMin == tempMax){

switch(RangeType){case fbRangeAllIncluded:case fbRangeLeftIncluded:case fbRangeRightIncluded:

if(tempMin==testVal)return true;

break;case fbRangeNotIncluded: //sempre errato

return false;break;

}return false;

}

switch(RangeType){case fbRangeAllIncluded:

if(tempMin<=testVal && testVal<=tempMax)return true;

break;case fbRangeLeftIncluded:

if( tempMin<=testVal && testVal<tempMax)return true;

break;

case fbRangeRightIncluded:if( tempMin<testVal && testVal<=tempMax)

return true;break;

case fbRangeNotIncluded:if( tempMin<testVal && testVal<tempMax)

return true;break;

}

return false;}

//! Restituisce il segno (1 -> +; -1 -> - ;0 -> 0)template <class T> inline T fbSign(const T& number){

if(number> (T)0)return 1;

if(number == (T)0)return 0;

return -1;}

//! Calcola la potenza intera di un numero realeinline fbDouble fbPowInt (const fbDouble Base, const fbInt exp)

118

Page 127: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

{if (exp == 0)

return 1.0;

fbDouble outVal = Base;

for (int i = 1; i < exp; i++)outVal ∗ = Base;

return outVal;}

//! Quadrato di valtemplate <class T> inline T fbSqr(const T val){

return val ∗ val;}

//! FattorialefbDouble fbFact(fbDouble nVal);

//! Binomio di NewtonfbDouble fbNewtonBinomy(fbInt n,fbInt i);

//! Bernstein EvaluatorfbDouble Bernstein(fbDouble t,fbInt n,fbInt i);

/∗!Riporta il polinomio di 3◦ grado in forma di bezier.I Pti sono ordinati da P0 a Pn-1SIDE EFFECTS: solo il caso di grado 3 e’ supportato

∗/template <class T1,class T2> void fbPolyToBezier(const T1& Poly, T2& Bezier){

switch(Poly.size()){case 4:

Bezier.resize(4);Bezier[0] = Poly[3];Bezier[1] = (Poly[2]∗FB 1 3 + Bezier[0] );Bezier[2] = (Poly[1]∗FB 1 3 - Bezier[0] + Bezier[1] ∗ 2.0 );Bezier[3] = Poly[0] + Bezier[0] - Bezier[1] ∗ 3.0 + Bezier[2] ∗ 3.0;break;

case 3:Bezier.resize(3);Bezier[0] = Poly[2];Bezier[1] = Poly[1]∗0.5 + Bezier[0];Bezier[2] = Poly[0] - Bezier[0] + 2.0 ∗ Bezier[1];break;

}}

/∗!Calcola le soluzione di un polinomio di grado 2N.B. Testato e controllato

∗/template <class T> fbInt fbPoly2DegreeFindRoots(const T& a, const T& b, const T& c , T& sol 1, T& sol 2){

if ( a == 0.0 ){

if( b == 0.0 )return 0;

sol 1 = sol 2 = - c / b;return 1;

}

TDelta = b∗b - 4.0 ∗ a ∗ c;

if( Delta < 0.0 )return 0;

if( Delta == 0.0 ){

sol 1 = sol 2 = - b / 2.0 ∗ a;return 1;

}

// modificato secondo Numerical RecipesT

q = -0.5 ∗ ( b + fbSign( b ) ∗ sqrt(Delta));

if( b != 0){

sol 1 = q / a;sol 2 = c / q ;

}else{sol 2 = sqrt( - c / a );sol 1 = - sol 2;

119

Page 128: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

}return 2;

}

/∗! Calcola le radici di una equazione di grado n ( per ora n<=2 Ha Ha)viene ipotizzato che i coefficienti siano passati in ordinedescrescente con il grado del polinomio:\f$ a nt∧n + a {n-1}t∧{n-1} + a {n-2}t∧{n-2} + ... + a 0 =0 \f$= v[0] , v[1],...,v[n]

∗/template <class T> void fbPolyFindRoots(const std::vector<T>& pdCoeff,std::vector<T>& vdRes){

std::vector<T>tempVector;

copy(pdCoeff.begin(),pdCoeff.end(),back inserter(tempVector));//insert iterator<std::vector<T> >(tempVector,tempVector.end()));

// per sicurezza faccio pulizievdRes.clear();

//se il polinomio e’ di gradio superiore a 4 o vuotoif(tempVector.size() >5 || tempVector.empty())

throw fbRangeException(string( FILE )+string( fbPolyFindRoots(const std::vector<T>& ...): Bad poly

size));

if(tempVector.size() == 2){

if(tempVector[0] == 0 )throw fbRangeException(string( FILE )+string( fbPolyFindRoots(const std::vector<T>& ...):

Constant value only in poly));else{

vdRes.push back(-tempVector[1]/tempVector[0]);return;

}}

if(tempVector.size() == 3){

TdSol 1,dSol 2;

fbIntnNumberOfSol = fbPoly2DegreeFindRoots(tempVector[0], tempVector[1], tempVector[2], dSol 1,

dSol 2);

if(nNumberOfSol == 0)throw fbRangeException(string( FILE )+string( fbPolyFindRoots(const std::vector<T>& ...):

Roots are complex));

if(nNumberOfSol == 1)vdRes.push back( dSol 1 );

if(nNumberOfSol == 2){

vdRes.push back( dSol 1 );vdRes.push back( dSol 2 );

}

}

if(tempVector.size() == 4){

if(tempVector[0] == 0 ) // e’ il caso di secondo grado{

// faccio risalire i valoritempVector[0] = tempVector[1];tempVector[1] = tempVector[2];tempVector[2] = tempVector[3];tempVector.pop back(); // elimino l’ultimofbPolyFindRoots<T>(tempVector,vdRes);

}else{

// normalizzo per utilizzare le formule di Cardano (N.B. a e’ != 0.0)for(fbUInt i=0;i<4;i++)

tempVector[i]/=tempVector[0];

/∗Q = (a∗a - 3∗b) /9

R = (2∗a∗a∗a -9∗a∗b+27∗c)/54

con a = tempVector[1]b = tempVector[2]c = tempVector[3]

∗/T

120

Page 129: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

a2 = tempVector[1]∗tempVector[1],Q = (a2 - 3.0∗ tempVector[2])/9.0,R = (2.0 ∗ a2 ∗tempVector[1] -9.0 ∗tempVector[1]∗tempVector[2] +27.0∗tempVector[3])/54.0,Q3 = Q∗Q∗Q,R2 = R∗R;

if(R2<Q3){

Ttheta = acos(R/sqrt(Q3)) / 3.0,coeff 1 = -2.0∗sqrt(Q),coeff 2 = -tempVector[1]/3.0;

vdRes.push back(coeff 1∗cos(theta)+coeff 2);vdRes.push back(coeff 1∗cos(theta+2.0∗FB PI 3)+coeff 2);vdRes.push back(coeff 1∗cos(theta-2.0∗FB PI 3)+coeff 2);

}else{

/∗T

A = - pow([ R + sqrt(R2 - Q3)],3.0);

if(A!= 0.0)B = Q / A:

elseB =0.0;

vdRes.push back(coeff 1∗cos(theta)+coeff 2);∗/throw fbRangeException(string( FILE )+string( fbPolyFindRoots(const std::vector<T>&...):

Roots are complex));}

}}

}

/∗! Calcola la derivata di un polinomioviene ipotizzato che i coefficienti siano passati in ordinedescrescente con il grado del polinomio:\f$ a nt∧n + a {n-1}t∧{n-1} + a {n-2}t∧{n-2} + ... + a 0 =0 \f$ritorna\f$ a n\cdot n\cdot t∧{n-1} + a {n-1}\cdot (n-1)\cdot t∧{n-2} + ... + a 1 =0 \f$

∗/template <class T> void fbPolyDerive(const std::vector<T>& pdCoeff,std::vector<T>& vdRes){

std::vector<T> tempVector;copy(pdCoeff.begin(),pdCoeff.end(),back inserter(tempVector));

//insert iterator<std::vector<T> >(tempVector,tempVector.end()));

// per sicurezza faccio pulizievdRes.clear();fbUInt degree=tempVector.size() - 1 ;for(fbUInt i=0;i<tempVector.size()-1;i++)

vdRes.push back((degree - i )∗tempVector[i]);}

/∗! Valuta un polinomio per un dato valoreviene ipotizzato che i coefficienti siano passati in ordinedescrescente con il grado del polinomio:\f$ a nt∧n + a {n-1}t∧{n-1} + a {n-2}t∧{n-2} + ... + a 0 =0 \f$

∗/template <class T > T fbPolyEval(const std::vector<T>& pdCoeff,const T dVal){

fbUIntpolyOrder = pdCoeff.size();

if(polyOrder < 0 )throw fbRangeException(string( FILE )+string( fbPolyEval(const std::vector<fbDouble>& pdCoeff,const

fbDouble dVal): Ply is too little));

if(polyOrder ==0 )return 0;

if(polyOrder ==1 )return pdCoeff[0];

TexitVal=pdCoeff[0] ;

for(fbUInt i=0;i<polyOrder-1;i++)exitVal = exitVal ∗ dVal + pdCoeff[i+1];

return exitVal;}

/∗!Prodotto fra due polinomi

∗/template <class T> void fbPolyMultPoly(const std::vector<T>& FirstPoly,const std::vector<T>&

121

Page 130: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

SecondPoly,std::vector<T>& ResPoly){

std::vector<T> tempVector;

if ( FirstPoly.size() == 0 || SecondPoly.size() == 0) //se i polinomi non sono validi ritornoreturn;

fbBoolbIsFirstGreaterSecond = false; // fisso un ordinamento

if ( FirstPoly.size() > SecondPoly.size() )bIsFirstGreaterSecond = true;

const std::vector<T> // e faccio due alias per il maggiore ed il minore&tempMaxPoly = bIsFirstGreaterSecond ? FirstPoly : SecondPoly,&tempMinPoly = bIsFirstGreaterSecond ? SecondPoly: FirstPoly ;

// lode ad STL by SGI doctempVector.resize(tempMaxPoly.size()); //alloco spazio per il polinomio piu’ grande

fbUIntnOffset =0; //offset per il polinomio risultato

for(fbUInt i=0;i<tempMinPoly.size();i++) // per tutti i coeff del polinomio di grado minore{

if(i<tempMinPoly.size() - 1)tempVector.push back(0); // aggiungo l’ultimo elemento

if(tempMinPoly[i]!=0.0) // salto le moltiplicazioni nullefor(fbUInt j=nOffset;j<tempMaxPoly.size() + nOffset;j++) // e per tutto il polinomio di grado

maggioretempVector[j] += tempMinPoly[i] ∗ tempMaxPoly[j - nOffset]; // moltiplico i coeff.

nOffset++; // sposto la finestra}

ResPoly.clear(); // pulisco il vettore del risultato

// e copio il risultatocopy(tempVector.begin(),tempVector.end(),back inserter(ResPoly));

}

/∗!Somma fra due polinomi

∗/template <class T> void fbPolyAddPoly(const std::vector<T>& FirstPoly,const std::vector<T>&SecondPoly,std::vector<T>& ResPoly){

std::vector<T> tempVector;

if ( FirstPoly.size() == 0 || SecondPoly.size() == 0) //se i polinomi non sono validi ritorno{

if(FirstPoly.size() == 0){

if(SecondPoly.size() != 0)copy(SecondPoly.begin(),SecondPoly.end(),back inserter(ResPoly));

}else

copy(FirstPoly.begin(),FirstPoly.end(),back inserter(ResPoly));

return;}

fbBoolbIsFirstGreaterSecond = false; // fisso un ordinamento

if ( FirstPoly.size() > SecondPoly.size() )bIsFirstGreaterSecond = true;

const std::vector<T> // e faccio due alias per il maggiore ed il minore&tempMaxPoly = bIsFirstGreaterSecond ? FirstPoly : SecondPoly,&tempMinPoly = bIsFirstGreaterSecond ? SecondPoly: FirstPoly ;

tempVector.resize(tempMaxPoly.size(),0);for(fbUInt i=tempMaxPoly.size()-1;i>0;i– –) // per tutti i coeff del polinomio di grado minore

tempVector[i] = tempMaxPoly[i] + (i<tempMinPoly.size() ? tempMinPoly[i] : 0);

tempVector[0] = tempMaxPoly[0] + tempMinPoly[0];

ResPoly.clear(); // pulisco il vettore del risultato

// e copio il risultatocopy(tempVector.begin(),tempVector.end(),back inserter(ResPoly));

}

/∗! Data una matrice di tipo C/C++ di dimensione nRow x nColmemorizzata per righe restituisce l’indiceche compete al vettore equivalente

∗/inline fbInt fbMatrixToVector(const fbInt i,const fbInt j,const fbInt nCol){

122

Page 131: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

return (i∗nCol+j);}

/∗! Dato un vettore di tipo C/C++ di dimensione nRow x nColritorna dalla posizione nPos gli indici dellacorrispondente matrice memorizzata per righe

∗/inline void fbVectorToMatrix(fbInt& i,fbInt& j,const fbInt nPos ,const fbInt nCol){

j = nPos % nCol;

i = (fbInt)(nPos - j)/nCol;}

const fbInt FB L1 = 4;const fbInt FB L2 = 3;const fbInt FB L3 = 2;const fbInt FB L4 = 1;

const fbInt FB R1 = -1;const fbInt FB R2 = -2;const fbInt FB R3 = -3;const fbInt FB R4 = -4;

/∗! Funzione che calcola con l’algoritmo di deCasteljau pti dello spazio \f$ E∧2 \f$per le costanti che richiamano i pti e’ stata utilizzata la stessa convenzionede Computer Graphics Authors: Foley VanDam (Pag 508)

∗/fbPoint DeCasteljau( const fbInt degree, //! Grado

const fbDouble t, //! Parametroconst fbPoint∗ p, //! Pti di controlloconst fbInt nMiddlePoint); //! Per estrarre i pti di controllo intermedi 1<degree+1

/∗!fbPoint fbCurveSubCtrlPnt(const fbPoint∗ p,const fbInt nVal, const fbDouble dTval):

funzione che calcola i sotto punti di controllo di un arco di Bezier di 3 grado

const fbPoint∗ p -> vettore di pti di controlloconst fbDouble dTval -> valore del parametroconst fbInt nVal -> pto da calcolare

∗/fbPoint fbCurveSubCtrlPnt(const fbPoint∗ p,const fbDouble dTval,const fbInt nVal);

//! Funzione che calcola il determinante di una matrice 2x2// Calcola il determinante di una matrice 2x2 [[a c]// [b d]]

inline fbDouble det2x2(const fbDouble a,const fbDouble b,const fbDouble c,const fbDouble d){

return (a∗d-b∗c);}

//! Funzione che calcola il determinante di una matrice 3x3// Calcola il determinante di una matrice 2x2 [[a d g]// [b e h]// [c f i]]inline fbDouble det3x3( const fbDouble a,const fbDouble b,const fbDouble c,\

const fbDouble d,const fbDouble e,const fbDouble f,\const fbDouble g,const fbDouble h,const fbDouble i)

{return (a∗det2x2(e,f,h,i)-d∗det2x2(b,c,h,i)+g∗det2x2(b,c,e,f));

}

//! Per le matrici utilizzi la stessa convenzione di OpenGL//! e le memorizzo per colonneclass fbVector;

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗\|∗ fbMatrix ∗|\∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/

/∗!fbMatrix classe per la gestione di matrici (esclusivamente 4x4)i principali operatori sono previsti la convenzione utilizzata perla memorizzazione rispecchia quella OpenGL (e’ possibile passaregli elementi di una matrice a glMultMatrix()

∗/class fbMatrix{private:

//! Vettore con le variabilifbDouble m pdValue[16];

//! Vettore per il ritorno della colonna

123

Page 132: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

// l’ho reso fisso per un miglior controllo di memoriafbDouble m pdTempColumn[4];

//! Numero di righefbInt m nRow;

//! Numero di ColonnefbInt m nCol;

//! Metodo che calcola il prodotto tra una riga ed una colonnainline fbDouble dRowColProduct(fbDouble ∗pRow,fbDouble ∗pCol);

public:

fbMatrix();

fbMatrix(const fbMatrix&);

virtual ∼fbMatrix();

//! Prodotto fra matricifbMatrix operator∗(fbMatrix&);

//! Prodotto fra matrice e vettore colonnafbVector operator∗(fbVector&);

//! Assegnazione fra matricifbMatrix& operator=(const fbMatrix&);

//! Fissa la dimensione della matrice <= 4x4inline void SetSize(const fbInt nRow,const fbInt nCol);

//! Ritorna la dimensione della matrice <= 4x4inline void GetSize(fbInt &nRow,fbInt& nCol);

//! Ritorna il valore nella posizione nRow nCol (0<=nRow,nCol<=3 )inline fbDouble& GetValue(const fbInt nRow,const fbInt nCol);

//! Fissa il valore nella posizione nRow nCol (0<=nRow,nCol<=3 )inline void SetValue(const fbInt r,const fbInt c,const fbDouble dVal);

//! Copia pElements come elementi della matricevoid SetValues(const fbDouble∗ pElements);

//! Ritorna la colonna nella posizione nCol (0<=nCol<=3 )inline fbDouble∗ GetColumn(const fbInt nCol);

//! Ritorna la riga nella posizione nRow (0<=nCol<=3 )inline fbDouble∗ GetRow(const fbInt nRow);

//! Traspone la matricevoid transpose();

//! Calcola il determinante della matricefbDouble det();

//! Calcola l’inversa della matricefbMatrix& inv();

//! Metodo per costruire una matrice di Vandermonde con il vettore colonnafbMatrix& Vandermonde(const fbDouble& a,const fbDouble& b,const fbDouble& c,const fbDouble& d);

//! Stampa a console della matricevoid Print();

friend std::ostream& operator�(std::ostream&,fbMatrix&);friend std::ostream& operator�(std::ostream&,fbMatrix∗);

};

/∗———————————————————∗\|∗ Espansione inline per la class fbMatrix ∗||∗ BEGIN ∗|\∗———————————————————∗/

inline fbDouble fbMatrix::dRowColProduct(fbDouble ∗pRow,fbDouble ∗pCol){

return ((pRow[0]∗pCol[0])+(pRow[1]∗pCol[1])+(pRow[2]∗pCol[2])+(pRow[3]∗pCol[3]));}

//! Fissa la dimensione della matrice <= 4x4inline void fbMatrix::SetSize(const fbInt nRow,const fbInt nCol){

m nRow=nRow;m nCol=nCol;

}

//! Ritorna la dimensione della matrice <= 4x4inline void fbMatrix::GetSize(fbInt &nRow,fbInt& nCol){

nCol = m nCol;nRow = m nRow;

124

Page 133: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

}

//! Ritorna il valore nella posizione nRow nCol (0<=nRow,nCol<=3 )inline fbDouble& fbMatrix::GetValue(const fbInt nRow,const fbInt nCol){

return m pdValue[nRow∗4+nCol];}

//! Fissa il valore nella posizione nRow nCol (0<=nRow,nCol<=3 )inline void fbMatrix::SetValue(const fbInt r,const fbInt c,const fbDouble dVal){

m pdValue[r∗4+c]=dVal;}

//! Ritorna la colonna nella posizione nCol (0<=nCol<=3 )inline fbDouble∗ fbMatrix::GetColumn(const fbInt nCol){

m pdTempColumn[0] = GetValue(0,nCol); m pdTempColumn[1] = GetValue(1,nCol);m pdTempColumn[2] = GetValue(2,nCol); m pdTempColumn[3] = GetValue(3,nCol);

return &m pdTempColumn[0];}

//! Ritorna la riga nella posizione nRow (0<=nCol<=3 )inline fbDouble∗ fbMatrix::GetRow(const fbInt nRow){

return &m pdValue[nRow∗m nRow] ;}/∗———————————————————∗\|∗ END ∗||∗ Espansione inline per la class fbMatrix ∗|\∗———————————————————∗/

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗\|∗ fbVector ∗|\∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/

class fbVector{

public:enum fbVectorType{

FB VECTOR COLUMN,FB VECTOR ROW

};

// Costruttore di default un vettore e’ colonna e di 4 elementifbVector();

//! Costuttore (tipo vettore(riga-colonna),dimensione)fbVector(const fbVectorType,const fbInt);

//! Costruttore di copiefbVector(const fbVector&);

//! Costruttore per vettore colonna a 2 dimensionifbVector(const fbDouble x,const fbDouble y);

//! Costruttore per vettore colonna a 3 dimensionifbVector(const fbDouble x,const fbDouble y,const fbDouble z);

//! Costruttore per vettore colonna a 4 dimensionifbVector(const fbDouble x,const fbDouble y,const fbDouble z,const fbDouble w);

//! Costruttore che calcola il vettore (colonna) da 2 pti bidimensionali (p2-p1)fbVector(const fbPoint& p1,const fbPoint& p2);

//! Distruttorevirtual ∼fbVector();

//! Ritorna la dimensioneinline fbInt GetSize() const;

//! Ritorna l’orientamento (riga,colonna)inline fbInt GetType() const;

//! Fissa il valore in nPos a dVal (se errore rilancia fbRangeException)void SetElement(const fbInt nPos,const fbDouble dVal);

/∗!Fissa gli elementi del vettore in funzione delle dimensioni del vettore passato (per default 4)i valori e la dimensione precedente vengono cancellate.

∗/void SetElements(const fbDouble∗,const fbInt nSize=4);

/∗! Fissa il vettore a 2 dimensioni con valori v[0] = el1 e v[1] = el2i valori e la dimensione precedente vengono cancellate.

∗/void SetElements(const fbDouble& el1,const fbDouble& el2);

125

Page 134: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

/∗! Fissa il vettore a 3 dimensioni con valori v[0] = el1 , v[1] = el2 e v[2] = el3i valori e la dimensione precedente vengono cancellate.

∗/void SetElements(const fbDouble& el1,const fbDouble& el2,const fbDouble& el3);

/∗! Fissa il vettore a 3 dimensioni con valori v[0] = el1 , v[1] = el2 , v[2] = el3 e v[3] = el4i valori e la dimensione precedente vengono cancellate.

∗/void SetElements(const fbDouble& el1,const fbDouble& el2,const fbDouble& el3,const fbDouble& el4);

//! Ritorna l’elemento in posizione nPos (se errore rilancia fbRangeException)fbDouble GetElement(const fbInt nPos) const;

//! Modulo del vettoreconst fbDouble Abs() const;

//! Normalizza il vettorefbVector& Normalize();

//! InizializzazionefbVector& operator= (const fbVector &);

//! Prodotto scalare fra due vettori (se errore rilancia fbRangeException)fbDouble operator∗ (const fbVector& vect);

//! Prodotto con uno scalarefbVector operator∗ (const fbDouble dVal);

//! Prodotto con uno scalarefbVector& operator∗ = (const fbDouble dVal);

/∗!Prodotto vettoriale (il vettore in uscita e’ dimensionato in modo da essere coerentema non gestisce casi maggiori di vettori a 3 dimensioni)

∗/fbVector operator∧ (const fbVector &vect);

//! Meno unario (ruota il vettore di 180 gradi)inline fbVector& operator- ();

//! Restituisce l’elemento in posizione nPos (se errore rilancia fbRangeException)fbDouble& operator[ ] (const fbInt nPos);

//! Stampa a videofriend std::ostream& operator�(std::ostream&,fbVector&);friend std::ostream& operator�(std::ostream&,fbVector∗);

private://! Elementi del vettorefbDouble ∗m pdEls;

//! Dimensioni del vettorefbInt m nSize;

//! Tipo del vettore e dimensionefbVectorType m nType;

};

/∗———————————————————∗\|∗ Espansione inline per la class fbVector ∗||∗ BEGIN ∗|\∗———————————————————∗/

inline fbVector& fbVector::operator-(){

for(fbInt i = 0;i < m nSize; i++)m pdEls[i] = -m pdEls[i];

return ∗this;}

inline fbInt fbVector::GetSize() const{

return m nSize;}

inline fbInt fbVector::GetType() const{

return m nType;}

/∗———————————————————∗\|∗ END ∗||∗ Espansione inline per la class fbVector ∗|\∗———————————————————∗/

/∗———————————————————∗\|∗ fbVector VS fbPoint ∗|

126

Page 135: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

|∗ Funzioni comuni per la gestione ∗||∗ di vettori e pti. ∗|\∗———————————————————∗/

//! Prodotto per uno scalarefbVector operator∗ (const fbDouble dVal,const fbVector& v); // d ∗ v = v

//! Ritorna un pto dalla somma di un pto con un vettoretemplate <class T> inline fbPoint2<T> operator+ (const fbPoint2<T>& p,const fbVector& v) // p + v = p{

return fbPoint2<T>(p.X + v.GetElement(0),p.Y + v.GetElement(1));}

template <class T> inline fbPoint3<T> operator+ (const fbPoint3<T>& p,const fbVector& v) // p + v = p{

return fbPoint3<T>(p.X + v.GetElement(0),p.Y + v.GetElement(1),p.Z + v.GetElement(2));}

template <class T> inline fbPoint4<T> operator+ (const fbPoint4<T>& p,const fbVector& v) // p + v = p{

return fbPoint4<T>(p.X + v.GetElement(0),p.Y + v.GetElement(1),p.Z + v.GetElement(2),p.W +v.GetElement(3));}

//! Ritorna un pto dalla somma di un pto con un vettoreinline fbPoint operator+ (const fbVector& v,const fbPoint& p) // v + p = p{

return fbPoint(p.X + v.GetElement(0),p.Y + v.GetElement(1));}template <class T> inline fbPoint2<T> operator+ (const fbVector& v,const fbPoint2<T>& p) // v + p = p{

return fbPoint2<T>(p.X + v.GetElement(0),p.Y + v.GetElement(1));}template <class T> inline fbPoint3<T> operator+ (const fbVector& v,const fbPoint3<T>& p) // v + p = p{

return fbPoint3<T>(p.X + v.GetElement(0),p.Y + v.GetElement(1),p.Z + v.GetElement(3));}template <class T> inline fbPoint4<T> operator+ (const fbVector& v,const fbPoint4<T>& p) // v + p = p{

return fbPoint4<T>(p.X + v.GetElement(0),p.Y + v.GetElement(1),p.Z + v.GetElement(2),p.W +v.GetElement(3));}

//! Ritorna un pto dalla somma di un pto con un vettoreinline fbPoint operator+ (const fbPoint∗ p,const fbVector& v) // p + v = p{

return fbPoint(p→X + v.GetElement(0),p→Y + v.GetElement(1));}template <class T> inline fbPoint2<T> operator+ (const fbPoint2<T>∗ p,const fbVector& v) // p + v = p{

return fbPoint(p→X + v.GetElement(0),p→Y + v.GetElement(1));}template <class T> inline fbPoint3<T> operator+ (const fbPoint3<T>∗ p,const fbVector& v) // p + v = p{

return fbPoint(p→X + v.GetElement(0),p→Y + v.GetElement(1),p→Z + v.GetElement(2));}template <class T> inline fbPoint4<T> operator+ (const fbPoint4<T>∗ p,const fbVector& v) // p + v = p{

return fbPoint(p→X + v.GetElement(0),p→Y + v.GetElement(1),p→Z + v.GetElement(2),p→W +v.GetElement(3));}

//! Ritorna un pto dalla somma di un pto con un vettoreinline fbPoint operator+ (const fbVector& v,const fbPoint∗ p) // v + p = p{

return fbPoint(p→X + v.GetElement(0),p→Y + v.GetElement(1));}template <class T> inline fbPoint2<T> operator+ (const fbVector& v,const fbPoint2<T>∗ p) // v + p = p{

return fbPoint(p→X + v.GetElement(0),p→Y + v.GetElement(1));}template <class T> inline fbPoint3<T> operator+ (const fbVector& v,const fbPoint3<T>∗ p) // v + p = p{

return fbPoint(p→X + v.GetElement(0),p→Y + v.GetElement(1),p→Z + v.GetElement(2));}template <class T> inline fbPoint4<T> operator+ (const fbVector& v,const fbPoint4<T>∗ p) // v + p = p{

return fbPoint(p→X + v.GetElement(0),p→Y + v.GetElement(1),p→Z + v.GetElement(2),p→W +v.GetElement(3));}

//! Ritorna un vettore come somma di 2 vettoriinline fbVector operator+ (const fbVector& a,const fbVector& b) // p + v = p{

return fbVector ( a.GetElement(0)+b.GetElement(0),a.GetElement(1)+b.GetElement(1));}

//! Ritorna un vettore dalla differenza tra 2 pti (p1-p2)inline fbVector operator- (const fbPoint& p1,const fbPoint& p2) // p - p = v{

return fbVector(p2,p1);

127

Page 136: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

}

template <class T> inline fbVector operator- (const fbPoint2<T>& p1,const fbPoint2<T>& p2) // p - p = v{

return fbVector(p2,p1);}

template <class T> inline fbVector operator- (const fbPoint3<T>& p1,const fbPoint3<T>& p2) // p - p = v{

fbVector p(fbVector::FB VECTOR COLUMN,3);

p[0] = p2.X - p1.X;p[1] = p2.Y - p1.Y;p[2] = p2.Z - p1.Z;

return p;}

template <class T> inline fbVector operator- (const fbPoint4<T>& p1,const fbPoint4<T>& p2) // p - p = v{

fbVector p(fbVector::FB VECTOR COLUMN,4);

p[0] = p2.X - p1.X;p[1] = p2.Y - p1.Y;p[2] = p2.Z - p1.Z;p[3] = p2.W - p1.W;

return p;}

//! Ritorna un vettore dalla differenza tra 2 vettori (v2-v1)inline fbVector operator- (const fbVector& v1,const fbVector& v2) // v - v = v{

fbIntnMin = fbMin(v1.GetSize(),v2.GetSize());

fbVector p (fbVector::FB VECTOR COLUMN,3);

for(fbInt i = 0; i< nMin;i++)p[i] = v2.GetElement(i)-v1.GetElement(i);

return p;}

//! Ritorna un pto applicato al vettore ruotato di 180 gradi

template <class T> inline T operator- (const T& p,const fbVector& v) // p - v = p{

fbVector v1(v);return (p + (-v1));

}

//! Ritorna un pto applicato al vettore ruotato di 180 gradi

template <class T> inline T operator- (const fbVector& v,const T& p) // v - p = p{

fbVector v1(v);return (-T(p) + v1);

}

//! Rotazione di 90 gradiinline fbVector fbVectorRotate90(const fbVector& vToRotate){

return fbVector(-vToRotate.GetElement(1),vToRotate.GetElement(0));}

//! Rotazione di -90 gradiinline fbVector fbVectorRotateMinus90(const fbVector& vToRotate){

return fbVector(vToRotate.GetElement(1),-vToRotate.GetElement(0));}

#endif // FBMATH H//———————————————————// End Of File//———————————————————

A.1.22 fbOperation//———————————————————//// FILENAME : fbOperation.h//// CLASS(ES) ://// DESCRIPTION : Classe per la gestione degli algoritmi

128

Page 137: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

// di suddivisioni di fbCurve//// HISTORY ://———————————————————#ifndef FB OPERATION H#define FB OPERATION H

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000

#include fbConfig.h

#include fbPoint.h

#include fbStraightLine.h

#include fbCircle.h

#include fbFunction.h

class fbOperation :public fbFunctionDouble{public:

fbOperation();virtual ∼fbOperation();virtual fbDouble operator ()(){

return 0;};virtual fbDouble operator ()(const fbDouble ,const fbDouble ,const fbDouble ,const fbDouble ,const

fbDouble ,const fbDouble ){

return 0;};

};

/∗!Classe per disegnare nell’algoritmo di suddivisione

∗/class fbCurveDraw :public fbOperation{public:

fbCurveDraw();virtual ∼fbCurveDraw();fbDouble operator ()( const fbDouble px1,const fbDouble py1,\

const fbDouble px2,const fbDouble py2,const fbDouble t0,const fbDouble t1);

};

/∗!Classe per effettuare le misurazioniil valore deve essere calcolato esternamente qua ci occupiamo di memorizzaregli incrementi successivi

∗/class fbCurveMeasure: public fbOperation{

fbDouble m dCurveLenght;

public:

fbCurveMeasure():m dCurveLenght(0.0)

{}

virtual ∼fbCurveMeasure(){}

inline fbDouble operator ()( const fbDouble px1,const fbDouble py1,\const fbDouble px2,const fbDouble py2,const fbDouble t0,const fbDouble t1)

{return m dCurveLenght+=fbPointsDistance(px1,py1,px2,py2);

};

inline fbDouble operator ()(){

return m dCurveLenght;};

};

class fbCurve;

/∗!Classe per effettuare la parametrizzazione uniforme

∗/template <class Container > class fbCurveSubdivideUniform: public fbOperation{

//! Tolleranza richista dall’algoritmofbDouble m dTolerance;

129

Page 138: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

//! Passo richiestofbDouble m dStep;

//! Flag per il controllo dell’inserimento dell’ ultimo valorefbInt m nLastInterval;

//! Numero di intervalli previstifbInt m nIntervals;

//! Vettore dove salvare il parametroContainer& m Container;

//! Curva di cui devo effettuare la suddivisionefbCurve∗ m pCurve;

public:

//! CostruttorefbCurveSubdivideUniform(Container& Cont,const fbDouble dStep,const fbDouble dTolerance,fbCurve∗

pCurve):m Container (Cont ),m pCurve (pCurve)

{m dStep = fbAbs(dStep);m dTolerance = fbAbs(dTolerance);

}

virtual ∼fbCurveSubdivideUniform(){}

fbDouble operator ()(){

FB TRACE(Non capisco questo controllo: riguardalo\n);if( m dStep < m dTolerance )

return FB ERROR;

fbDoubledRatio = m pCurve→GetLenght();

if(dRatio <= m dStep)return 0;

dRatio /= m dStep;

// numero di intervalli da calcolarem nIntervals = (fbInt)floor(dRatio);

/∗FBErase :controllo inutile

// se c’e’ qualcosa di sbagliato ritornoif ( m nIntervals <= 0)

return FB ERROR;else∗/{

// In linea di principio non posso sapere// se l’ultimo valore deve essere inserito o meno, dipende dal// resto di questa divisione se e’ prossimo a zero allora// non lo inserisco altrimento si’ (il passo di divisione e’// fissato a piacere e quindi potrebbe non essere un multiplo// della lunghezza della linea)

if(fbAbs(dRatio - m nIntervals) < m dTolerance)m nLastInterval = 1;

elsem nLastInterval = 0;

FB TRACE(Posso migliorare questo codice calcolando prima la curva [0,t1]\n);FB TRACE(poi, da quella, calcolare [t0,t1]. Alla fine faccio \n);FB TRACE(la differenza tra la lunghezza di L1 e quella di L0\n);FB TRACE(in questo modo risparmio cicli di calcolo della lunghezza nelle fasi finali.\n);

// inizio la ricercarecursion(0.0,1.0);

}return m Container.size();

}

private:

/∗!Calcola in modo ricorsivo i parametri necessari per unaparametrizzazione uniforme

∗/void recursion(const fbDouble t0,const fbDouble t1){

if(t1-t0 < FB EPSILON)return;

// Calcolo le curve individuate dai due parametri correnti...fbCurve∗

130

Page 139: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

pCurveLeft 0 = m pCurve→GetLeftArc(t0);fbCurve∗

pCurveLeft 1 = m pCurve→GetLeftArc(t1);

// ... e la loro lunghezzafbDouble

dL0 = pCurveLeft 0→GetLenght(),dL1 = pCurveLeft 1→GetLenght();

// calcolo il valore della lunghezza di parametrizzazionefbDouble

dCurrentStepLenght = (m Container.size() + 1)∗m dStep;

// se la lunghezza massima per questo intervallo e’ minore di quella// prevista per la parametrizzazione ritornoif(dL1 < dCurrentStepLenght){

delete pCurveLeft 0;delete pCurveLeft 1;return;

}

// se la lunghezza massima e’ minore di m dTolerance della lunghezza// di parametrizzazioneif ( dL1 - dCurrentStepLenght < m dTolerance){

delete pCurveLeft 0;delete pCurveLeft 1;

// aggiungo il valore del parametro corrente proporzionale alla lunghezza che// gli competeif( m Container.size () < (unsigned)(m nIntervals-m nLastInterval) ) // test di ultimo intervallo

(vedi sopra)m Container.push back( (t1 - t0) / (dL1 - dL0) ∗ (dCurrentStepLenght - dL0 ) + t0 );

}else // divisioni successive{

delete pCurveLeft 0;delete pCurveLeft 1;

fbDoubletm = (t1 + t0) ∗0.5;

recursion(t0,tm);recursion(tm,t1);

}}

};

/∗!Classe per effettuare la parametrizzazione PixelBased

∗/template <class Container > class fbCurveSubdividePixelSize: public fbOperation{

//! Vettore dove salvare il parametroContainer& m Container;

public:

//! CostruttorefbCurveSubdividePixelSize(Container& Cont)

:m Container (Cont ){}

virtual ∼fbCurveSubdividePixelSize(){}

fbDouble operator ()( const fbDouble px1,const fbDouble py1,const fbDouble px2,const fbDouble py2,const fbDouble t0 ,const fbDouble t1)

{if(t1 != 1.0)

m Container.push back(t1);

return m Container.size();}

};

/∗!Classe per calcolore il parametro che spetta ad una data lunghezzaAggiunto posizioni iniziali del parametro per accelerare la ricerca.

∗/class fbCurveSubdivideForLenght: public fbOperation{

//! Curva di cui devo effettuare la suddivisionefbCurve∗ m pCurve;

//! Tolleranza richista dall’algoritmofbDouble m dTolerance;

131

Page 140: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

//! Passo richiestofbDouble m dStep;

//!Valore trovatofbDouble m dParameterValue;

//!Valori del parametro inizialifbDouble m dT0,m dT1;

public:

//! CostruttorefbCurveSubdivideForLenght( const fbDouble dStep,

const fbDouble dTolerance,fbCurve ∗pCurve,const fbDouble dT0=0.0,const fbDouble dT1=1.0);

virtual ∼fbCurveSubdivideForLenght();

fbDouble operator ()();

private:void recursion(const fbDouble t0,const fbDouble t1);

};

/∗!Classe per la gestione delle intersezioni con le rette∗/

template <class Container > class fbIntersectStraightLine : public fbOperation{

//! Container per i risultatiContainer &C;//! TolleranzafbDouble m dTolerance;//! Pti della rettafbPoint m p1,m p2;//! Riferimento alla curvafbCurve ∗m pCurve;

public:fbIntersectStraightLine(Container& Cont,const fbStraightLine& StraightLine,const fbDouble dTol, fbCurve∗

pCurve):C ( Cont ),m dTolerance ( dTol ),m pCurve ( pCurve )

{m p1 = StraightLine.GetPoint(0);m p2 = StraightLine.GetPoint(1);

}

virtual ∼fbIntersectStraightLine(){}

/∗!Non dovrebbero essere necessari controlli di consistenza dati(pto p1 == p2) perche’ sono svolti dalla routine di ricorsionedella fbCurve∗/

fbDouble operator ()( const fbDouble px1,const fbDouble py1,const fbDouble px2,const fbDouble py2,const fbDouble t0 ,const fbDouble t1)

{static fbDouble

beta,x,y;static fbCurve

∗pTempCurve 1;

static fbOperation∗pOperation;

switch(fbSegmentIntersection(px1,py1,px2,py2,\m p1.X,m p1.Y,\m p2.X,m p2.Y,x,y))

{case fbSegment::FB SEGMENT DO INTERSECT:

FB STUB();FB TRACE(Potenziale baco di divisione per 0\n);beta = fbPointsDistance( px1, py1, x , y ) / fbPointsDistance(px1, py1, px2, py2);beta = t0 + (t1-t0)∗beta;if ( fbPointsDistance( m pCurve→GetPoint(beta) , fbPoint( x, y ) ) < m dTolerance){

C.push back(beta);return C.size();

}else{

pTempCurve 1 = m pCurve→GetLeftArc( t0 );

132

Page 141: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

pOperation = new fbCurveSubdivideForLenght( pTempCurve 1→GetLenght()+fbPointsDistance( fbPoint(px1,py1),\

fbPoint( x, y ) ),m dTolerance,m pCurve,t0,t1);

if((∗pOperation )() != FB ERROR )C.push back((∗pOperation )());

delete pOperation;delete pTempCurve 1;return C.size();

}

break;case fbSegment::FB SEGMENT COLLINEAR:

C.push back(t0 + (t1-t0)∗0.5);return C.size();break;

}

return C.size();}

};

/∗!Classe per la gestione delle intersezioni con le rette∗/

template <class Container > class fbIntersectCircle : public fbOperation{

//! Container per i risultatiContainer &C;//! TolleranzafbDouble m dTolerance;//! Pti del cerchiofbPoint m Center;//! Pti del cerchiofbDouble m dMetaRadius;

//! Riferimento alla curvafbCurve ∗m pCurve;

public:fbIntersectCircle(Container& Cont,const fbCircle& Circle,const fbDouble dTol, fbCurve∗ pCurve)

:C ( Cont ),m dTolerance ( dTol ),m pCurve ( pCurve )

{m Center = Circle.GetCenter();m dMetaRadius = Circle.GetRadius();m dMetaRadius ∗ = m dMetaRadius;

}

virtual ∼fbIntersectCircle(){}

/∗!Non dovrebbero essere necessari controlli di consistenza dati(pto p1 == p2) perche’ sono svolti dalla routine di ricorsionedella fbCurve∗/

fbDouble operator ()( const fbDouble px1,const fbDouble py1,const fbDouble px2,const fbDouble py2,const fbDouble t0 ,const fbDouble t1)

{static fbDouble

dMetaDistance1,dMetaDistance2;

dMetaDistance1 = fbAbs( px1 - m Center.X ) + fbAbs( py1 - m Center.Y ) ;dMetaDistance2 = fbAbs( px2 - m Center.X ) + fbAbs( py2 - m Center.Y ) ;

fbIntnNumberOfSolution = 0;

fbDoubledx = px2 - px1,dy = py2 - py1,a = dy,b = -dx,c = (py1 - m Center.Y) ∗ dx - (px1 - m Center.X) ∗ dy;

if( (dMetaDistance1 <= m dMetaRadius && m dMetaRadius <= dMetaDistance2 ) ||(dMetaDistance2 <= m dMetaRadius && m dMetaRadius <= dMetaDistance1 ) ||c∗c / (a∗a + b∗b ) <= m dMetaRadius )

{// se sono interno ha senso cercare intersezione// traslo la retta rispetto al centro e risolvo il polinomio

133

Page 142: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

static fbDoubledSol 1,dSol 2;

static fbPointintersection;

if (a != 0.0 ){

fbDoublea1 = a ∗ a + b ∗ b,b1 = 2.0 ∗ b ∗ c,c1 = c ∗ c - m dMetaRadius ∗ a ∗ a ;

nNumberOfSolution = fbPoly2DegreeFindRoots(a1, b1, c1, dSol 1, dSol 2);

if( nNumberOfSolution == 0 )return C.size();

}else{

if(b != 0){

dSol 1 = sqrt(m dMetaRadius - (c∗c / b∗b));dSol 2 = -dSol 1;nNumberOfSolution = -1;

}else{

// sono paralleli e scelgo una via di mezzointersection = fbPointMiddle(fbPoint(px1,py1),fbPoint(px2,py2));nNumberOfSolution = 11;

}}

static fbCurve∗pTempCurve 1;

static fbOperation∗pOperation;

switch( nNumberOfSolution ){case 1: // due soluzioni reali e coincidenti

intersection.Y = dSol 1;intersection.X = -(b ∗ intersection.Y + c ) / a;

intersection.X += m Center.X;intersection.Y += m Center.Y;

if( ( py1 < intersection.Y && intersection.Y < py2 ) ||( py1 > intersection.Y && intersection.Y > py2 ) )

{pTempCurve 1 = m pCurve→GetLeftArc( t0 );

pOperation = new fbCurveSubdivideForLenght( pTempCurve 1→GetLenght()+fbPointsDistance( fbPoint(px1,py1), intersection ), m dTolerance, m pCurve);

if((∗pOperation )() != FB ERROR )C.push back((∗pOperation )());

delete pOperation;delete pTempCurve 1;

}break;

case -1:// soluzione lungo y

intersection.X = dSol 1;intersection.Y = -(a ∗ intersection.X + c ) / b;

intersection.X += m Center.X;intersection.Y += m Center.Y;

if( ( px1 < intersection.X && intersection.X < px2 ) ||( px1 > intersection.X && intersection.X > px2 ) )

{pTempCurve 1 = m pCurve→GetLeftArc( t0 );

pOperation = new fbCurveSubdivideForLenght( pTempCurve 1→GetLenght()+fbPointsDistance( fbPoint(px1,py1), intersection ), m dTolerance, m pCurve);

if((∗pOperation )() != FB ERROR )C.push back((∗pOperation )());

delete pOperation;delete pTempCurve 1;

}

intersection.X = dSol 2;intersection.Y = -(a ∗ intersection.X + c ) / b;

intersection.X += m Center.X;

134

Page 143: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

intersection.Y += m Center.Y;if( ( px1 < intersection.X && intersection.X < px2 ) ||

( px1 > intersection.X && intersection.X > px2 ) ){

pTempCurve 1 = m pCurve→GetLeftArc( t0 );

pOperation = new fbCurveSubdivideForLenght( pTempCurve 1→GetLenght()+fbPointsDistance( fbPoint(px1,py1), intersection ), m dTolerance, m pCurve);

if((∗pOperation )() != FB ERROR )C.push back((∗pOperation )());

delete pOperation;delete pTempCurve 1;

}break;

case 2:// due soluzioni reali e distinte

intersection.Y = dSol 1;intersection.X = -(b ∗ intersection.Y + c ) / a;

intersection.X += m Center.X;intersection.Y += m Center.Y;

if( ( py1 < intersection.Y && intersection.Y < py2 ) ||( py1 > intersection.Y && intersection.Y > py2 ) )

{pTempCurve 1 = m pCurve→GetLeftArc( t0 );

pOperation = new fbCurveSubdivideForLenght( pTempCurve 1→GetLenght()+fbPointsDistance( fbPoint(px1,py1), intersection ), m dTolerance, m pCurve);

if((∗pOperation )() != FB ERROR )C.push back((∗pOperation )());

delete pOperation;delete pTempCurve 1;

}

intersection.Y = dSol 2;intersection.X = -(b ∗ intersection.Y + c ) / a;

intersection.X += m Center.X;intersection.Y += m Center.Y;

if( ( py1 < intersection.Y && intersection.Y < py2 ) ||( py1 > intersection.Y && intersection.Y > py2 ) )

{pTempCurve 1 = m pCurve→GetLeftArc( t0 );

pOperation = new fbCurveSubdivideForLenght( pTempCurve 1→GetLenght()+fbPointsDistance( fbPoint(px1,py1), intersection ), m dTolerance, m pCurve);

if((∗pOperation )() != FB ERROR )C.push back((∗pOperation )());

delete pOperation;delete pTempCurve 1;

}break;

case 11:// paralleleFB TRACE(Rette parallele\n);

pTempCurve 1 = m pCurve→GetLeftArc( t0 );

pOperation = new fbCurveSubdivideForLenght( pTempCurve 1→GetLenght()+fbPointsDistance( fbPoint(px1,py1), intersection ), m dTolerance, m pCurve);

if((∗pOperation )() != FB ERROR )C.push back((∗pOperation )());

delete pOperation;delete pTempCurve 1;

break;}

}return C.size();

}};

/∗!Calcola l’intervallo di lunghezza minimaN.B. il risultato e’ ottenuto dalla chiamata a funzione :res = (∗operation)() ;

∗/class fbCurveMinimumSegment : public fbOperation{

private:

135

Page 144: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

//! Valore del minimofbDouble m dMinimumSegment;

//! Valori del parametro per cui si ha il minimofbDouble

m dT0,m dT1;

public:

fbCurveMinimumSegment();

virtual ∼fbCurveMinimumSegment();

/∗!Funzione usata nella suddivisione ricorsiva

∗/fbDouble operator ()( const fbDouble px1,const fbDouble py1,

const fbDouble px2,const fbDouble py2,const fbDouble t0 ,const fbDouble t1);

/∗!Ritorna il valore del minimo∗/

fbDouble operator ()();

/∗!Ritorna i valori del parametro per cui si consegue il minimo.∗/

void GetValuesOfParameters(fbDouble& dt0,fbDouble& dt1) const;

};

/∗!Calcola l’intervallo di lunghezza massimaN.B. il risultato e’ ottenuto dalla chiamata a funzione :res = (∗operation)() ;

∗/class fbCurveMaximumSegment : public fbOperation{private:

//! Valore del minimofbDouble m dMaximumSegment;

//! Valori del parametro per cui si ha il minimofbDouble

m dT0,m dT1;

public:

fbCurveMaximumSegment ();

virtual ∼fbCurveMaximumSegment ();

/∗!Funzione usata nella suddivisione ricorsiva

∗/fbDouble operator ()( const fbDouble px1,const fbDouble py1,

const fbDouble px2,const fbDouble py2,const fbDouble t0 ,const fbDouble t1);

/∗!Ritorna il valore del minimo∗/

fbDouble operator ()();

/∗!Ritorna i valori del parametro per cui si consegue il minimo.∗/

void GetValuesOfParameters(fbDouble& dt0,fbDouble& dt1) const;

};

/∗!Calcola la curva di grado minore

∗/void fbCurveReduction( fbCurve∗ pCurve, std::vector<fbPoint>& vPnts, fbDouble& dLeft,fbDouble& dRight);

template <class Container > class fbCurveDegreeReduction : public fbOperation{private:

136

Page 145: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

//! Container per i risultatiContainer &C;

//! TolleranzafbDouble m dTolerance;

//! Riferimento alla curvafbCurve ∗m pCurve;

std::vector<fbPoint> m pTempVect;

fbDoubledMaxLeftError,dMaxRightError;

public:fbCurveDegreeReduction(Container& Cont,fbDouble dTol, fbCurve∗ pCurve)

:C ( Cont ),m dTolerance ( dTol ),m pCurve ( pCurve )

{};

virtual ∼fbCurveDegreeReduction(){};

/∗!Funzione usata nella suddivisione ricorsiva

∗/fbDouble operator ()( const fbDouble px1,const fbDouble py1,

const fbDouble px2,const fbDouble py2,const fbDouble t0 ,const fbDouble t1)

{if(t1-t0 < FB EPSILON)

return;

m pTempVect.clear();

fbCurveReduction(m pCurve, m pTempVect, dMaxLeftError,dMaxRightError);

if( dMaxLeftError <= m dTolerance && dMaxRightError <=m dTolerance ){

C.push back( (t0+t1)∗0.5 );return;

}};

/∗!Ritorna il valore del minimo∗/

fbDouble operator ()(){};

};

#endif // !defined( FB OPERATION H )//———————————————————// End Of File//———————————————————

A.1.23 fbPan//———————————————————//// FILENAME : fbPan.h//// CLASS(ES) : fbPan//// DESCRIPTION ://// HISTORY ://———————————————————#ifndef FB PAN H#define FB PAN H

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000

#include fbConfig.h

#include fbTool.h

#include fbPoint.h

#include fbFrame.h

#include <list>class fbFasped;class fbFrame;

//! fbPan Tool di gestione della traslazione/∗!

fbPan gestisce la traslazione del contesto grafico per fare

137

Page 146: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

panoramica∗/class fbPan : public fbTool{

//! Stato del bottone (regola il disegno)fbBool

m bIsPressed;

//! Pti del disegnofbDouble

m pCursor[4];

//! Riferimento all’ ultima posizione validafbPoint

m OldPosition;public:

void Clear();

fbPan(fbFasped∗ pWin);

virtual ∼fbPan();

//! Gestione generica del movimento mousevoid HandleMouseMove (const fbUInt nButtonPressed, const fbDouble x, const fbDouble y) ;

//! Gestione generica della pressione di un bottono mousevoid HandleMouse (const fbUInt nButtonPressed, const fbDouble x, const fbDouble y) ;

void InitGL();void Draw();

};

#endif // !defined( FB PAN H )//———————————————————// End Of File//———————————————————

A.1.24 fbPencil//———————————————————//// FILENAME:fbPencil.h//// CLASS(ES)://// DESCRIPTION://// DATE : Fri Oct 6 2000// COPYRIGTH: (C) 2000 by Fabrizio Morciano// E MAIL : [email protected]////———————————————————

#ifndef FB PENCIL H#define FB PENCIL H

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000

#include fbConfig.h

#include fbTool.h

#include fbStraightLine.h

#include fbCurve.h

#include fbCircle.h

#include <vector>

//! fbPencil/∗!

fbPencil : Classe che gestisce il disegno inserendo linee nel frame∗/class fbPencil : public fbTool{private:

//! Vettore di pti di descrizione per rappresentare un cursorefbDouble m pCursor[4];

//! Vettore contenente i pti acquisiti dal mouse movestd::vector<fbPoint> m vPointsSampled;

public:void Clear();fbPencil(fbFasped∗);virtual ∼fbPencil();

void HandleMouse (const fbUInt nButtonPressedAndStatus,const fbDouble x,const fbDouble y);void HandleMouseMove(const fbUInt nButtonPressedAndStatus,const fbDouble x,const fbDouble y);

//! Inizializzazione

138

Page 147: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

/∗!Inizializza le componenti openGL del tool∗/

void InitGL();

void Draw();

};

#endif // !defined( FB PENCIL H )//———————————————————// End Of File//———————————————————

A.1.25 fbPen//———————————————————//// FILENAME:fbPen.h//// CLASS(ES)://// DESCRIPTION://// DATE : Fri Oct 6 2000// COPYRIGTH: (C) 2000 by Fabrizio Morciano// E MAIL : [email protected]////———————————————————

#ifndef FB PEN H#define FB PEN H

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000

#include fbConfig.h

#include fbTool.h

#include fbStraightLine.h

#include fbCurve.h

#include fbCircle.h

#include <vector>

//! fbPen/∗!

fbPen : Classe che gestisce il disegno inserendo linee nel frame∗/class fbPen : public fbTool{private:

//! Flag per stabilire se sono alla prima selezionefbBool m bFirstPoint;

//! Vettore di pti di descrizione per rappresentare un cursorefbDouble m pCursor[4];

//! Segmenti per rappresentare le tangentifbSegment m PrevTangent, m NextTangent;

//! Curva fantasma per la manipolazione temporaneafbCurve m GhostCurve;

//! Cerchi di visualizzazione estremi (bilancini) e di chiusura lineafbCircle m Circle[3];

//! Pti di backup della posizione appena abbandonatafbPoint m pPrevPositions[2];

public:void Clear();fbPen(fbFasped∗);virtual ∼fbPen();

void HandleMouse (const fbUInt nButtonPressedAndStatus,const fbDouble x,const fbDouble y);void HandleMouseMove(const fbUInt nButtonPressedAndStatus,const fbDouble x,const fbDouble y);

//! Inizializzazione/∗!

Inizializza le componenti openGL del tool∗/

void InitGL();

void Draw();

};

#endif // !defined( FB PEN H )

139

Page 148: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

//———————————————————// End Of File//———————————————————

A.1.26 fbPointManipulator//———————————————————//// FILENAME : fbPointManipulator.h//// CLASS(ES) :// fbPointManipulator// ListOfFFDInfoBackInsertIterator//// DESCRIPTION : Classe per la gestione del tool di manipolazione a forma di pto//// HISTORY : 14/09/2000//———————————————————#ifndef FB POINT MANIPULATOR H#define FB POINT MANIPULATOR H

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000

#include fbPoint.h

#include fbTool.h

#include fbConfig.h

#include fbCircle.h

#include fbFrame.h

#include fbPolyLine.h

#include fbPotential.h

#include <list>#include <vector>

/∗!fbPointManipulator : Tool che sfrutta gli algoritmi di FreeFornDeformation perfare una qualche manipolazione sul frame.

∗/class fbPointManipulator : public fbTool{

/∗!fbCurveInfoFFD per la freeform deformation carica la curva che ha intersezioni

con la regione di potenziale e i sottoarchi in cui e’ stata suddivisa∗/

struct fbCurveInfoFFD{

fbCurve∗ m pCurve;PolyLine m lCurves;fbCurveInfoFFD(fbCurve∗ pCurve,PolyLine& Curves)

:m pCurve(pCurve){

std::copy(Curves.begin(),Curves.end(),PolyLineBackInsertIterator<PolyLine>(m lCurves));}

};

//! Cerchietto a videofbCircle m Circle;

//! Copia del cerchietto a video per i calcoli successivifbCircle m CopyOfCircle;

//! Booleano per stabilire se deve essere variato la dimensione del cerhiofbBool m bMoveCircleRadius;

//! Booleano per stabilire se deve essere mosso il toolfbBool m bMoveTool;

//! Pto per il posizionamento preciso in presenza di selezione non perfettafbPoint m LocalOffset;

//! Flag per l’inseguimento del mousefbBool m bFollowMouse;

//! Lista di curve che sono interessate dall’intersezione con il manipolatorestd::list< fbCurveInfoFFD> m lSelectedCurves;

//! Copia della lista di curve che sono interessate dall’intersezione con il manipolatorestd::list< fbCurveInfoFFD> m lCopyOfSelectedCurves;

//! Flag per permettere la traslazione invece della funzione potenzialefbBool m bIsTranslable;

//! Funzione potenziale per il toolfbPotential∗ m PotentialFunction;

public:

140

Page 149: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

void SubdivideCurves();

enum{

FB PNT MAN CURVES MATCH = 0,// indica dove e quando fare la suddivisioneFB PNT MAN SPLIT LEFT = 1,FB PNT MAN SPLIT RIGHT = 2

};

fbPointManipulator(fbFasped∗ pAppl);

virtual ∼fbPointManipulator();

// Gestione generica del movimento mousevirtual void HandleMouseMove (const fbUInt nButtonPressed, const fbDouble dPositionX, const fbDouble

dPositionY) ;

// Gestione generica della pressione di un bottono mousevirtual void HandleMouse (const fbUInt nButtonPressed, const fbDouble dPositionX, const fbDouble

dPositionY) ;

void Draw();void InitGL();void Clear();

//! Sostiuisce le curve che sono state variatevoid ReplaceCurves();

//! Pulisce le strutture che ono servonovoid ClearLists();

//! Calcola le intersezioni con il toolvoid FindIntersection();

//! Classe per la gestione degli insert iteratorfriend class ListOfFFDInfoBackInsertIterator;

};

//———————————————————

/∗!ListOfFFDInfoBackInsertIterator si occupa della copia della lista delle curve selezionate

∗/class ListOfFFDInfoBackInsertIterator{

std::list<fbPointManipulator:: fbCurveInfoFFD>& container;public:

explicit ListOfFFDInfoBackInsertIterator(std::list<fbPointManipulator:: fbCurveInfoFFD>& Line):container(Line)

{};

ListOfFFDInfoBackInsertIterator& operator=(fbPointManipulator:: fbCurveInfoFFD& value ){

container.push back(fbPointManipulator:: fbCurveInfoFFD(newfbCurve(∗value.m pCurve),value.m lCurves));

return (∗this);};

ListOfFFDInfoBackInsertIterator& operator∗() {return (∗this); }ListOfFFDInfoBackInsertIterator& operator++() {return (∗this); }ListOfFFDInfoBackInsertIterator operator++(int) {return (∗this); }

};

#endif // !defined( FB POINT MANIPULATOR H )//———————————————————// End Of File//———————————————————

A.1.27 fbPoint//———————————————————//// FILENAME : fbPoint.h//// CLASS(ES) : fbPoint//// DESCRIPTION : Classe per la gestione di un pto//// HISTORY : 10/11/2000//———————————————————#ifndef FB POINT H#define FB POINT H

#include <cmath>#include <iostream>#include fbConfig.h

/∗!

141

Page 150: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

fbPoint2 classe per la gestione di un pto bidimensionale∗/

template <class T> class fbPoint2{

public:T X,Y;

fbPoint2() :X(0) ,Y(0) {};fbPoint2(const fbPoint2& p) :X(p.X) ,Y(p.Y) {};fbPoint2(const T x,const T y) :X(x) ,Y(y) {};

virtual ∼fbPoint2(){};

fbBool operator==(const fbPoint2& p){

if(this→X == p.X && this→Y == p.Y)return true;

return false;}

#if FASPED MAJOR VERSION < 1//! Per compatibilita’inline void SetPosition(const T x,const T y){

X = x; Y= y;}

#endif

fbPoint2& operator∗ =(const T dVal){

X ∗ = dVal;Y ∗ = dVal;

return ∗this;}

fbPoint2 operator∗(const T dVal) const{

fbPoint2outVal;

outVal.X ∗ = dVal;outVal.Y ∗ = dVal;

return outVal;}

fbPoint2<T>& operator-(){

X = -X;Y = -Y;

return ∗this;}

};

/∗!fbPoint3 classe per la gestione di un pto trimidensionale / o bidimensionale omogeneo

∗/template <class T> class fbPoint3{

public:T X,Y,Z;fbPoint3() :X(0) ,Y(0) ,Z(0) {};fbPoint3(const fbPoint3& p) :X(p.X) ,Y(p.Y) ,Z(p.Z) {};fbPoint3(const T x,const T y,const T z) :X(x) ,Y(y) ,Z(z) {};virtual ∼fbPoint3(){};

fbBool operator==(const fbPoint3& p){

if(this→X == p.X && this→Y == p.Y && this→Z == p.Z )return true;

return false;}

fbPoint3& operator∗ =(const T dVal){

X ∗ = dVal;Y ∗ = dVal;Z ∗ = dVal;

return ∗this;}

fbPoint3 operator∗(const T dVal)

142

Page 151: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

{fbPoint3

outVal;outVal.X ∗ = dVal;outVal.Y ∗ = dVal;outVal.Z ∗ = dVal;

return outVal;}

fbPoint3& operator-(){

X = -X;Y = -Y;Z = -Z;

return ∗this;}

};

/∗!fbPoint4 classe per la gestione di un pto quadridensionale / o tridimensionale omogeneo

∗/template <class T> class fbPoint4{

public:T X,Y,Z,W;

fbPoint4() :X(0) ,Y(0) ,Z(0) ,W(0) {};fbPoint4(const fbPoint3<T>& p) :X(p.X) ,Y(p.Y) ,Z(p.Z) ,W(p.W) {};fbPoint4(const T x,const T y,const T z,const T w) :X(x) ,Y(y) ,Z(z) ,W(w) {};virtual ∼fbPoint4(){};

fbBool operator==(const fbPoint4& p){

if(this→X == p.X && this→Y == p.Y && this→Z == p.Z && this→W == p.W)return true;

return false;}

fbPoint4& operator∗ =(const T dVal){

X ∗ = dVal;Y ∗ = dVal;Z ∗ = dVal;W ∗ = dVal;

return ∗this;}

fbPoint4 operator∗(const T dVal){

fbPoint4outVal;

outVal.X ∗ = dVal;outVal.Y ∗ = dVal;outVal.Z ∗ = dVal;outVal.W ∗ = dVal;

return outVal;}

fbPoint4& operator-(){

X = -X;Y = -Y;Z = -Z;W = -W;

return ∗this;}

};

//! Typedef per compatibilita’typedef fbPoint2<fbDouble> fbPoint;

//! Pto medio/∗inline fbPoint fbPointMiddle(const fbPoint& p1,const fbPoint& p2){

return fbPoint( (p1.X + p2.X)∗0.5 , (p1.Y+ p2.Y)∗0.5 );}∗/

template <class T> inline fbPoint2<T> fbPointMiddle(const fbPoint2<T>& p1,const fbPoint2<T>& p2){

143

Page 152: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

return fbPoint2<T>( (p1.X + p2.X)∗0.5 , (p1.Y+ p2.Y)∗0.5 );}

template <class T> inline fbPoint3<T> fbPointMiddle(const fbPoint3<T>& p1,const fbPoint3<T>& p2){

return fbPoint3<T>( (p1.X + p2.X)∗0.5 , (p1.Y+ p2.Y)∗0.5 ,(p1.Z + p2.Z)∗0.5);}

template <class T> inline fbPoint4<T> fbPointMiddle(const fbPoint4<T>& p1,const fbPoint4<T>& p2){

return fbPoint4<T>( (p1.X + p2.X)∗0.5 , (p1.Y+ p2.Y)∗0.5 ,(p1.Z + p2.Z)∗0.5,(p1.W + p2.W)∗0.5);}

//! Distanza fra 2 ptitemplate <class T> inline T fbPointsDistance(const fbPoint2<T>& p1,const fbPoint2<T>& p2){

return sqrt( fbSqr(p2.X - p1.X) + fbSqr(p2.Y - p1.Y));}

template <class T> inline T fbPointsDistance(const fbPoint3<T>& p1,const fbPoint3<T>& p2){

return sqrt( fbSqr(p2.X - p1.X) + fbSqr(p2.Y - p1.Y) + fbSqr(p2.Z - p1.Z));}

template <class T> inline T fbPointsDistance(const fbPoint4<T>& p1,const fbPoint4<T>& p2){

return sqrt( fbSqr(p2.X - p1.X) + fbSqr(p2.Y - p1.Y) + fbSqr(p2.Z - p1.Z) + fbSqr(p2.W - p1.W));}

//! Distanza fra 2 ptitemplate <class T> inline T fbPointsDistance(const T x1,const T y1,const T x2,const T y2){

return sqrt( fbSqr(x2-x1) + fbSqr(y2-y1));}

template <class T> inline T fbPointsDistance(const T x1,const T y1,const T z1,const T x2,const T y2,const T z2){

return sqrt( fbSqr(x2-x1) + fbSqr(y2-y1) + fbSqr(z2-z1));}

//! Test di collinearita’ (p2-p1)∧(p3-p1) (ritorna true false e non tiene conto del segno)fbBool fbPointsAreCollinear(const fbPoint& p1,const fbPoint& p2,const fbPoint& p3,const fbDoubledTolerance);

//! Test di collinearita’ (p2-p1)∧(p3-p1) (ritorna il valore di altezza (v1∧v2)[2] e tiene conto del segno)fbDouble fbPointsAreCollinear(const fbPoint& p1,const fbPoint& p2,const fbPoint& p3);

/∗!Ritorna le coordinate baricentriche di 3 ptiSe i pti non sono collineari ritorna falsese c’e’ un errore a = b =FB DOUBLE MAX

∗/fbBool fbPointsGetBaycentricCoordinates(fbDouble& dAlpha,fbDouble& dBeta,const fbPoint& p1,constfbPoint& p2,const fbPoint& p3,const fbDouble dTolerance);

/∗!Calcola la coordinata baricentrica fra 2 pti fissati i valori alpha e beta

∗/inline fbPoint fbPointsSetBaycentricCoordinates(const fbDouble dAlpha,const fbDouble dBeta,const fbPoint&p1,const fbPoint& p2){

fbPoint outPoint;

outPoint.X = p1.X ∗ dAlpha + p2.X ∗ dBeta;outPoint.Y = p1.Y ∗ dAlpha + p2.Y ∗ dBeta;

return outPoint;}

const fbUInt FB POINT CROSS = 0;const fbUInt FB POINT CIRCLE = 1;const fbUInt FB POINT CIRCLE FULL = 2;const fbUInt FB POINT QUAD = 3;

void fbPointDraw(const fbPoint& p,\const fbDouble dSizeInPixel,\const fbDouble dTol,\const fbInt nType=FB POINT CIRCLE);

template <class T> std::ostream& operator�(std::ostream& os,const fbPoint2<T>& p){

os�p.X�’ ’�p.Y�endl;return os;

}

template <class T> std::ostream& operator�(std::ostream& os,const fbPoint2<T>∗ p){

os�p→X�’ ’�p→Y�endl;return os;

144

Page 153: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

}

template <class T> std::ostream& operator�(std::ostream& os,const fbPoint3<T>& p){

os�p.X�’ ’�p.Y�’ ’�p.Z�endl;return os;

}

template <class T> std::ostream& operator�(std::ostream& os,const fbPoint3<T>∗ p){

os�p→X�’ ’�p→Y�’ ’�p→Z�endl;return os;

}

template <class T> std::ostream& operator�(std::ostream& os,const fbPoint4<T>& p){

os�p.X�’ ’�p.Y�’ ’�p.Z�’ ’�p.W�endl;return os;

}

template <class T> std::ostream& operator�(std::ostream& os,const fbPoint4<T>∗ p){

os�p→X�’ ’�p→Y�’ ’�p→Z�’ ’�p→W�endl;return os;

}

template <class T> std::istream& operator�(std::istream& is,fbPoint2<T>& p){

is�p.X�p.Y;return is;

}

template <class T> std::istream& operator�(std::istream& is,fbPoint2<T>∗ p){

is�p→X�p→Y;return is;

}

template <class T> std::istream& operator�(std::istream& is,fbPoint3<T>& p){

is�p.X�p.Y�p.Z;return is;

}

template <class T> std::istream& operator�(std::istream& is,fbPoint3<T>∗ p){

is�p→X�p→Y�p→Z;return is;

}

template <class T> std::istream& operator�(std::istream& is,fbPoint4<T>& p){

is�p.X�p.Y�p.Z�p.W;return is;

}

template <class T> std::istream& operator�(std::istream& is,fbPoint4<T>∗ p){

is�p→X�p→Y�p→Z�p→W;return is;

}

template <class T> inline fbPoint2<T> operator∗(const T dVal, const fbPoint2<T>& p){

return p.operator∗(dVal);}

template <class T> inline fbPoint3<T> operator∗(const T dVal, const fbPoint3<T>& p){

return p.operator∗(dVal);}

template <class T> inline fbPoint4<T> operator∗(const T dVal, const fbPoint4<T>& p){

return p.operator∗(dVal);}#endif // FB POINT H//———————————————————// End OF File//———————————————————

A.1.28 fbPolyLine//———————————————————//// FILENAME : fbPolyLine.h//// CLASS(ES) :

145

Page 154: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

// fbPolyLine// fbFindCurveInPolyline// PolyLineBackInsertIterator//// DESCRIPTION : Classe per la gestione di una polyline//// HISTORY ://———————————————————#ifndef FB POLYLINE H#define FB POLYLINE H

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000

#include fbConfig.h

#include fbGrOb.h

#include fbCurve.h

#include fbPoint.h

#include <list>#include <functional>

//———————————————————

//! Iteratori per la struttura list<fbCurve∗>typedef std::list<fbCurve∗> PolyLine;typedef PolyLine::iterator itPolyLine;typedef PolyLine::reverse iterator ritPolyLine;typedef PolyLine::const iterator citPolyLine;typedef PolyLine::const reverse iterator critPolyLine;

//! Funzione di Pulizia per una PolyLinevoid fbPolyLineClear(PolyLine& PLine);void fbPolyLineClear(PolyLine∗ PLine);

/∗!PolyLineBackInsertIterator Classe inseritrice copia una polyline copiando

nella nuova polyline tutte le curve presenti∗/

template <class Container> class PolyLineBackInsertIterator{

Container& container;public:

explicit PolyLineBackInsertIterator(Container& Line):container(Line)

{};

PolyLineBackInsertIterator& operator=(const fbCurve∗ value ){

container.push back(new fbCurve(∗value));return (∗this);

};

PolyLineBackInsertIterator& operator∗() {return (∗this); }PolyLineBackInsertIterator& operator++() {return (∗this); }PolyLineBackInsertIterator operator++(int) {return (∗this); }

};

//———————————————————

/∗!fbFindCurveInPolyline : Classe per la ricerca nella polyline

∗/class fbFindCurveInPolyline:public std::unary function<fbCurve∗,fbBool>{

fbPoint m PointToCheck;fbDouble m dPickRay;fbInt m nCheckArea;

public:enum{

FB FIND IN CONVEX HULL,FB FIND IN MIN MAX

};

explicit fbFindCurveInPolyline(const fbPoint& Point,const fbDouble dPickRay,const fbIntnCheckArea=FB FIND IN CONVEX HULL)

:m PointToCheck (Point),m dPickRay (dPickRay),m nCheckArea (nCheckArea)

{};

bool operator() (fbCurve∗ a) const{

if(!a→GetVisibility())return false;

if(m nCheckArea == FB FIND IN CONVEX HULL)if(a→CheckPointInConvexHull(m PointToCheck,m dPickRay))

return true;

146

Page 155: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

if(m nCheckArea == FB FIND IN MIN MAX)if(a→CheckPointInMinMax(m PointToCheck,m dPickRay))

return true;

return false;};

};

//———————————————————

/∗!fbPolyLine : Classe per la gestione di una linea di curve∗/

class fbPolyLine : public fbGrOb{

//! Lista di curvePolyLine m lCurve;

//! t della curva selezionatafbDouble m dT;

//! t della curva selezionatafbDouble m dDistance;

//! tipo di curvafbInt m nPolylineType;

public:

//! Ritorna la lista delle polyline che sono interne al cerchiofbInt IntersectionWithCircle(fbCircle& Circle, std::list<fbPolyLine∗>& lPL);

//! Aggiunge un oggetto fbPolyLine alla linea correntevoid AddPolyLine(fbPolyLine∗ pPL);

//! Aggiunge un oggetto fbPolyLine alla linea correntevoid AddPolyLine(PolyLine∗ pPL);

//! inizializza prima del disegnovoid InitGL();

//! Valore del bottom left della minmaxboxfbPoint m MinMaxBottomLeft;

//! calcola la minmaxBoxvoid setMinMaxBox();

//! Ritorna un pto della polyline per valore dT del parametrofbPoint GetPoint(const fbDouble dT);

//! Metodo che restituisce true se la curva e’ nella polylineitPolyLine Select(const fbCurve∗ pCurve);

//!Ritorna un handler alla struttura delle lineePolyLine& GetPolyLine();

void AcceptVisitor(fbVisitor∗ pVisitor);

//! Riferimento alla curva che segue pCurve o NULL se l’ultima (se pCurve == 0 ritorna l’ultima)fbCurve∗ GetNext(fbCurve∗ pCurve) const;

//! Riferimento alla curva che precede pCurve o NULL se la prima (se pCurve == 0 ritorna la prima)fbCurve∗ GetPrev(fbCurve∗ pCurve) const;

//! Seleziona una curva con pto di controllo vicino a Point/∗! Seleziona la curva pCurveSelected il cui pto di controllo nPointOffset

sia a meno di dPickRay da PointN.B. dPickRay e’ assunto essere il quadrato del valore di raggio di pick

in tal modo le distanze sono controllate senza calcolare le radici∗/void SelectByControlPoint(const fbPoint& Point,const fbDouble dPickRay,fbInt&

nControlPoint,itPolyLine& itPLine);

/∗! Tipo unumerato per indicare il tipo∗ -Tipo di curve∗ -# FB POLYLINE CLOSED∗ l’ultima curva ha l’ultimo pto in comune con la prima∗ -# FB POLYLINE OPENED∗ l’ultima curva non ha collegamenti con la prima∗/enum{

FB POLYLINE CLOSED ,FB POLYLINE OPENED

};

fbPolyLine();

//!

147

Page 156: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

fbPolyLine(const PolyLine& Line);

//!

//!fbPolyLine(const std::vector<fbPoint>& vPnts, const fbVector& ,const fbVector& ,const fbDouble

dTolerance);

virtual ∼fbPolyLine();

//! Costruttore di copiafbPolyLine(const fbPolyLine& Line);

//! Operatore di assegnazionefbPolyLine& operator=(const fbPolyLine& Line);

//! Seleziona una curvavoid Select(const fbPoint& Point,const fbDouble dPickRay,fbDouble& dTValue,fbCurve∗ &pOutCurve);

//! Seleziona la curva della polyline piu’ vicina a Pointvoid SelectByPoint(const fbPoint& Point,const fbDouble dPickRay,fbDouble& dTValue,itPolyLine&

itPLine);

//! Ritorna il tipo di curva (chiusa o aperta)fbInt GetType() const { return m nPolylineType;}

//! Ritorna il tipo di curva (chiusa o aperta)void SetType(const fbInt nType){

if(nType == FB POLYLINE CLOSED )m nPolylineType = FB POLYLINE CLOSED;

if(nType == FB POLYLINE OPENED )m nPolylineType = FB POLYLINE OPENED;

};

//! Disegna la polylinevoid Draw();

//! Elimina una curvavoid DeleteCurve(fbCurve∗ pCurve);

//! Aggiunge una curvainline void AddCurve(fbCurve∗ pCurve);

//! T della ultima curva selezionata -1 altrimentiinline fbDouble GetT() const;

//! Distanza del pto dall’ultima curva selezionata -1 altrimentiinline fbDouble GetDistance() const;

//! Elimina tutte le curve della listavoid DeleteAllCurves();

friend std::ostream& operator �(std::ostream &os, fbPolyLine ∗pPLine);friend std::ostream& operator �(std::ostream &os, fbPolyLine &pPLine);friend std::istream& operator �(std::istream &is, fbPolyLine ∗pPLine);friend std::istream& operator �(std::istream &is, fbPolyLine &pPLine);

};

/∗——————————————————-∗\|∗ Espansione inline per la classe fbPolyLine ∗||∗ BEGIN ∗|\∗——————————————————-∗/

inline void fbPolyLine::AddCurve(fbCurve∗ pCurve){

SetInitGL(false);m lCurve.push back(pCurve);

}

inline fbDouble fbPolyLine::GetT() const{

return m dT;}

inline fbDouble fbPolyLine::GetDistance() const{

return m dDistance;}

/∗——————————————————-∗\|∗ END ∗||∗ Espansione inline per la classe fbPolyLine ∗|\∗——————————————————-∗/

//———————————————————

148

Page 157: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

/∗!Restituisce la curva precedente pCurve nella polyline o null

∗/fbCurve∗ fbPolyLineGetPrev(const PolyLine& PLine,fbCurve ∗pCurve);

/∗!Restituisce la curva seguente pCurve nella polyline o null

∗/fbCurve∗ fbPolyLineGetNext(const PolyLine& PLine,fbCurve ∗pCurve);

/∗!Converte una curva (a meno di tolleranza) nella rispettiva polyline

∗/void fbPolyLineConvertCurveToPolyLine(fbCurve∗ pCurve,const fbDouble dTol,PolyLine& PLine);

/∗!Converte una curva nella rispettiva polyline utilizzando i valori presenti in vIn

∗/void fbPolyLineConvertCurveToPolyLine(fbCurve∗ pCurve,const std::vector<fbDouble>& vIn,PolyLine& PLine);

// restituisce il pto della polyline che compete al valore di t selezionatofbPoint fbPolyLineGetPoint(const PolyLine& PLine, const fbDouble dT);

// restituisce l’iteratore della polyline che compete al valore di t selzionatoitPolyLine fbPolyLineTPositionToArcIterator(PolyLine& PLine,const fbDouble t);

//! Cerca di diminuire il numero di archi presenti nella polylinevoid fbPolyLineReduction(PolyLine& PLine,const fbDouble dTolerance);

#endif // !defined( FB POLYLINE H )

//———————————————————// End Of File//———————————————————

A.1.29 fbPotential//———————————————————//// FILENAME : fbPotential.h//// CLASS(ES) : fbPotential//// DESCRIPTION : Classe per la gestione della funzione potenziale da applicare// al tool manipulator//// HISTORY ://———————————————————#ifndef FB POTENTIAL H#define FB POTENTIAL H

#include fbConfig.h

#include fbFunction.h

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000

/∗!fbPotential : classe astratta per la descrizione di una funzione potenziale

∗/class fbPotential : public fbFunction<fbDouble>{public:

fbPotential();virtual ∼fbPotential();virtual fbDouble GetPotential(const fbPoint& PointToTest) = 0;

};

/∗!fbPotentialConstant : classe per la gestione di un potenziale costante

∗/class fbPotentialConstant: public fbPotential{public:

fbPotentialConstant() {};virtual ∼fbPotentialConstant() {};

fbDouble GetPotential(const fbPoint& PointToTest){

return 1.0;}

fbDouble operator()(fbFactorsDouble& Factors){

return 1.0;}

149

Page 158: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

};

/∗!fbPotentialSpherical : classe per la gestione del potenziale nel caso sferico

∗/class fbPotentialSpherical : public fbPotential{private:

fbDouble m dMetaSphereRadius;fbPoint m SphereCenter;

public:

fbPotentialSpherical(const fbDouble dRadiusForTest,const fbPoint SphereCenter);

virtual ∼fbPotentialSpherical(){};

fbDouble GetPotential(const fbPoint& PointToTest);

fbDouble operator()(fbFactorsDouble& Factors){

FB STUB();return 1.0;

}

};

#endif // !defined( FB POTENTIAL H )//———————————————————// End Of File//———————————————————

A.1.30 fbRectangle//———————————————————//// FILENAME : fbRectangle.h//// CLASS(ES) : fbRectangle//// DESCRIPTION : Classe per disegno di un rettangolo//// HISTORY : 23/08/2000//———————————————————

#ifndef FB RECTANGLE H#define FB RECTANGLE H

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000

#include fbGrOb.h

#include fbPoint.h

#include fbConfig.h

#include fbPolyLine.h

class fbRectangle : public fbGrOb{protected:

fbPoint m BottomLeft;public:

fbPoint GetVertex(const fbInt nVertex) const;enum{

FB RECTANGLE V1 = 0,// bottom left |FB RECTANGLE V2 = 1,// anticlockwiseFB RECTANGLE V3 = 2,// up rightFB RECTANGLE V4 = 3

};void SetBarycentre(const fbPoint& Barycentre);fbPoint GetBarycentre() const;fbRectangle IntersectionWithRectangle(const fbRectangle&);fbBool CheckPointInRectangle(const fbPoint&) const;

const static fbInt fbRectangleMatch ;const static fbInt fbRectangleOverlap ;const static fbInt fbRectangleDisjoint ;

void Draw();fbRectangle();fbRectangle(const fbDouble dWidth, const fbDouble dHeight);fbRectangle(const fbPoint&,const fbDouble dWidth, const fbDouble dHeight);fbRectangle(const fbPoint&,const fbPoint&);virtual ∼fbRectangle();

150

Page 159: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

/// Fissa il bottom left del rettangolo (le dimensioni sono fissate da SetSize)void SetBottomLeft(const fbPoint&);

/// Ritorna il bottom left del rettangolo (le dimensioni sono fissate da SetSize)fbPoint GetBottomLeft() const {return m BottomLeft;};

/// Funzione che controlla se 2 rettangoli si contengonofriend fbBool fbRectangleCheckOverlap(const fbRectangle&a,const fbRectangle&b);

};

void fbRectangleToPolyline(const fbRectangle& Rect,PolyLine& PLine);

#endif // !defined( FB RECTANGLE H )//———————————————————// End Of File//———————————————————

A.1.31 fbSaver//———————————————————//// FILENAME : fbSaver.h//// CLASS(ES) : fbSaver// DESCRIPTION : Classe per il salvataggio delle informazioni//// HISTORY ://———————————————————#ifndef FBSAVER H#define FBSAVER H

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000

#include fbConfig.h

#include fbRectangle.h

#include fbFrame.h

#include fbException.h

#include fbPoint.h

#include fbFasped.h

#include fbPolyLine.h

#include fbCurve.h

class fbSaver{public:

fbBool SaveFile(const fbChar∗ pFileName);fbSaver(fbFasped ∗);virtual ∼fbSaver();

private:fbBool SaveFSE(const fbChar ∗ pFileName);fbFasped ∗m pApplicationReference;

};

fbBool fbSaveFRP(const fbChar ∗pFileName, const std::vector<fbPoint>& vPnts );#endif // !defined( FBSAVER H )//———————————————————// End Of File//———————————————————

A.1.32 fbSelector//———————————————————//// FILENAME : fbSelector.h//// CLASS(ES) : fbSelector//// DESCRIPTION ://// HISTORY ://———————————————————#ifndef FB SELECTOR H#define FB SELECTOR H

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000

#include fbTool.h

#include fbRectangle.h

#include fbPolyLine.h

class fbSelector : public fbTool

151

Page 160: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

{public:

void Draw();void HandleMouse (const fbUInt nButtonPressed, const fbDouble x, const fbDouble y);void HandleMouseMove (const fbUInt nButtonPressed, const fbDouble y, const fbDouble x);void Clear();void InitGL();fbSelector(fbFasped∗ pAppl);virtual ∼fbSelector();

private:PolyLine m PLineFound;fbRectangle m BBox;

};

#endif // !defined( FB SELECTOR H )//———————————————————// End Of File//———————————————————

A.1.33 fbStraightLine//———————————————————//// FILENAME : fbStraightLine.h//// CLASS(ES) :// fbStraightLine// fbSegment// DESCRIPTION : Classi per la gestione di rette e segmenti//// HISTORY : 23/08/2000//———————————————————#ifndef FB SLINE H#define FB SLINE H

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000

#include fbGrOb.h

#include fbPoint.h

#include fbConfig.h

#include fbMath.h

#include <vector>

/∗!fbStraightLine Classe per la gestione di una retta∗/

class fbStraightLine : public fbGrOb{protected:

//! Pti della retta fissano anche il verso di percorrenza vanno da//! m Point[0] -> m Point[1]fbPoint m Point[2];

//! Coeff dell’ equazione normalizzatafbDouble m da,m db,m dc;

//! Ordine dei pti/∗! Flag che comunica se l’ordine dei pti e’ cambiato rispetto a quesso specificato

-# true ordine 0 1-# false ordine 1 0

∗/fbBool m bOrder;

//! Radice quadrata de \f$ sqrt(a∧2+b∧2)\f$ utile nella misura della distanzafbDouble m dSqrtOfa2plusb2;

public:fbVector GetNormalVector() const;

/∗∗ Retta delle ascissse ∗/static fbStraightLine XAxis;/∗∗ Retta delle ascissse ∗/static fbStraightLine YAxis;

//! Enumeratore per recuperare i pti della retta \f$ (y-y 0)/(y 1-y 0) = (x-x 0)/(x 1-x 0) \f$enum{

FB SLINE P1 = 0,FB SLINE P2 = 1

};

fbStraightLine();fbStraightLine(const fbPoint&,const fbPoint&);virtual ∼fbStraightLine();

152

Page 161: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

//! Ritorna la distanza del ptovirtual fbDouble DistanceFromPoint(const fbPoint&) const;

//! Ritorna la distanza del ptovirtual fbDouble DistanceFromPoint(const fbDouble px,const fbDouble py) const;

/∗! Calcola la retta normale alla corrente passante per il ptoscelto

∗/fbStraightLine NormalStraightLineInPoint(const fbPoint&) const;

void Draw();

//! Ritorna il coeff angolare della retta o FB DOUBLE MAX se m db = 0fbDouble GetAngle() const;

//! Restituisce unO dei pti passati per fissare la retta (0 -> il primo , 1 -> il secondo)fbPoint GetPoint(const fbInt nVal) const;

//! Restituisce i pti passati per fissare la rettavoid GetPoints(fbPoint& p1,fbPoint& p2 ) const;

//! Ritorna i coeff della rettavoid GetCoeff(fbDouble& a,fbDouble& b,fbDouble& c) const;

//! Fissa i coeff della retta e ricalcola i pti di descrizione della rettavoid SetCoeff(const fbDouble,const fbDouble,const fbDouble);

//! Fissa un pto di descrizione della retta (0 -> il primo, 1 -> il secondo)void SetPoint(const fbPoint&,const fbInt nVal);

//! Fissa i pti per la rettavoid SetPoints(const fbPoint&,const fbPoint&);

//! Fissa i pti per la rettavoid SetPoints(const fbDouble p1x,const fbDouble p1y,const fbDouble p2x,const fbDouble p2y);

void GetBarycentricCoords(const fbPoint& point,fbDouble& a,fbDouble& b) const;

//! Calcola il pto d’intesezione fra 2 rettefriend fbPoint fbStraightLineIntersection(const fbStraightLine& first,const fbStraightLine& second);friend void fbCircleIntersectionWithStraightLine(const fbCircle& Circle,const fbStraightLine

StraightLine,std::vector<fbPoint>& vecRes);};

/∗!fbSegment Classe per la gestione di un segmento∗/

class fbSegment : public fbStraightLine{public:

enum{

FB SEGMENT DONT INTERSECT = 0,FB SEGMENT DO INTERSECT = 1,FB SEGMENT COLLINEAR = 2

};fbSegment(const fbStraightLine&);fbDouble GetLenght() const;

fbSegment(){};fbSegment(const fbPoint&,const fbPoint&);virtual ∼fbSegment();void Draw();

//! Ritorna la distanza del pto con il check del rangefbDouble DistanceFromPoint(const fbPoint &p) const;

//! Controlla che il pto appartenga al segmentofbBool ChekPointInSegment(const fbPoint&) const;

/∗! Ritorna il tpo d’intersezione fra 2 segmenti o un pto non valido(MAX DOUBLE)se l’intersezione e’ vuota

∗/

friend fbPoint fbSegmentIntersection(fbSegment& first,fbSegment& second);};

fbInt fbSegmentIntersection(const fbDouble p1x,const fbDouble p1y,const fbDouble p2x,const fbDouble p2y,\const fbDouble p3x,const fbDouble p3y,const fbDouble p4x,const fbDouble

p4y,fbDouble& p,fbDouble& py);

inline fbInt fbSegmentIntersection(const fbPoint& P1,const fbPoint& P2,const fbPoint& P3,const fbPoint&P4,fbPoint& p){

return fbSegmentIntersection(P1.X,P1.Y,P2.X,P2.Y,P3.X,P3.Y,P4.X,P4.Y,p.X,p.Y);}

#endif // !defined( FB SLINE H )//———————————————————

153

Page 162: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

//End Of File//———————————————————

A.1.34 fbSubSelector//———————————————————//// FILENAME : fbSubSelector.h//// CLASS(ES) : fbSubSelector//// DESCRIPTION : Tool per la gestione delle linee mediante i pti di controllo//// DATE : 11/11/2000// COPYRIGTH : (C) 2000 by Fabrizio Morciano// E MAIL : [email protected]////———————————————————#ifndef FB SUBSELECTOR H#define FB SUBSELECTOR H

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000

#include fbTool.h

#include fbConfig.h

//! fbSubSelector: Gestisce i pti di controllo delle curve/∗!

Permette la manipolazione dei pti di controllo delle curve∗/

class fbSubSelector : public fbTool{private:

//! Puntatore alla curva individuata al pickfbCurve∗ m pCurveToModifyLeft;

//!Copia per le modifiche a videofbCurve∗ m pCopyOfCurveToModifyLeft;

//! Puntatore alla curva individuata al pickfbCurve∗ m pCurveToModifyRight;

//!Copia per le modifiche a videofbCurve∗ m pCopyOfCurveToModifyRight;

//! Pto selzionato tra gli Anchor PointsfbInt m nPnt;

//! Flag di collinearita’fbBool m bIsCollinear;

public:

//! Trova il tool piu’ vicino al ptofbInt FindAnchor(const fbPoint& Point);

fbSubSelector(fbFasped∗);

virtual ∼fbSubSelector();

void Draw();void InitGL();void Clear();void HandleMouseMove(const fbUInt nButtonPressedAndStatus,const fbDouble x,const fbDouble y);void HandleMouse(const fbUInt nButtonPressedAndStatus,const fbDouble x,const fbDouble y);

private:struct fbPointWithStatus{

fbPoint m Pnt;fbBool m bIsValid;

fbPointWithStatus():m Pnt (fbPoint(FB DOUBLE MAX,FB DOUBLE MAX)),m bIsValid (false){}

fbPointWithStatus(fbPoint Pnt, fbBool bIsValid):m Pnt (Pnt),m bIsValid (bIsValid){}

};

//! Anchor point a videofbPointWithStatus m pAnchorPoints[3];

};

154

Page 163: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

#endif // !defined( FB SUBSELECTOR H )//———————————————————// End Of File//———————————————————

A.1.35 fbTool//———————————————————//// FILENAME : fbTool.h//// CLASS(ES) : fbTool//// DESCRIPTION : Classe per la gestione dei tool di disegno//// HISTORY :// Presa la decisione di lavorare anche con i tools in coordinate// mondo la trasformazione di coordinate avviene ad un livello// superiore (dalla finestra che gestisce il tool e che si preoccupa// di collocarlo)// 29/09/2000://———————————————————#ifndef FBTOOL H#define FBTOOL H

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000

#include fbGrOb.h

#include fbFasped.h

#include fbPoint.h

#include <list>

typedef std::list<fbTool∗> ToolList;typedef ToolList::iterator itToolList;typedef ToolList::const iterator citToolList;typedef ToolList::reverse iterator ritToolList;typedef ToolList::const reverse iterator critToolList;class fbFasped;

enum fbToolType{

FB TOOL UNKNOWN =-1,FB TOOL ARROW = 0,FB TOOL AUTO SWITCH = 1,FB TOOL BENDER = 2,FB TOOL CURSOR = 3,FB TOOL DRAWING PIN = 4,FB TOOL FRAME MANAGER = 5,FB TOOL GEO OBJ = 6,FB TOOL PAN = 7,FB TOOL PENCIL = 8,FB TOOL POINT MANIPULATOR = 9,FB TOOL SELECTOR =10,FB TOOL SUB SELECTOR =11,

};

//! fbTool: Classe per la gestione dei tool/∗!fbTool classe astratta per la gestione di un tool di disegnointeragisce con il riferimento al frame passatogli nel costruttore∗/class fbTool : public fbGrOb{protected:

//! Flag di selezione per modalita’ senza texturesbool m bIsTexturized;

//! Offset (punto di riferimento per il calcolo del vettore spostamento)fbPoint m Offset;

//! Punto corrente del toolfbPoint m BottomLeft;

//! Riferimento all’applicazionefbFasped∗ m pFasped;

//! Tipo di toolfbToolType m ToolType;

//! Lista di tool che rimangono a videostatic ToolList s lPermanentTool;

//! Riferimenti alle texturesfbUInt m pTextures[2];

//! Variabile per il conteggio del numero di clickstatic fbInt s nClickCounter;

155

Page 164: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

public:

fbTool(fbFasped∗);

virtual ∼fbTool();

//! Ritorna il puntatore all’applicazione correntemente attivainline fbFasped∗ GetFasped();

//! Ritorna il frame attivo nelll finestra correnteinline fbFrame∗ GetFrame();

//! Ritorna la lista delinline ToolList& GetToolList();

//! Deve gestire il messaggio di clear che arriva da fbFaspedvirtual void Clear() =0;

//! Distribuisce il visitorvoid AcceptVisitor(fbVisitor∗ pVisitor);

//! Ritorna lo stato del flag di TexturefbBool GetTextureStatus() const;

//! Setta lo stato del flag di Texturevoid SetTextureStatus(const fbBool );

//! Funzione per la cancellazione del tool e della lista a videostatic void fbDeleteTool();

//! Gestione generica del movimento mousevirtual void HandleMouseMove (const fbUInt nButtonPressed, const fbDouble dPositionX, const fbDouble

dPositionY) ;

//! Gestione generica della pressione di un bottono mousevirtual void HandleMouse (const fbUInt nButtonPressed, const fbDouble dPositionX, const fbDouble

dPositionY) ;

//! Metodo per la sostituzione del tool a run timestatic void fbChangeTool(fbTool∗ newTool);

//! Metodo di accesso al toolstatic fbTool∗ fbGetTool(fbFasped∗ pApplication);

//! Metodo di Disegno dei Toolsstatic void fbDrawTool();

//! Metodo che restituisce il tipo di toolinline fbToolType GetToolType();

//! Metodo per prendere il pto bottom left del toolinline fbPoint& GetBottomLeft();

};

/∗——————————————————-∗\|∗ Espansione funzioni inline per la classe fbTool ∗||∗ BEGIN ∗|\∗——————————————————-∗/inline fbToolType fbTool::GetToolType(){

return m ToolType;}

inline fbFasped∗ fbTool::GetFasped(){

return m pFasped;}

inline fbFrame∗ fbTool::GetFrame(){

return (m pFasped == 0 ? 0 : m pFasped→GetFrame());}

inline ToolList& fbTool::GetToolList(){

return s lPermanentTool;}

inline fbPoint& fbTool::GetBottomLeft(){

return m BottomLeft;}/∗——————————————————-∗\|∗ END ∗||∗ Espansione funzioni inline per la classe fbTool ∗|\∗——————————————————-∗/#endif // !defined( FBTOOL H )//———————————————————// End Of File//———————————————————

156

Page 165: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

A.1.36 fbTriangle//———————————————————//// FILENAME : fbTriangle.h//// CLASS(ES) : fbTriangle//// DESCRIPTION : Classe per disegno di un triangolo//// HISTORY : 08/09/2000//———————————————————#ifndef FB TRIANGLE H#define FB TRIANGLE H

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000

#include fbGrOb.h

#include fbPoint.h

#include fbConfig.h

#include fbException.h

class fbTriangle : public fbGrOb{

/// Vertici del triangolofbPoint m Vertex[3];

public:fbPoint GetBarycentre() const;fbPoint GetVertex(const fbInt);void SetVertex(const fbPoint& p1,const fbPoint& p2,const fbPoint& p3);fbTriangle();fbTriangle(const fbPoint∗p);fbTriangle(const fbPoint& p1,const fbPoint& p2,const fbPoint& p3);fbTriangle(const fbTriangle& Triangles);

virtual ∼fbTriangle();

/// Fissa i vertici del triangolo indicizzando con nVertexNumbervoid SetVertex(const fbInt nVertexNumber,const fbPoint& Vertex);void SetVertex(const fbPoint∗ pVertex);

/// Controlla l’appartenenza di un pto ad un triangolofbBool CheckPointInTriangle(const fbPoint&);

void Draw();private:

fbDouble area(const fbPoint&a,const fbPoint& b,const fbPoint& c);fbBool checkPointInSide(const fbInt& first,const fbInt& second,const fbInt& third,const fbPoint&);

};

//! Calcola un triangolo allargato di radius (per i test)fbTriangle fbTriangleSetEnlarged(const fbPoint &p1, const fbPoint &p2, const fbPoint &p3, const fbDouble&radiusOfPick) throw (fbRangeException);

#endif // !defined( FB TRIANGLE H )//———————————————————// End Of File//———————————————————

A.1.37 fbUtil//———————————————————//// FILENAME:fbUtil.h//// CLASS(ES)://// DESCRIPTION://// DATE : Fri Oct 6 2000// COPYRIGTH: (C) 2000 by Fabrizio Morciano// E MAIL : [email protected]////———————————————————#ifndef FB UTILITY#define FB UTILITY

#include fbPoint.h

#include fbCurve.h

#include fbPolyLine.h

#include <vector>

/∗! LoadTexture : Carica la texture (.rgb) del fine fnfalse->la texture e’ caricata nel vettore vect in posizione t numtrue ->errore

∗/bool LoadTexture(const char ∗fn,unsigned int∗ vect,int t num);

157

Page 166: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

//! Testa il puntatore lo elimina e alloca nuova memoriatemplate <class T> inline T∗ fbMemoryTestClearAndAlloc(T∗ &pPointerToEraseAndAlloc){

if(pPointerToEraseAndAlloc)delete pPointerToEraseAndAlloc;

return (pPointerToEraseAndAlloc = new T);}

//! Testa il puntatore lo elimina e resetta il valoretemplate <class T> inline T∗ fbMemoryTestClearAndReset(T∗ &pPointerToEraseAndReset){

if(pPointerToEraseAndReset)delete pPointerToEraseAndReset;

return (pPointerToEraseAndReset = 0);}

//! Testa il puntatore se valido ne esegue il metodotemplate <class T> inline void fbMemoryTestAndDoMethod(T∗ pPointer,void (T::∗Method)()){

if(pPointer)(pPointer→ ∗Method)();

}

//! Testa il puntatore se valido esegue una funzionetemplate <class T,class Function> inline void fbMemoryTestAndDoFunction(T∗ pPointer,Function Method){

if(pPointer)Method(pPointer);

}

//! Testa il container e pulisce i campi puntatoretemplate <class Container> void fbMemoryTestAndClearContainer( Container& container){

if(container.empty()){

typename Container::iterator tempIt;for(tempIt = container.begin();tempIt != container.end() ;tempIt++)

delete ∗tempIt;}container.clear();

}

//! Mostra il contenuto di un contenitore/∗

In Win32 puo non funzionare per strutturecomplesse in cui e presente una classe conoutput ridefinito (liste di fbPoint ad esempio)

∗/template <class T> void fbContainerPrint(const T& C){#ifdef FB MFC PROJECT

FB TRACE(Container size: %d\n,C.size());#else

std::cout�Container size: �C.size()�std::endl;#endif

typename T::const iterator citC;fbUInt i=0;for(citC = C.begin();citC != C.end(); citC++){

#ifdef FB MFC PROJECTFB TRACE([%d] %f\n,i++,∗citC);

#else

std::cout�’[’�i++�] �∗citC;#endif

}}

/∗!Suddivide un container in due parti uguali

∗/template <class T> void fbContainerSplit(const T& vIn, T& vOut 1, T& vOut 2){

typename T::const iteratorcitC = vIn.begin();

fbIntnMiddle = (fbInt)((fbFloat)vIn.size() ∗ 0.5);

advance (citC, nMiddle);

copy( vIn.begin(), citC , back inserter(vOut 1) );

copy( citC , vIn.end(), back inserter(vOut 2) );}

/∗!Suddivide un container in due parti in funzione dell’indice nIndex

∗/

158

Page 167: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

template <class T> void fbContainerSplit(const T& vIn, const fbInt nIndex, T& vOut 1, T& vOut 2){

typename T::const iteratorcitC = vIn.begin();

advance (citC, nIndex);

copy( vIn.begin(), citC , back inserter(vOut 1) );

copy( citC , vIn.end(), back inserter(vOut 2) );}

/∗! Calcola il polinomio di quinto grado che risolve il problemadi trovare il valore del parametro tx di pCurve piu’ vicino

a PointToCheckBibl.

Graphics Geems Vol I pag 607Solving the nearest-point-on-curve problemAuthor(s) Philip J.Schneider

∗/std::vector<fbPoint> fbConvertToBezierForm(const fbPoint& PointToCheck,fbCurve∗ pCurve);

/∗!Risolve le radici del polinomio di quinto grado generato da fbConvertToBezierFormper la soluzione del problema del pto piu’ vicino ad una cubica

∗/fbInt PolyFifthFindRoots (const std::vector<fbPoint>& w,std::vector<fbDouble>& t, fbInt nDepth);

void fbBSplineComputeControlPoints( const std::vector<fbPoint>& vIn ,\std::vector<fbPoint>& vOut ,\std::vector<fbDouble>& vKnots );

void fbBSplineConvertInCurves(const std::vector<fbPoint>& vBSpline,\const std::vector<fbDouble>& vKnots ,\

std::vector<fbPoint>& vCtrlPntsOfCurves);

fbInt fbSplitPointsForCurvature(const std::vector<fbPoint>& vPnts,\std::vector< std::vector<fbPoint>∗ >& vOut);

/∗Calcola il valore di Alpha da utilizzare nella suddivisione

∗/fbDouble GetAlpha(const std::vector<fbPoint>& vLeft,const std::vector<fbPoint>& vRight);

/∗Filtraggio dei punti troppo vicini

∗/void fbFilterPoints(const std::vector<fbPoint>& vPnts,std::vector<fbPoint>& vPntsFiltered, const fbDoubledThreshold);

#endif

//———————————————————// End Of File//———————————————————

A.1.38 fbVisitAndChangeColor//———————————————————//// FILENAME : fbVisitAndChangeCOLOR.h//// CLASS(ES) : fbVisitAndChangeCOLOR//// DESCRIPTION : classe visitatrice che si preoccupa di cambiare// il colore//// HISTORY : 11/08/2000//———————————————————#ifndef FB VISIT AND CHANGE COLOR H#define FB VISIT AND CHANGE COLOR H

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000

#include fbVisitor.h

#include fbConfig.h

/∗!fbVisitAndChangeColor Classe visistatrice per la gestione del colorein un oggetto.

∗/class fbVisitAndChangeColor:public fbVisitor{

fbFloat m dR; //! Valore di RossofbFloat m dG; //! Valore di VerdefbFloat m dB; //! Valore di BlufbFloat m dA; //! Valore AlphafbInt m nTypes; //! A quale stato appartengono i colori

159

Page 168: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

public:

/∗!Costruttore

∗/fbVisitAndChangeColor(fbFloat r,fbFloat g,fbFloat b,fbFloat a,fbInt nType=fbGrOb::FB COLOR ACTIVE)

:m dR(r),m dG(g),m dB(b),m dA(a),m nTypes(nType)

{};

/∗!Costruttore∗/

fbVisitAndChangeColor(const fbFloat∗ color,fbInt nType=fbGrOb::FB COLOR ACTIVE):m dR(color[0]),m dG(color[1]),m dB(color[2]),m dA(color[3]),m nTypes(nType)

{}

/∗!Permette di cambiare il colore allo stato∗/

void SetColor(const fbFloat∗ color,fbInt nType){

m dR =color[0]; m dG=color[1];m dB= color[2]; m dA=color[3];m nTypes = nType;

}

void ActionInGrOb(fbGrOb∗ pObj){

pObj→SetColor(m dR,m dG,m dB,m dA,m nTypes);}

};

#endif // !defined( FB VISIT AND CHANGE COLOR H )//———————————————————// End Of File//———————————————————

A.1.39 fbVisitAndChangeDesignAspect//———————————————————//// FILENAME : fbVisitAndChangeDesignAspect.h//// CLASS(ES) : fbVisitAndChangeDesignAspect//// DESCRIPTION : classe visitatrice che si preoccupa di cambiare// l’aspetto di visualizzazione degli oggetti// (aggiunge la visualizzazione dei pti di controllo etc)//// HISTORY : 11/08/2000//———————————————————#ifndef FB VISIT AND CHANGE DESIGN ASPECT H#define FB VISIT AND CHANGE DESIGN ASPECT H

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000#include fbVisitor.h

#include fbConfig.h

/∗!fbVisitAndChangeDesignAspect :classe visitatrice che si preoccupa di cambiare

l’aspetto di visualizzazione degli oggetti(aggiunge la visualizzazione dei pti di controllo etc)

∗/class fbVisitAndChangeDesignAspect : public fbVisitor{

fbLong m nType;

public:fbVisitAndChangeDesignAspect(const fbLong nType)

:m nType(nType){}

virtual ∼fbVisitAndChangeDesignAspect(){}

//! Cambia le proprieta’ delle curvevoid ActionInCurve(fbCurve∗ pCurve){

pCurve→SetObjectType(m nType);

160

Page 169: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

}

};

#endif // !defined( FB VISIT AND CHANGE DESIGN ASPECT H )//———————————————————// End Of File//———————————————————

A.1.40 fbVisitAndChangeTolerance//———————————————————//// FILENAME : fbVisitAndChangeTolerance.h//// CLASS(ES) : fbVisitAndChangeTolerance//// DESCRIPTION : classe visitatrice che si preoccupa di cambiare// la tolleranza di visualizzazione degli elementi//// HISTORY : 11/08/2000//———————————————————#ifndef FB VISIT AND CHANGE TOLERANCE H#define FB VISIT AND CHANGE TOLERANCE H

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000#include fbVisitor.h

#include fbConfig.h

#include fbGrOb.h

class fbVisitAndChangeTolerance : public fbVisitor{

fbDouble m dTol;

public:fbVisitAndChangeTolerance(const fbDouble dVal=FB TOLERANCE)

:m dTol(dVal){}

virtual ∼fbVisitAndChangeTolerance(){}

void ActionInGrOb(fbGrOb∗ pObj){

// fissa la tolleranzapObj→SetTolerance(m dTol);// ed indica che l’oggetto deve essere rinizializzatopObj→SetInitGL(false);

}};

#endif // !defined( FB VISIT AND CHANGE TOLERANCE H )//———————————————————// End Of File//———————————————————

A.1.41 fbVisitAndChangeVisibility//———————————————————//// FILENAME : fbVisitAndChangeVisibility.h//// CLASS(ES) : fbVisitAndChangeVisibility//// DESCRIPTION : classe visitatrice che si preoccupa di cambiare// la visibilita’ se fuori schermo//// HISTORY : 11/11/2000//———————————————————#ifndef FB VISIT AND CHANGE VISIBILITY H#define FB VISIT AND CHANGE VISIBILITY H

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000

#include fbVisitor.h

#include fbConfig.h

#include fbRectangle.h

/∗!fbVisitAndChangeVisibility classe visitatrice che si preoccupa di cambiare

la visibilita’ se fuori schermo∗/

class fbVisitAndChangeVisibility : public fbVisitor{

161

Page 170: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

private://! BBox della World WindowfbRectangle m BBox;

public:fbVisitAndChangeVisibility (const fbRectangle& BBox)

:m BBox(BBox){}virtual ∼fbVisitAndChangeVisibility (){}

//! Cambia la visibilita’ della curva se il MinMax e’ completamente fuori dallo schermovoid ActionInCurve(fbCurve∗ pCurve){

if(fbRectangleCheckOverlap(pCurve→GetMinMaxBox(),m BBox))pCurve→SetVisibility(true);

elsepCurve→SetVisibility(false);

}};#endif//#ifdef FB VISIT AND CHANGE VISIBILITY H//———————————————————// End Of File//———————————————————

A.1.42 fbVisitor//———————————————————//// FILENAME : fbVisitor.h//// CLASS(ES) : fbVisitor//// DESCRIPTION : classe di gestione delle azioni da fare nei nodi// della lista//// HISTORY : 11/08/2000//———————————————————#ifndef FB VISITOR H#define FB VISITOR H

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000

class fbGrOb;class fbFrame;class fbCurve;class fbStraightLine;class fbSegment;class fbWindow;class fbBSpline;class fbArc;class fbCircle;class fbTool;class fbPolyLine;

class fbVisitor{public:

fbVisitor();virtual ∼fbVisitor();

/// Metodo per l’azione su un generico oggetto graficovirtual void ActionInGrOb(fbGrOb∗){};

/// Metodo per l’azione su una curvavirtual void ActionInCurve(fbCurve∗){};

/// Metodo per l’azione su un framevirtual void ActionInFrame(fbFrame∗){};

/// Metodo per l’azione su una rettavirtual void ActionInStraightLine(fbStraightLine∗){};

/// Metodo per l’azione su un segmentovirtual void ActionInSegment(fbSegment∗){};

/// Metodo per l’azione su una windowvirtual void ActionInWindow(fbWindow∗){};

/// Metodo per l’azione su una BSplinevirtual void ActionInBSpline(fbBSpline∗){};

/// Metodo per l’azione su un cerchiovirtual void ActionInCircle(fbCircle∗){};

/// Metodo per l’azione su un tool

162

Page 171: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

virtual void ActionInTool(fbTool∗){};

/// Metodo per l’azione su una polylinevirtual void ActionInPolyLine(fbPolyLine∗){};

};

#endif // !defined( FB VISITOR H )//———————————————————// End Of File//———————————————————

A.1.43 fbWindow//———————————————————//// FILENAME : fbWindow.h//// CLASS(ES) : fbWindow//// DESCRIPTION : Classe per la gestione di una finestra//// HISTORY ://———————————————————#ifndef FB WINDOW H#define FB WINDOW H

#if MSC VER > 1000#pragma once

#endif // MSC VER > 1000

#include fbRectangle.h

#include fbGrOb.h

#include fbConfig.h

#include fbPoint.h

/∗! fbWindow : Classe che descrive una finestra, contiene i metodinecessari per le trasformazioni di coordinateda finestra a mondo ed i metodi per la gestionedegli eventi

∗/class fbWindow : public fbGrOb{private:

//! permette di scalare le coordinate a valori opportunifbDouble m dScaleFactor;

//! dimensione del pixel della finestrafbDouble m dPixelSize;

//! Centro (in coordinate mondo) della finestrafbPoint m Center;

//! Valore della lettera del tasto premutofbUInt m nKeyPressed;

//! Valore del modificatore da tastierafbUInt m nKeyModifyer;

public:

fbWindow();virtual ∼fbWindow();

//! Conversione coordinate mondo schermo (rasterizza)fbPoint WorldToScreen(const double dX, const double dY) const;

//! Conversione coordinate schermo mondofbPoint ScreenToWorld(const fbInt x,const fbInt y) const;

//!Metodo che ritorna il centro della finestra in coordinate mondoinline const fbPoint& GetCenterOfWindow() const;

//!Metodo che fissa il centro della finestra in coordinate mondoinline void SetCenterOfWindow(const fbPoint&);

//!Metodo che ritorna la dimensione del pixel della finestrainline fbDouble GetPixelSize() const;

//!Metodo che fissa la dimensione del pixel della finestrainline void SetPixelSize(const fbDouble);

//1 Ritorna la BBox a World della finestra (la tolleranza della bbox e quella di disegno)fbRectangle GetWorldBBox() const;

//!void Draw(){};

//! Fissa il fattore di scala (da ricontrollare)

163

Page 172: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

inline void SetScaleFactor(const fbDouble& dScaleFactor);

virtual void OnResize(const fbInt nW,const fbInt nH) {};virtual void OnLMouseMove (const fbInt,const fbInt){}virtual void OnLMouseDown (const fbInt,const fbInt){}virtual void OnLMouseUp (const fbInt,const fbInt){}virtual void OnRMouseMove (const fbInt,const fbInt){}virtual void OnRMouseDown (const fbInt,const fbInt){}virtual void OnRMouseUp (const fbInt,const fbInt){}virtual void OnMouseMove (const fbInt,const fbInt){}

// Eventi di tastiera// Contiene anche il campo con l’ultima posizione del mousevirtual void OnKeyUp (const fbChar , const fbUInt,const fbInt,const fbInt){}virtual void OnKeyDown (const fbChar , const fbUInt,const fbInt,const fbInt){}virtual void OnSpecialKeyUp (const fbChar , const fbUInt,const fbInt,const fbInt){}virtual void OnSpecialKeyDown (const fbChar , const fbUInt,const fbInt,const fbInt){}

//! Valore dell’ultimo tasto premutoinline fbUInt GetKeyPressed() const;

//! Valore dell’ultimo modificatore premutoinline fbUInt GetKeyModifyer() const;

//! Fissa il valore dell’ultimo tasto premutoinline void SetKeyPressed(const fbUInt nKeyPressed);

//! Fissa il valore dell’ultimo modificatore premutoinline void SetKeyModifyer(const fbUInt nKeyModifyer);

//! Metodo per la manipolazione mediante visitorvoid AcceptVisitor(fbVisitor∗);

};

/∗———————————————————∗\|∗ Espansione inline per la class fbWindow ∗||∗ BEGIN ∗|\∗———————————————————∗/

inline const fbPoint& fbWindow::GetCenterOfWindow() const{

return m Center;}

inline fbUInt fbWindow::GetKeyPressed() const{

return m nKeyPressed;}

inline fbUInt fbWindow::GetKeyModifyer() const{

return m nKeyModifyer;}

inline void fbWindow::SetKeyPressed(const fbUInt nKeyPressed){

m nKeyPressed = nKeyPressed;}

inline void fbWindow::SetKeyModifyer(const fbUInt nKeyModifyer){

m nKeyModifyer = nKeyModifyer;}

inline void fbWindow::SetPixelSize(const fbDouble dVal)

{m dPixelSize=dVal;

}

inline fbDouble fbWindow::GetPixelSize() const{

return m dPixelSize;}

inline void fbWindow::SetCenterOfWindow(const fbPoint &Point){

m Center=Point;OnResize((fbInt)W(),(fbInt)H());

}

inline void fbWindow::SetScaleFactor(const fbDouble &dScaleFactor){

m dScaleFactor = dScaleFactor;}

/∗———————————————————∗\|∗ END ∗||∗ Espansione inline per la class fbWindow ∗|\∗———————————————————∗/

164

Page 173: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

A. APPENDICE A

#endif // !defined( FB WINDOW H )//———————————————————// End Of File//———————————————————

165

Page 174: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

Bibliografia

[1] James Foley Andries van Dam Steven K.Feiner John F.Hughes.

Computer Graphics. Addison Wesley, second edition, 1993.

[2] Erik Bizouarn and Jean-Daniel Fekete. Tictactoon: A paper-

less system for professional 2d animation. Computer Graphics

Proceedings.

[3] Gianluca Natale. Riconoscimento di aree chiuse in immagini

vettoriali. PhD thesis, Universta degli studi l’Aquila, 4 2000.

[4] Macromedia. Flash 4.0, 1999.

[5] Supoj Sutanthavibul. Xfig 3.2.3, 1999.

[6] Adam Finkelstein David H.Salesin. Multiresolution curves.

Computer Graphics Proceedings, 1:261–268, 1994.

[7] Thomas W.Sederberg Eugene GreenWood. A physically based

approach to 2-d shape blending. Computer Graphics, 26:25–34, 1992.

[8] Yu-Kuang Chang and Alyn P.Rockwood. A generalized de Ca-

steljau approach to 3d free-form deformation. Computer Graphics

Proceedings, 1:257–260, 1994.

[9] A.R. Forrest. The twisted cubic curve: A computer-aided geometric

design. Computer Aided Design, 12:165–172, 1980.

166

Page 175: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

BIBLIOGRAFIA BIBLIOGRAFIA

[10] Gerald Farin. Curves an Surface for Computer-Aided Geometric

Design. Academic Press, 1994.

[11] P.Schneider. An algoritm for automatically fitting digitized curves.

Graphic Gems, pages 612–626, 1990.

[12] Koichi Itoh and Yoshio Ohno. A curve fitting algorihm for character

font. Electronic Publishing, 6:195–205, 1993.

[13] http://www.sgi.com/technology/stl/. Visitato il: 29/06/2001.

[14] http://www.opengl.org. Visitato il: 29/06/2001.

[15] Microsoft. http://www.microsoft.com. Visitato il: 29/06/2001.

[16] Trolltech. http://www.trolltech.com/. Visitato il: 29/06/2001.

[17] Margaret A.Ellis Bjarne Stroustrup. The Annotated C++ Reference

Manual. Addison Wesley, 1997.

[18] Barbara Robertson. Digital toons. Computer Graphics World, pages

40–46, 1994.

[19] Xiaogang Jin Youfu Li Qunsheng Pen. General constrained de-

formation base on generalized metaballs. Computer and Graphics,

24:219–231, 2000.

[20] Erich Gamma Richard Helm Ralph Johnson John Vlissides. Design

Patterns. Addison Wesley, first edition, 1995. Elements of Reusable

Object-Oriented Software.

[21] Bjarne Stroustrup. The C++ programming language. Addison

Wesley, third edition, 1997.

[22] Josie Wernecke. The Inventor Mentor. Addison Wesley, 1994. Pro-

gramming Object-Oriented 3D Graphics with Open InventorTM ,

Release 2.

167

Page 176: Tecniche di manipolazione intuitiva di splines bidimensionasixoomer.virgilio.it/fmorcia/fasped/fbTesi.pdf · Tecniche per la manipolazione intuitiva di splines bidimensionali di Fabrizio

BIBLIOGRAFIA BIBLIOGRAFIA

[23] Mark Willey. libstroke. http://www.etla.net/∼willey/projects/libstroke/.

Visitato il: 29/06/2001.

168