2012-05-02 16 views
7

Otrzymany prostokątny kształt S, o współczynniku kształtu sx/sy i dwa inne prostokątne kształty A (ze współczynnikiem proporcji ax/ay) i B (ze współczynnikiem kształtu bx/o), w jaki sposób Dowiaduję się, który z kształtów A lub B ma najbliższy współczynnik proporcji do S? Rozmiary kształtów są nieistotne.Jak określić, które współczynniki proporcji są najbliższe?

Czy to tylko wartość (sx/sy)/(ax/ay) i (sx/sy)/(bx/by) jest najbliżej 1?

Tym, co faktycznie próbuję zrobić, jest sprawdzenie, który kształt na slajdzie PPTX najlepiej pasuje do obrazu, który zostanie przeskalowany, a następnie przycięty, aby dopasować go do tego kształtu. Myślę, że innym podejściem byłoby ustalenie, który kształt powoduje utratę najmniejszej liczby pikseli, chociaż w moim kodzie będzie łatwiej, jeśli będę mógł to zrobić, porównując współczynniki proporcji.

W końcu poszedłem z poniższym algorytmem, realizowane w następujący sposób (dzięki Matt piłka do jego sprzężenie zwrotne):

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

Odpowiedz

4

to tylko w zależności od (SX/sy)/(ax/ay) i (sx/sy)/(bx/by) jest najbliżej 1?

To brzmi rozsądnie. Można też po prostu zminimalizować różnicę:

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 

Aktualizacja: algorytm w tej odpowiedzi nie do końca pracy, jak wyjaśniono w komentarzach poniżej. OP zaktualizował swoje pytanie, dodając algorytm, którego używał, co działa dobrze.

+0

Początkowo o tym myślałem, ale myślę, że działa to tylko wtedy, gdy założymy, że wszystkie kształty mają X> Y (lub vice wers).Na przykład w przypadku obrazów portretowych proporcje są zawsze ułamkami; dla krajobrazu jest liczbą całkowitą. Daj mi znać, jeśli się mylę - dzięki –

+0

Załóżmy, że 'target_ratio' to' 1', 'a_ratio' to' 1.1', a 'b_ratio' to' 0.5' (więc poprawna odpowiedź to 'a_ratio') . Następnie masz '| -0.1 | <| 0.5 | 'lub' 0.1 <0.5', więc przypadek 'if' jest" prawdziwy ", więc otrzymujemy' a_ratio' z algorytmu pseudokodowania. Tak więc działa to dobrze, gdy używa się mieszanki krajobrazu i portretu. –

+1

Po prostu zaimplementowałem to w moim kodzie i działa idealnie - dzięki :-) –

3

Patrząc na sugestię powyżej, nie jestem przekonany:

Pomyśl na poniższym przykładzie: A = 1: 2 B = 2: 1 i

targetRatio = 1: 1

Oczywiście zarówno a & B powinna być równie odpowiednie, ale przy porównaniu z

(1 - GoalAR/CandiateAR), jak sugeruje,

aspectRatioCandidateA = 0,5 [1: 2]

aspectRatioCandidateB = 2 [2: 1]

ty chcesz dostać

closenessScoreA = 1

closenessScoreB = 0,5

Najlepszym sposobem porównania współczynników proporcji jest określenie ich jako kąt:

tan (O) = h/w

o = atan (H/W)

można po prostu porównywać różnicę kątów się.

+0

Przyjęta odpowiedź, jak stwierdzono, nie działa, jak pokazuje Twój przykład. Jeśli przeczytasz ten wątek komentarza, zobaczysz, co zrobiłem - używając algorytmu podanego w pytaniu. W każdym razie, dzięki za twoje wejście :-) –

+0

Cześć. Nieco zdezorientowany teraz. Jak rozumiem obecny wątek, kod wydrukowany w pytaniu (po twojej edycji) jest tym, czego używasz, prawda? Miałem na myśli to z moim kontrprzykładem. Weźmy przykład dwóch stosunków A = 3: 4 = 0,75 i B = 17: 10 = 1,7. Który jest bliżej G = 5: 4 = 1,25? Według twojego kodu będzie to A z wynikiem 0.66, podczas gdy B ma wynik 0.735. Jeśli jednak porównasz kąty, kończysz na tym, że B jest "bliżej" do celu. B ma teta 59,53, A ma teta 36,869, a bramka jest na 51,34. – BmyGuest

+1

Twoja metoda może być dokładniejsza (wydaje się rozsądna). Jednakże, używając algorytmu "mój", B również wygrywa: s A (sx/sy)/(ax/ay) = 1,67; B (sx/sy)/(ax/ay) = 0,74; Wynik A (bliskość do 1) = 1-1.67 = 0.67; Wynik B = 1-0,74 = 0,26. Chyba że popełniłem błąd ;-) –

Powiązane problemy