2009-10-25 20 views
7

Sto sviluppando un videogioco indie, e ho operato partendo dal presupposto che, poiché la levetta sul mio controller ha un raggio di movimento circolare, restituisce le coordinate "circolari"; cioè, coordinate cartesiane vincolate a un'area circolare (di raggio 1). Infatti, le coordinate sono "quadrate"; ad esempio, la posizione del pollice in alto a destra registra come x = 1, y = 1. Quando converto le coordinate da cartesiano a polare, la magnitudine può superare 1 - il che ha l'effetto che il giocatore può muoversi più rapidamente in diagonale di quanto possa verticalmente o orizzontalmente.Come posso convertire le coordinate su un quadrato in coordinate su un cerchio?

Quindi, per chiarire, voglio registrare la posizione di una levetta analogica in termini di direzione e magnitudine, dove la magnitudine è compresa tra 0 e 1. La levetta restituisce le coordinate su un piano quadrato, quindi è sufficiente convertire le coordinate da cartesiano a polare non è sufficiente. Penso di aver bisogno di convertire le coordinate nello spazio, ma ciò sta premendo i limiti del mio cervello scimmia.

+0

Si occupa del quadrato "intero" o restituisce coordinate che si trovano all'interno di qualcosa che sembra già un cerchio? Per esempio.assicurati di poter (o non puoi) prendere la sqrt-magnitude. –

+0

Cosa (x, y) ottieni con il bastone verso l'alto? Inoltre, il tuo stick analogico o interruttori? Puoi ottenere valori come (0,5,0,5)? – Nosredna

+0

Sì, le coordinate sono distribuite su un quadrato, inclusi gli angoli. – Metaphile

risposta

15

Vedere Mapping a Square to a Circle. C'è anche una bella visualizzazione per la mappatura. Si ottiene:

xCircle = xSquare * sqrt(1 - 0.5*ySquare^2) 
yCircle = ySquare * sqrt(1 - 0.5*xSquare^2) 
+0

In base alla visualizzazione, penso che questo sia esattamente ciò che voglio. Grazie! – Metaphile

0

Dividere ciascun valore per la grandezza per normalizzare tutti i valori su un vettore unitario, ad es.

magn = sqrt(x * x + y * y); 
newx = magn > 1.0 ? x/magn : x; 
newy = magn > 1.0 ? y/magn : y; 

Tuttavia, questo può avere l'effetto di clipping grandezza invece di normalizzare i valori interni .. Cioè, si otterrà lo stesso valore per un controller spinto "pienamente" in alto a sinistra e un controller quasi premuto completamente nella stessa direzione.

+1

Non voglio assolutamente ritagliare la grandezza. Ho già una zona morta. I due insieme ridurrebbe in modo significativo l'effettivo raggio di movimento del bastone. Penso che Eemeli abbia l'idea giusta. – Metaphile

8

La mappatura non è univoca. Ci sono molte altre soluzioni a questa domanda.

Ad esempio, questa mappatura funziona anche

u = x √ (x² + y² - x²y²)/√ (x² + y²)

v = y √ (x² + y² - x²y²)/√ (x² + y²)

dove (u, v) sono coordinate disco circolare e (x, y) sono coordinate quadrati.

Un'immagine vale più di mille parole, quindi ecco alcune immagini per illustrare la non unicità della mappatura e la sua inversa.

circular Brady bunch


squared Boston Celtics

For a C++ implementation di quest'altro mappatura, vai a
http://squircular.blogspot.com/2015/09/fg-squircle-mapping.html
Vedere http://squircular.blogspot.com per più immagini di risultati della mappatura.

Vedere anche "Analytical Methods for Squaring the Disc" per un documento che illustra le diverse equazioni di mappatura con prove e derivazioni.

+0

Bello. Come hai generato le figure (lingua/biblioteca)? – Praxeolitic

+1

Ho scritto un semplice programma di elaborazione delle immagini in C++ che utilizza diverse equazioni di mappatura per pixel. Vedi il link per il collegamento del codice di esempio. Libpng è utile per leggere e scrivere file PNG –

Problemi correlati