2009-09-03 15 views
42

Ho un rettangolo di origine e un rettangolo di destinazione. Devo trovare la scala massima a cui la sorgente può essere ridimensionata mentre si adatta all'interno del rettangolo di destinazione e mantenendo le proporzioni originali.Come si ridimensiona un rettangolo alla dimensione massima possibile all'interno di un altro rettangolo?

Google ha trovato one modo di farlo ma non sono sicuro che funzioni in tutti i casi. Ecco la mia soluzione prodotta in casa:

  • Calcola altezza/larghezza per ciascun rettangolo. Questo dà le pendenze delle diagonali msrc e mdest.
  • Se msrc < mdst, fonte scala larghezza per adattarsi alla destinazione larghezza (e altezza di scala dallo stesso rapporto)
  • Altrimenti, fonte scala altezza per adattarsi alla destinazione altezza (e la scala larghezza dal stesso rapporto)

Alla ricerca di altre possibili soluzioni a questo problema. Non sono nemmeno sicuro che il mio algoritmo funzioni in tutti i casi!

risposta

84
scale = min(dst.width/src.width, dst.height/src.height) 

Questo è il tuo approccio ma scritto in modo più pulito.

+4

Dolce! Una volta che hai la scala, utilizzare questi per ottenere le dimensioni finali: 'width = src.width * scale' e' height = src.height * scale' –

+4

Change min con max se si vuole coprire tutta l'area di destinazione. – Glogo

+6

La stessa soluzione, ma con i nomi più chiari per me: 'scale = min (maxWidth/actualWidth, maxHeight/actualHeight)', 'newWidth = actualWidth * scale',' newHeight = actualHeight * scale'. –

1
  1. Calcolare il più piccolo dei destWidth/srcWidth e destHeight/srcHeight
  2. Scala da quel

modifica è naturalmente lo stesso del vostro metodo, con i pezzi della formula spostati. Il mio parere è che questo è più chiaro semanticamente, ma è solo quello - un'opinione.

10

Un'altra opzione potrebbe essere di scalare a larghezza massima e quindi controllare se l'altezza ridotta è maggiore dell'altezza massima consentita in caso affermativo scala per l'altezza (o viceversa):

scale = (dst.width/src.width); 
if (src.height * scale > dst.height) 
scale = dst.height/src.height; 

Credo questa soluzione è sia più breve, più veloce e più facile da capire.

+0

Penso che tu abbia il rapporto invertito nella terza riga. – tom10

+0

hai assolutamente ragione. ho sistemato. – Guss

1

Se tutte le dimensioni sono diverse da zero, utilizzare il seguente codice (che corrisponde essenzialmente al codice).

scaleFactor = (outerWidth/outerHeight > innerWidth/innerHeight) 
    ? outerHeight/innerHeight 
    : outerWidth/innerWidth 

Questo può anche essere modificato per consentire a qualsiasi dimensione di essere zero se necessario.

+1

Penso che un rettangolo con una dimensione zero sia chiamato "linea". : P – MusiGenesis

+1

Questa soluzione è matematicamente identica alla mia: moltiplica la tua diseguaglianza per (innerHeight * outerHeight/innerWidth) e ottieni la mia disuguaglianza. Il vantaggio del mio codice è che se la disuguaglianza fallisce, allora la soluzione non deve essere ricalcolata. – Guss

+0

L'operatore di ternariy valuterà la condizione solo una volta. E, naturalmente, tutte le soluzioni dovrebbero essere equivalenti matematiche ... o sbagliate ... –

Problemi correlati