2009-11-20 18 views
17

Otrzymałem przypisanie dla modułu graficznego, którego jedną częścią jest obliczenie minimalnej elipsy ograniczającej zbioru dowolnych kształtów. Elipsa nie musi być wyrównana względem osi.Ograniczająca elipsa

To działa w java (euch) przy użyciu kształtu AWT, więc mogę używać wszystkich narzędzi zapewnia kształty do sprawdzania przechowywania/przecięcia obiektów.

+4

drumroll ... i pytanie brzmi? – ChssPly76

+1

to jest to, co pochodzi z pisania pytań o 3.44 rano! Czy wierzysz, że odrabiam pracę domową o tej porze i nie ma jej nawet jutro? Co uniwersytet zrobił dla mnie !? ;) – Martin

+0

Wow ... robicie fajne rzeczy. Chyba że brakuje mi tego oczywistego, to nie jest banalne ... – mjv

Odpowiedz

33

Poszukujesz Minimum Volume Enclosing Ellipsoid, lub w przypadku 2D, minimalnego obszaru. Ten problem optymalizacji jest wypukły i można go skutecznie rozwiązać. Sprawdź kod MATLAB w łączu, który zawarłem - implementacja jest trywialna i nie wymaga niczego bardziej skomplikowanego niż inwersja macierzowa.

Osoby zainteresowane matematyką powinny przeczytać this document.

Wykreślanie elipsy jest również proste - można je znaleźć pod numerem here, ale do wygenerowania punktów na elipsie potrzebna jest funkcja specyficzna dla MATLAB.

Ale ponieważ algorytm zwraca równanie elipsy w postaci macierzowej,

matrix form http://mathurl.com/yz7flxe.png

można użyć tego kodu, aby zobaczyć, jak można przekształcić równanie do postaci kanonicznej,

canonical http://mathurl.com/y86tlbw.png

przy użyciu Singular Value Decomposition (SVD). A następnie łatwo jest wykreślić elipsę za pomocą canonical form.

Oto wynik kodu MATLAB na zestawie 10 losowych punktów 2D (niebieski). results

Inne metody, takie jak PCA nie gwarantuje, że elipsa otrzymano z rozkładem (eigen/wartość liczby pojedynczej) będzie minimalna elipsy ograniczającej od punktów na zewnątrz tej elipsy jest wskazanie wariancji.

EDIT:

Więc jeśli ktoś przeczytać dokument, istnieją dwa sposoby, aby przejść na ten temat w 2D: oto pseudokod optymalnego algorytmu - algorytm suboptimal jest jasno wyjaśnione w dokumencie:

Optymalny algorytm:

Input: A 2x10 matrix P storing 10 2D points 
     and tolerance = tolerance for error. 
Output: The equation of the ellipse in the matrix form, 
     i.e. a 2x2 matrix A and a 2x1 vector C representing 
     the center of the ellipse. 

// Dimension of the points 
d = 2; 
// Number of points 
N = 10; 

// Add a row of 1s to the 2xN matrix P - so Q is 3xN now. 
Q = [P;ones(1,N)] 

// Initialize 
count = 1; 
err = 1; 
//u is an Nx1 vector where each element is 1/N 
u = (1/N) * ones(N,1)  

// Khachiyan Algorithm 
while err > tolerance 
{ 
    // Matrix multiplication: 
    // diag(u) : if u is a vector, places the elements of u 
    // in the diagonal of an NxN matrix of zeros 
    X = Q*diag(u)*Q'; // Q' - transpose of Q  

    // inv(X) returns the matrix inverse of X 
    // diag(M) when M is a matrix returns the diagonal vector of M 
    M = diag(Q' * inv(X) * Q); // Q' - transpose of Q 

    // Find the value and location of the maximum element in the vector M 
    maximum = max(M); 
    j = find_maximum_value_location(M); 

    // Calculate the step size for the ascent 
    step_size = (maximum - d -1)/((d+1)*(maximum-1)); 

    // Calculate the new_u: 
    // Take the vector u, and multiply all the elements in it by (1-step_size) 
    new_u = (1 - step_size)*u ; 

    // Increment the jth element of new_u by step_size 
    new_u(j) = new_u(j) + step_size; 

    // Store the error by taking finding the square root of the SSD 
    // between new_u and u 
    // The SSD or sum-of-square-differences, takes two vectors 
    // of the same size, creates a new vector by finding the 
    // difference between corresponding elements, squaring 
    // each difference and adding them all together. 

    // So if the vectors were: a = [1 2 3] and b = [5 4 6], then: 
    // SSD = (1-5)^2 + (2-4)^2 + (3-6)^2; 
    // And the norm(a-b) = sqrt(SSD); 
    err = norm(new_u - u); 

    // Increment count and replace u 
    count = count + 1; 
    u = new_u; 
} 

// Put the elements of the vector u into the diagonal of a matrix 
// U with the rest of the elements as 0 
U = diag(u); 

// Compute the A-matrix 
A = (1/d) * inv(P * U * P' - (P * u)*(P*u)'); 

// And the center, 
c = P * u; 
+2

W algebrze liniowej ufamy!Dziękuję Jacobowi za podzielenie się tym. Jakoś oczekiwałem o wiele bardziej skomplikowanego rozwiązania. ale duh! Myślałem, że algorytm nie jest algebrą. +1, chciałbym móc +2, muszę wspierać ludzi, którzy szukają czegoś innego niż "jaka jest różnica między pytaniami == b i a = b"! Dziękuję Ci. – mjv

+1

Lol, wielkie dzięki! To naprawdę wielki przypadek, znalazłem rozwiązanie tego dla moich własnych badań wczoraj! Matematyka za tym jest dość trudna do zrozumienia, ale niesamowitą częścią jest implementacja trywialna. – Jacob

+1

Czy mógłbyś wyjaśnić, że jest to bardziej java, naprawdę nie mam pojęcia, jeśli chodzi o matlab, więc jestem tutaj zagubiony :( – Martin

Powiązane problemy