2012-05-02 3 views
7

Étant donné une forme rectangulaire S, avec un rapport d'aspect sx/sy, et deux autres formes rectangulaires A (avec rapport d'aspect ax/ay) et B (avec rapport d'aspect bx/par) comment Je découvre lequel de forme A ou B a le rapport d'aspect le plus proche de S? Les tailles des formes sont sans importance.Comment déterminer quels rapports d'aspect sont les plus proches

Est-ce simplement que (sx/sy)/(ax/ay) et (sx/sy)/(bx/par) sont les plus proches de 1? Ce que j'essaie réellement de faire est de trouver quelle forme sur une diapositive PPTX correspondrait le mieux à une image qui sera redimensionnée puis recadrée pour l'adapter à cette forme. J'imagine qu'une autre approche consisterait à déterminer quelle forme entraîne la perte du plus petit nombre de pixels, bien que dans mon code, ce soit plus facile si je peux le faire en comparant les proportions.

En fin de compte, je suis allé avec l'algorithme ci-dessous, mis en œuvre comme suit (grâce à Matt Ball pour ses commentaires):

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; 
} 

Répondre

4

Est-il juste celui des (sx/sy)/(hache/ay) et (sx/sy)/(bx/par) est le plus proche de 1?

Cela semble raisonnable. Vous pouvez aussi simplement minimiser la différence:

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 

Mise à jour: l'algorithme dans cette réponse ne fonctionne pas tout à fait, comme expliqué dans les commentaires ci-dessous. Le PO a mis à jour sa question pour inclure l'algorithme qu'il a utilisé, ce qui fonctionne semble bien fonctionner.

+0

J'ai d'abord pensé à cela mais je pense que cela ne fonctionne que si nous supposons que toutes les formes ont X> Y (ou vice versa).Par exemple, pour les images portrait, le rapport d'aspect est toujours une fraction; pour le paysage c'est un entier. Faites-moi savoir si je me trompe à ce sujet - merci –

+0

Supposons que 'target_ratio' est' 1', 'a_ratio' est' 1.1', et 'b_ratio' est' 0.5' (donc la bonne réponse est 'a_ratio') . Alors vous avez '| -0.1 | <| 0.5 | 'ou' 0.1 <0.5' donc le cas 'if' est' true', donc nous avons 'a_ratio' de l'algorithme du pseudo-code. Donc, cela fonctionne très bien lorsque vous utilisez un mélange de paysage et de portrait. –

+1

Juste implémenté ceci dans mon code et cela fonctionne parfaitement - merci :-) –

3

regardant la suggestion ci-dessus, je ne suis pas convaincu:

Pensez à l'exemple suivant: A = 1: 2 B = 2: 1 et

targetRatio = 1: 1

Il est clair que les deux A & B devraient également convenir, mais avec la comparaison des

(1 - GoalAR/CandiateAR) comme suggéré,

aspectRatioCandidateA = 0,5 [1: 2]

aspectRatioCandidateB = 2 [2: 1]

vous obtiendrez

closenessScoreA = 1

closenessScoreB = 0,5

La meilleure façon de comparer les proportions est de les considérer comme définissant un angle:

tan (o) = h/p

o = atan (h/w)

Vous pouvez alors comparer simplement la différence des angles maintenant.

+0

La réponse acceptée comme indiqué n'a pas fonctionné, comme votre exemple le démontre. Si vous lisez le fil de commentaires pour cette réponse, vous verrez ce que j'ai fini par faire - qui utilisait l'algorithme que j'ai mis en avant dans la question. Quoi qu'il en soit, merci pour votre contribution :-) –

+0

Salut. Légèrement confus maintenant. Comme je comprends le fil actuel, le code imprimé dans la question (après votre édition) est ce que vous utilisez, n'est-ce pas? Je parlais de cela avec mon contre-exemple. Prenons l'exemple des deux rapports A = 3: 4 = 0,75 et B = 17: 10 = 1,7. Quel est le plus proche de G = 5: 4 = 1.25? Selon votre code, il serait A avec un score de 0,66 tandis que B a un score de 0,735. Cependant, si vous comparez les angles, vous vous retrouvez avec B étant «plus proche» du but. B a un thêta de 59,53, A a un thêta de 36,869 et le but est de 51,34. – BmyGuest

+1

Votre méthode peut être plus précise (cela semble raisonnable). Cependant, en utilisant 'mon' algorithme, B gagne aussi: s A (sx/sy)/(ax/ay) = 1,67; B (sx/sy)/(ax/ay) = 0,74; Score de A (proximité de 1) = 1-1,67 = 0,67; Score de B = 1-0,74 = 0,26. Sauf si j'ai fait une erreur ;-) –

Questions connexes