2012-05-02 21 views
7

Dato una forma rettangolare S, con proporzioni sx/sy, e due altre forme rettangolari A (con rapporto proporzionale ax/aa) e B (con rapporto larghezza/altezza bx/per) come può Scopro quale di forma A o B ha lo aspect ratio più vicino a S? Le dimensioni delle forme non sono importanti.Come determinare quali rapporti sono più vicini

È solo quello di (sx/sy)/(ax/ay) e (sx/sy)/(bx/by) è più vicino a 1?

Quello che sto effettivamente cercando di fare è scoprire quale forma su una diapositiva PPTX si adatta meglio a un'immagine che verrà ridimensionata e quindi ritagliata per adattarla a quella forma. Immagino che un altro approccio sarebbe quello di capire quale forma si traduce con il minor numero di pixel persi, sebbene nel mio codice sarà più facile se riuscirò a farlo confrontando le proporzioni.

Alla fine sono andato con l'algoritmo di seguito, implementato nel modo seguente (grazie a Matt Ball per il suo feedback):

ShapeInPPTXLocation closest; 
double imageAR = a_imageDim.getWidth()/a_imageDim.getHeight(); 
double aspectRatioCandidateA = a_candidateA.getWidth()/a_candidateA.getHeight(); 
double aspectRatioCandidateB = a_candidateB.getWidth()/a_candidateB.getHeight(); 
double closenessScoreA=1-(imageAR/aspectRatioCandidateA); 
double closenessScoreB=1-(imageAR/aspectRatioCandidateB); 

if (Math.abs(closenessScoreA) <= Math.abs(closenessScoreB)) 
{ 
    closest=a_candidateA; 
} 
else 
{ 
    closest=a_candidateB; 
} 

risposta

4

è solo a seconda di quale delle (sx/SY)/(ax/ay) e (sx/sy)/(bx/by) è più vicino a 1?

Sembra ragionevole. Si potrebbe anche solo ridurre al minimo la differenza:

let target_ratio = sx/sy 
let a_ratio = ax/ay 
let b_ration = bx/by 

if |target_ratio - a_ratio| < |target_ratio - b_ratio| 
    a_ratio is closer to target 
else 
    b_ratio is closer to target 

Aggiornamento: l'algoritmo in questa risposta non funziona del tutto, come spiegato nei commenti qui sotto. L'OP ha aggiornato la sua domanda per includere l'algoritmo che ha usato, il che funziona sembra funzionare correttamente.

+0

Inizialmente ci ho pensato, ma penso che funzioni solo se assumiamo che tutte le forme abbiano X> Y (o viceversa).Ad esempio, per le immagini verticali, le proporzioni sono sempre una frazione; per il paesaggio è un numero intero. Fammi sapere se mi sbaglio su questo però - grazie –

+0

Supponiamo che 'target_ratio' sia' 1', 'a_ratio' è' 1.1', e 'b_ratio' è' 0.5' (quindi la risposta corretta è 'a_ratio') . Quindi hai '| -0.1 | <| 0.5 | 'o' 0.1 <0.5' quindi il caso 'if' è' true', quindi otteniamo 'a_ratio' dall'algoritmo pseudocodice. Quindi funziona bene quando si usa un mix di paesaggio e ritratto. –

+1

Ho appena implementato questo nel mio codice e funziona perfettamente - grazie :-) –

3

Guardando il suggerimento di cui sopra, io non sono convinto:

Pensate il seguente esempio: A = 1: 2 B = 2: 1 e

targetRatio = 1: 1

Chiaramente sia A & B dovrebbero essere ugualmente adatti, ma con il confronto delle

(1 - GoalAR/CandiateAR) come suggerito,

aspectRatioCandidateA = 0.5 [1: 2]

aspectRatioCandidateB = 2 [2: 1]

si otterrebbe

closenessScoreA = 1

closenessScoreB = 0.5

Il modo migliore per confrontare le proporzioni è pensare a loro come a definire un angolo:

tan (o) = h/w

o = atan (h/w)

Si può quindi confrontare semplicemente la differenza degli angoli ora.

+0

La risposta accettata come dichiarato non ha funzionato, come dimostra il tuo esempio. Se leggi il thread dei commenti per quella risposta vedrai cosa ho finito per fare - che stava usando l'algoritmo che ho proposto nella domanda. Comunque, grazie per il tuo contributo :-) –

+0

Ciao. Un po 'confuso ora. Come ho capito il thread corrente, il codice stampato nella domanda (dopo la modifica) è quello che stai usando, non è vero? Mi riferivo a questo con il mio contro-esempio. Prendi l'esempio dei due rapporti A = 3: 4 = 0,75 e B = 17: 10 = 1,7. Qual è più vicino a G = 5: 4 = 1,25? Secondo il tuo codice sarebbe A con un punteggio di 0,66 mentre B ha un punteggio di 0,735. Tuttavia, se si confrontano gli angoli, si finisce con B che è "più vicino" all'obiettivo. B ha un theta di 59.53, A ha un theta di 36.869 e l'obiettivo è 51.34. – BmyGuest

+1

Il tuo metodo potrebbe essere più accurato (sembra ragionevole). Tuttavia, usando l'algoritmo "mio", B vince anche: s A's (sx/sy)/(ax/ay) = 1.67; B's (sx/sy)/(ax/ay) = 0,74; Punteggio di A (prossimità a 1) = 1-1,67 = 0,67; Punteggio di B = 1-0.74 = 0.26. A meno che non abbia commesso un errore ;-) –

Problemi correlati