Newsgroup: it.comp.programmare.win32
Titolo: Forse [OT] ???

Salve,
non sapevo in quale ng postare quindi parto da qui.
Problema : rotazione di un punto (in generale di un'immagine).
Ho una struttura (un insieme di punti) che rappresentano tutti i punti 
che si trovano nell'area di un cerchio di una certo raggio.
Ho bisogno di ruotare questo insieme di punti (insomma non l'insieme, i 
punti che lo compongono ;) ) e ovviamente un primo tentativo è stato 
quello di ruotare con un algoritmo 'scontato' come quello che partendo 
dalle coordinate (x,y) calcola atan(abs(y/x)) e discute i segni per 
ottenere l'angolo, poi ruota per mezzo di seno e coseno...insomma quello 
  lì.
Il problema, come mi aspettavo, era che gli arrotondamenti ( che in gran 
parte ho tenuto sotto controllo )in alcuni casi mi fanno perdere punti.
Allora ho guardato un pò in giro ed ho beccato lo Shear Algorithm, cioè 
quello che eseguo la traslazione per linee orizzontali, verticali, e di 
nuovo orizzontali senza degradazione dell'immagine, e graficamente è 
accettabile (cioè funziona proprio bene...).
Il punto è che questo non produce alcun informazione di tipo geometrico 
: parte da un'analisi dell'immagine e ne sposta delle parti, pesando i 
colori dell'immagine iniziale per generare colori nella posizione voluta 
dalla rotazione.
Il punto è che non lavora su punti ma su colori, e questo non è quanto 
cercavo.
Qualcuno potrebbe darmi qualche consiglio ???
Ah, lavorare nel discreto..... ;(

 cercavo.
Perchè non usi una semplice matrice 2x2 per ricavare le nuove coordinate
facendo tutti i calcoli in double (o al limite in float) e poi usi un filtro
per ottenere l'immagine finale?
Anzi, possiamo fare di meglio!
Molti punti saranno probabilmente equidistanti (almeno solitamente...).
In questo caso ci basta calcolare i vettori incremento e ruotare quelli.
Se per es. sai che:
P0
P1 = P0 + v1
P2 = P1 + v1
P3 = P0 + v2
P4 = P3 + v1
ecc...
Basta calcolare: (M = matrice rotazione)
P0' = M*P0
v1' = M*v1
v2' = M*v2
E poi ricavare gli altri punti:
P1' = P0' + v1'
P2' = P1' + v1'
P3' = P0' + v2'
P4' = P3' + v1'
Se poi i punti sono veramente tutti equidistanti, avrai appena due
incrementi Vx e Vy.
       Vx    Vx    Vx    Vx
     *--->*--->*--->*--->*
Vy |
     v Vx
     *--->*         ecc...
Vy |
     v
     *
(sperando che sia incolonnato)
Questo serve solo per risparmiare qualche calcolo...
Infine dovrai filtrare l'immagine in modo da convertire valori double in
valori discreti.
Nota che i valori double sono quelli posizionali: i colori sono rimasti
discreti (non li abbiamo minimamente toccati).
Immagina che lo schermo sia una griglia dove ogni quadrato rappresenta un
pixel delimitato da coordinate ben precise.
Immagina che i punti ruotati abbiano un'area e siano di forma quadrata,
circolare, ellittica o altro e abbiano un'area ben precisa.
Im. che il piano dei punti sia sovrapposto al piano dello schermo.
Ogni punto (ruotato) contribuirà a colorare un pixel con un'intensità
proporzionale all'area dell'intersezione tra l'area del pixel e del punto.
Vale il discorso precedente: se i punti sono disposti secondo un determinato
schema, puoi evitare molti calcoli inutili.
Consigli:
1) Mantieni in memoria le posizioni *iniziali*. Se devi ruotare l'immagine
due volte, per es. prima di 30° e poi di 50°, ruota la prima volta i dati
iniziali di 30° e la seconda volta sempre i dati iniziali di 80°. In questo
modo non avrai propagazione di errori.
2) Mantieni internamente i valori double e utilizza i corrispondenti interi
(arrotondati) ogni qual volta tu debba mostrarli o scriverli su file (se è
richiesto che siano interi).
3) Il discorso del *sampling* (intersezione di aree, ecc...) può essere
fatto anche se i punti non sono colorati. Puoi assegnare a ogni punto
l'intensità massima (1.0) (se avessi i colori dovresti usare una tripla (R,
G, B)) e "dosare" quella tenendo conto delle aree d'intersezione.
Intuitivamente, più un punto è centrato rispetto al pixel, più lo illumina
(o meglio, contribuisce a illuminarlo).
Attenzione! Le intensità non devono eccedere quella massima (usa addizioni
con saturazione e magari 0.7 anzichè 1.0).
Spero di esserti stato di qualche aiuto.
Kiuhnm


