2012-05-02 13 views
7

Dada una forma rectangular S, con relación de aspecto sx/sy, y otras dos formas rectangulares A (con relación de aspecto ax/ay) y B (con relación de aspecto bx/by) cómo puede Descubrí cuál de las formas A o B tiene la relación de aspecto más cercana a S? Los tamaños de las formas no son importantes.Cómo determinar qué relaciones de aspecto están más cercanas

¿Es justo lo que (sx/sy)/(ax/ay) y (sx/sy)/(bx/by) está más cerca de 1?

Lo que en realidad estoy tratando de hacer es averiguar qué forma en una diapositiva PPTX encajaría mejor en una imagen que se redimensionará y luego se recortará para adaptarse a esa forma. Creo que otro enfoque sería averiguar qué forma da como resultado la pérdida de los pocos píxeles, aunque en mi código será más fácil si puedo hacerlo comparando relaciones de aspecto.

Al final me fui con el siguiente algoritmo, implementado de la siguiente manera (gracias a Matt Ball para su retroalimentación):

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

Respuesta

4

se trata sólo de cualquiera de (SX/sy)/(ax/ay) y (sx/sy)/(bx/by) es lo más cercano a 1?

Eso suena razonable. También puede simplemente minimizar la diferencia:

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 

actualización: el algoritmo en esta respuesta no funciona bien, como se explica en los comentarios a continuación. El OP actualizó su pregunta para incluir el algoritmo que usó, que funciona parece funcionar bien.

+0

Pensé en esto inicialmente, pero creo que solo funciona si asumimos que todas las formas tienen X> Y (o viceversa).Por ejemplo, para imágenes verticales, la relación de aspecto siempre es una fracción; para el paisaje es un número entero. Pero si me equivoco al respecto, agradeceré –

+0

Supongamos que 'target_ratio' es' 1', 'a_ratio' es' 1.1' y 'b_ratio' es' 0.5' (por lo que la respuesta correcta es 'a_ratio') . Entonces tienes '| -0.1 | <| 0.5 | 'o' 0.1 <0.5' entonces el caso 'if' es' true', entonces obtenemos 'a_ratio' del algoritmo de pseudocódigo. Así que esto funciona bien cuando se usa una combinación de paisaje y retrato. –

+1

Acabo de implementar esto en mi código y funciona perfectamente - gracias :-) –

3

En cuanto a la sugerencia anterior, no estoy convencido:

Piense en el siguiente ejemplo: A = 1: 2 B = 2: 1 y

targetRatio = 1: 1

claramente tanto A & B debería ser igualmente adecuado, pero con la comparación de

(1 - GoalAR/CandiateAR) como se sugiere,

aspectRatioCandidateA = 0,5 [1: 2]

aspectRatioCandidateB = 2 [2: 1]

se obtendría

closenessScoreA = 1

closenessScoreB = 0,5

La mejor manera de comparar relaciones de aspecto es pensar en ellos como la definición de un ángulo:

tan (o) = h/w

o = atan (h/w)

continuación, puede simplemente comparar la diferencia de los ángulos ahora.

+0

La respuesta aceptada tal como se indicó no funcionó, como lo demuestra su ejemplo. Si lees el hilo de comentarios para esa respuesta, verás lo que terminé haciendo, que era usar el algoritmo que presenté en la pregunta. De todos modos, gracias por su entrada :-) –

+0

Hola. Un poco confundido ahora. Según entiendo el hilo actual, el código impreso en la pregunta (después de su edición) es lo que está usando, ¿no es así? Me refería a eso con mi contraejemplo. Tomemos el ejemplo de las dos proporciones A = 3: 4 = 0.75 y B = 17: 10 = 1.7. ¿Cuál está más cerca de G = 5: 4 = 1.25? De acuerdo con su código, sería A con un puntaje de 0.66 mientras que B tiene un puntaje de 0.735. Sin embargo, si comparas los ángulos, terminas con B estando "más cerca" de la meta. B tiene un theta de 59.53, A tiene un theta de 36.869 y el objetivo es 51.34. – BmyGuest

+1

Su método puede ser más preciso (parece razonable). Sin embargo, usando 'mi' algoritmo, B también gana: s A's (sx/sy)/(ax/ay) = 1.67; B's (sx/sy)/(ax/ay) = 0.74; Puntaje de A (cercanía a 1) = 1-1.67 = 0.67; Puntaje de B = 1-0.74 = 0.26. A menos que haya cometido un error ;-) –

Cuestiones relacionadas