2009-09-03 8 views
42

Ich habe ein Quellrechteck und ein Zielrechteck. Ich muss die maximale Skalierung finden, auf die die Quelle skaliert werden kann, während sie in das Zielrechteck passt und das ursprüngliche Seitenverhältnis beibehalten.Wie skaliere ich ein Rechteck auf die maximal mögliche Größe innerhalb eines anderen Rechtecks?

Google gefunden one Weg, es zu tun, aber ich bin mir nicht sicher, ob es in allen Fällen funktioniert. Hier ist meine selbstgebraute Lösung:

  • Berechnen Sie Höhe/Breite für jedes Rechteck. Dies ergibt die Steigungen der Diagonalen msrc und mdest.
  • Wenn msrc < mdst, Zunder Quelle Breite das Ziel Breite (und Skalenhöhe im gleichen Verhältnis) zu passen
  • Andernfalls Skala Quelle Höhe das Ziel Höhe (und Skalenbreite durch die passend gleiches Verhältnis)

Auf der Suche nach anderen möglichen Lösungen für dieses Problem. Ich bin mir nicht einmal sicher, ob mein Algorithmus in allen Fällen funktioniert!

Antwort

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

Dies ist Ihr Ansatz, aber sauberer geschrieben.

+4

Süß! Sobald Sie die Waage haben, verwenden Sie diese, um die endgültigen Abmessungen zu erhalten: 'width = src.width * scale' und' height = src.height * scale' –

+4

Ändern Sie min mit max, wenn Sie den gesamten Zielbereich abdecken möchten. – Glogo

+6

Gleiche Lösung, aber mit Namen klarer für mich: 'scale = min (maxWidth/actualWidth, maxHeight/actualHeight)', 'newWidth = actualWidth * scale',' newHeight = actualHeight * scale'. –

1
  1. Arbeit aus dem kleineren von destWidth/srcWidth und destHeight/srcHeight
  2. Skala von diesem

bearbeiten es ist natürlich die gleiche wie Ihre Methode, wobei die Stücke der Formel um bewegt. Meine Meinung ist, dass dies semantisch klarer ist, aber es ist nur das - eine Meinung.

10

könnten andere Möglichkeit, um maximale Breite zu skalieren und dann prüfen, ob die skalierte Höhe dann die maximal zulässige Höhe, die größer ist, und wenn ja Skala von Höhe (oder umgekehrt):

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

ich diese Lösung denken ist kürzer, schneller und leichter zu verstehen.

+0

Ich denke, Sie haben das Verhältnis in Ihrer dritten Zeile umgedreht. – tom10

+0

Sie sind absolut richtig. Ich habe es repariert. – Guss

1

Wenn alle Dimensionen nicht Null sind, würde ich den folgenden Code verwenden (der im Wesentlichen mit Ihrem Code übereinstimmt).

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

Dies kann auch so geändert werden, dass jede Dimension bei Bedarf auf Null gesetzt werden kann.

+1

Ich denke, ein Rechteck mit einer Null-Dimension wird eine "Linie" genannt. : P – MusiGenesis

+1

Diese Lösung ist mathematisch identisch mit meiner: multiplizieren Sie Ihre Ungleichheit mit (innerHeight * outerHeight/innerWidth) und Sie erhalten meine Ungleichheit. Der Vorteil meines Codes ist, dass, wenn die Ungleichung fehlschlägt, die Lösung nicht neu berechnet werden muss. – Guss

+0

Der ternäre Operator wird die Bedingung auch nur einmal auswerten. Und natürlich sollten alle Lösungen mathematisch äquivalent sein ... oder falsch ... –

Verwandte Themen