Argomento: calcolo dell'orientamento di una terna di punti nel piano e sue applicazioni.
Consideriamo tre problemi geometrici:
Algoritmi per problemi 2 e 3 usano 1 come operazione ausiliaria.
Nota: i programmi che scrivete devono occuparsi solo del calcolo del risultato. Separatamente sono dati programmi grafici appositi per visualizzare la configurazione in input e controllare a vista se il risultato e' giusto.
Quest'esercitazione guidata consta di tre parti di cui la (1) e' necessaria per le altre due, mentre (2) e (3) sono indipendenti tra loro e se ne puo' fare una a scelta.
Scrivere una funzione C che abbia la forma:
int ThreePointTurn(float x1, float y1, float x2, float y2, float x3, float y3)e restituisca:
A lezione avete visto che questo equivale al calcolo del segno del determinante:
| yB-yA yC-yA | | xB-xA xC-xA |
Complessita' temporale: O(1), come visto a lezione.
Aggiungete la vostra funzione al programma test1.c (esiste gia' l'intestazione con il corpo della funzione vuoto).
Il programma test1:
Si compila con: make PROG=test1
(qui il makefile).
Si esegue con ./test1 xA yA xB yB xC yC dove gli
argomenti in linea di comando sono le coordinate dei tre punti.
Esempio: ./test1 4 4 -1 3 2 5
Fate delle prove con tutte le configurazioni possibili:
terne allineate, punti coincidenti, punto C interno al segmento AB...
Assicuratevi che questo funzioni prima di passare
agli altri esercizi!
Siano P1, P2, P3, ..., P(n) i vertici di un poligono
convesso, ordinati in senso antiorario.
Sia Q un altro punto.
La posizione di Q rispetto al poligono puo' essere:
Complessita' temporale: O(n) dove n e' il numero di vertici del poligono. Nel caso peggione (punto interno o sul contorno), si fanno esattamente n chiamate alla funzione che controlla l'orientamento di una terna di punti.
Scrivere una funzione C che abbia la forma:
int PointInPolygon(int n, float xp[], float yp[], float xq, float yq)dove n e' il numero di vertici del poligono, gli array xp e yp sono lunghi n e contengono rispettivamente le ascisse e le ordinate dei vertici del poligono e Q=(xq,yq) e' il punto da localizzare.
Aggiungete la vostra funzione al programma test2.c (esiste gia' l'intestazione con il corpo della funzione vuoto).
Il programma test2:
Si compila con make PROG=test2
(stesso makefile di prima).
Si esegue con ./test2 NOMEFILE X Y
dove NOMEFILE e' il nome del file contenente il poligono
e X, Y sono le coordinate del punto.
Esempio: ./test2 poli10.txt 12 2
Per esempio usando come file poligono
poli10.txt,
i punti (0,0) (2,2) (3,1) sono interni, (-2,-3) (6,6) sono esterni,
(-2,3) (3,4.5) (4.5 2.5) giacciono su un lato,
e naturalmente qualsiasi punto scritto nel file stesso e' un vertice!
Il file contenente il poligono elenca i vertici
ciascuno come coppia di coordinate floating point.
Il poligono deve essere convesso e i vertici devono essere
elencati in senso antiorario.
Se mancano queste condizioni non e' richiesto che il programma
funzioni.
Avete visto a lezione che il controllo se due segmenti AB e CD si intersechino richiede di esaminare l'orientamento delle quattro terne di punti formate dai due estremi di un segmento con un estremo dell'altro segmento.
Complessita' temporale: costante perche' si tratta di calcolare il segno di quattro svolte.
Scrivere una funzione C che abbia la forma:
int SegmentIntersect(float xa1, float ya1, float xa2, float ya2, float xb1, float yb1, float xb2, float yb2)e restituisca:
Nota: assumiamo che i due segmenti non giacciano sulla stessa retta di supporto.
Aggiungete la vostra funzione al programma test3.c (esiste gia' l'intestazione con il corpo della funzione vuoto).
Il programma test3:
Si compila con make PROG=test3
(stesso makefile di prima).
Si lancia digitando ./test3 xa1 ya1 xa2 ya2 xb1 yb1 xb2 yb2
dove le otto coordinate
definiscono due segmenti (xa1,ya1)-(xa2,ya2) e (xb1,yb1)-(xb2,yb2).
Esempi:
./test3 -3 2 -1 4 -3 6 0 -1 si intersecano
./test3 -4 -1 -3 -2 3 -2 5 1 non si intersecano
./test3 -3 2 -4 1 -4 1 0 -3 segmenti con un vertice comune
./test3 -3 2 -1 4 -2 3 0 0
un vertice di un segmento e' interno all'altro segmento (giunzione a T)
Questa parte non e' richiesta, ma puo' essere un buon esercizio pensarci sopra.
Se i due segmenti hanno la stessa retta di supporto, quali sono i casi possibili e come si discriminano in base alle svolte?