Ciò che dici è perfetto ma è molto + di quanto mi serve...il problema è 
che io le coordinate double le posso creare senza problemi, è la 
'discretizzazione' dei valori che mi fotte...e siccome il risultato 
della rotazione genera un input per una rete neurale non posso 
permettermi errori di arrotondamento.
Es.:
ecco in ASCII la 'figura' creata dai punti che compongono l'area del 
cerchio.
         x
      xxxxxxx
    xxxxxxxxxxx
   xxxxxxxxxxxxx
   xxxxxxxxxxxxx
  xxxxxxxxxxxxxxx
  xxxxxxxxxxxxxxx
  xxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxx
  xxxxxxxxxxxxxxx
  xxxxxxxxxxxxxxx
  xxxxxxxxxxxxxxx
   xxxxxxxxxxxxx
   xxxxxxxxxxxxx
    xxxxxxxxxxx
      xxxxxxx
         x
Devo eseguire una rotazione che mi dia punti che compongono la stessa 
immagine....mi spiego meglio.
Hai presente il mirino di Unreal Tournament (o di un gioco simile) ?
Ecco, quest'oggetto qui sopra rappresenta un 'occhio' che analizza un 
immagine.
Quest'occhio prende un contenuto da un'immagine e deve ruotarlo 
finquando non riconosce (eventualmente) qualcosa per cui la rete è 
addestrata.
Ora, ogni singolo punto (x,y) posso tranquillamente ruotarlo usando i 
reali, il problema è quando li 'infilo' in interi [es.: il primo pixel 
della linea centrale è il pixel di coordinate (-8,0) inizialmente, 
quando però ruoto questo cerchio avrò alcuni difetti : collisioni 
(alcuni punti adiacenti possono diventare lo stesso punto) altri che 
vengono arrotondati e diventano qualcosa tipo (-8,1) che non appartiene 
al cerchio etc. etc. ) ]
Per dirla tutta, può succedere qualcosa del tipo (ti riporto un solo 
quadrante per comodità):
         x
      xxxx
    xxxxxx
   xxxxxxx
   xx xxxx
  xx xxxx
  xxxxxxxx
xxx xxxx
  xxxx xxx
invece che
         x
      xxxx
    xxxxxx
   xxxxxxx
   xxxxxxx
  xxxxxxxx
  xxxxxxxx
  xxxxxxxx
xxxxxxxxx
ovvero un'immagine assolutamente 'comprensibile' (è tutto frutto 
dell'arrotondamento) ma inutile....
Ti ripeto e ti assicuro che l'algoritmo 'geometricamente' esatto, è la 
cacchio della discretizzazione il problema....

 appartiene al cerchio etc. etc. ) ]
Il problema di base è che perchè un'immagine possa essere ruotata in modo
perfetto, deve essere formata da un numero di pixel infinito.
Perchè possa invece essere ruotata di un angolo alfa prestabilito, deve
essere formata da un numero finito di pixel disposti radialmente.
E' semplicemente impossibile ruotare un immagine senza modificarla.
E' impossibile preservare tutto. Che cosa vuoi preservare per il tuo scopo?
L'intensità dei pixel?
In grafica si vuole solitamente minimizzare la differenza massima
d'intensità. Cioè poco importa se nessun pixel manterrà il proprio colore:
l'importante è che l'effetto visivo sia il medesimo.
Tu cosa vuoi mantenere invariato?
Quello che voglio dire è che se trovi una versione ruotata dell'immagine A
potrai constatare che tale immagine non è perfetta, ma è stata in qualche
modo riadattata. Se tu riuscissi in qualche modo ruotare la tua immagine
perfettamente (cosa impossibile), le due immagini non corrisponderebbero
ugualmente.
Non puoi usare un algoritmo di correlazione, cioè un algoritmo che ti dica
quanto due immagini si assomigliano?
Per sapere quale algo. usare per ruotare l'immagine, bisogna tenere conto di
quale algo. si userà per eseguire il confronto tra le due immagini
(riconoscimento).
Kiuhnm