Ho una geometria 2D. Voglio prendere dei limiti attorno alla mia geometria, e quindi renderne una versione più piccola da qualche altra parte sull'aereo. Ecco, più o meno il codice che devo fare il ridimensionamento e la traduzione:OpenGL: ridimensiona, quindi traduci? e come?
// source and dest are arbitrary rectangles.
float scaleX = dest.width/source.width;
float scaleY = dest.height/source.height;
float translateX = dest.x - source.x;
float translateY = dest.y - source.y;
glScalef(scaleX, scaleY, 0.0);
glTranslatef(translateX, translateY, 0.0);
// Draw geometry in question with its normal verts.
Questo funziona esattamente come previsto per una data dimensione in cui l'origine dest è 0. Ma se l'origine per, diciamo, x, è diverso da zero, il risultato è ancora ridimensionato correttamente ma sembra (?) è tradotto in qualcosa vicino allo zero su quell'asse comunque-- risulta che non è esattamente lo stesso come se dest.x fosse zero.
Qualcuno può indicare qualcosa di ovvio mi manca?
Grazie!
FINALE AGGIORNAMENTO Per le risposte di Bahbar e Marcus in basso, ho fatto qualche altra sperimentazione e ho risolto questo problema. Il commento di Adam Bowen è stato il consiglio. Mi mancavano due fatti critici:
- Avevo bisogno di essere ridimensionato attorno al centro della geometria a cui tenevo.
- Avevo bisogno di applicare le trasformazioni nell'ordine opposto dell'intuizione (per me).
Il primo è ovvio in retrospettiva. Ma per quest'ultimo, per altri bravi programmatori/matematici cattivi come me: scopre che la mia intuizione era quella di operare in quello che lo Red Book chiama un "Grande sistema di coordinate fisse", in cui c'è un piano assoluto, e la tua geometria si muove su quella aereo usando le trasformazioni. Questo è OK, ma data la natura della matematica dietro l'impilamento di più trasformazioni in una matrice, è l'opposto di come funzionano davvero le cose (vedere le risposte di seguito o Red Book per ulteriori informazioni). Fondamentalmente, le trasformazioni sono "applicate" in "ordine inverso" a come appaiono nel codice. Ecco la soluzione finale:
// source and dest are arbitrary rectangles.
float scaleX = dest.width/source.width;
float scaleY = dest.height/source.height;
Point sourceCenter = centerPointOfRect(source);
Point destCenter = centerPointOfRect(dest);
glTranslatef(destCenter.x, destCenter.y, 0.0);
glScalef(scaleX, scaleY, 0.0);
glTranslatef(sourceCenter.x * -1.0, sourceCenter.y * -1.0, 0.0);
// Draw geometry in question with its normal verts.
In breve, cambia l'ordine in glTranslate (dest); glScale (scala); glTranslate (source); –
Adam: Questo non sembra funzionare come suggerisci, anche se sono incuriosito ... puoi approfondire il motivo per cui l'ordinamento sarebbe andato così, e forse offrire un'idea più esplicita su come questo sembrerebbe relativo al codice esistente ? Forse sto solo interpretando male il tuo pseudocodice. Grazie! –
Nevermind: il "non funziona" era un valore fatfing in questo caso. Dopo aver risolto ciò, siamo in affari. Vedi la domanda aggiornata per ulteriori informazioni. Grazie! –