2011-08-26 11 views
7

Si prega di prendere in considerazione:Selezionare i punti all'interno di un'area circolare in Mathematica

dalist = {{9, 6}, {5, 6}, {6, 0}, {0, 5}, {10, 8}, {1, 2}, {10, 4}, {1, 1}, {7, 7}, 
      {6, 8}, {5, 3}, {6, 10}, {7, 4}, {1, 8}, {10, 0}, {10, 7}, {6, 3}, {4, 0}, 
      {9, 2}, {4, 7}, {1, 6}, {10, 8}, {7, 8}, {0, 10}, {3, 4}, {0, 0}, {8, 5}, 
      {4, 5}, {6,0}, {2, 9}, {2, 4}, {8, 4}, {7, 4}, {3, 6}, {7, 10}, {1, 10}, 
      {1, 4}, {8, 0}, {8, 9}, {5, 4}, {2, 5}, {2, 9}, {3, 1}, {0, 6}, {10, 3}, 
      {9, 6}, {8, 7}, {7, 6}, {7, 3}, {8, 9}}; 

frameCenter = {5, 5}; 

criticalRadius = 2; 

Graphics[{ 
      White, EdgeForm[Thick], Rectangle[{0, 0}, {10, 10}], Black, 
      Point /@ dalist, 
      Circle[frameCenter, 2]}]; 

enter image description here

vorrei creare un test di andare oltre dalist e respingere i punti che si trovano all'interno o su una determinata distanza da frameCenter come illustrato sopra. L'ho fatto in passato con una zona rettangolare ma sono perplesso su come farlo con un'area circolare

+2

Tutte le risposte finora farà. Se hai mai sentito il bisogno di testare se i punti si trovano in poligoni più complessi potresti voler guardare a questa discussione in matematica: http://groups.google.com/group/comp.soft-sys.math.mathematica/browse_thread/thread/7bf0c7c21b8d916a/c1bbce770899082f –

risposta

7

Questo sarà piuttosto efficienti:

In[82]:= 
Pick[dalist,UnitStep[criticalRadius^2-Total[(Transpose[dalist]-frameCenter)^2]],0] 

Out[82]= 
{{6,0},{10,8},{10,4},{1,1},{6,10},{10,0},{10,7},{4,0},{10,8}, 
{0,10},{0,0},{6,0},{7,10},{1,10},{8,0},{0,6},{10,3}} 

alternativa,

In[86]:= Select[dalist, EuclideanDistance[#, frameCenter] > criticalRadius &] 

Out[86]= {{6, 0}, {10, 8}, {10, 4}, {1, 1}, {6, 10}, {10, 0}, {10, 7}, {4, 0}, 
{10, 8}, {0, 10}, {0, 0}, {6, 0}, {7, 10}, {1, 10}, {8, 0}, {0, 6}, {10, 3}} 
1

Facile: basta usare il centro del cerchio. Da quello (usando il teorema di Pitagora) calcola la distanza da quel centro. Confrontalo al raggio. È inferiore o uguale al raggio, quindi è all'interno del cerchio. Altrimenti fuori.

+1

Come una parte - È possibile utilizzare questo metodo per calcolare PI. Vedi il metodo monte carlo per pi (Google è interessato) –

+0

E il tag 'Mathematica' non è' math' –

7

vicina può essere utile per scopi quali trovando ogni membro insieme in qualche raggio di un dato punto. Si usa la forma meno ben documentata del terzo argomento che consente una coppia che denota {numero massimo, distanza massima}. In questo caso, consentiamo a tutti di adattarsi al raggio massimo, quindi il numero massimo è impostato su infinito.

In[9]:= DeleteCases[dalist, 
Alternatives @@ 
    Nearest[dalist, frameCenter, {Infinity, criticalRadius}]] 

Out[9]= {{9, 6}, {6, 0}, {0, 5}, {10, 8}, {1, 2}, {10, 4}, {1, 1}, {7, 
    7}, {6, 8}, {6, 10}, {7, 4}, {1, 8}, {10, 0}, {10, 7}, {6, 3}, {4, 
    0}, {9, 2}, {4, 7}, {1, 6}, {10, 8}, {7, 8}, {0, 10}, {3, 4}, {0, 
    0}, {8, 5}, {6, 0}, {2, 9}, {2, 4}, {8, 4}, {7, 4}, {3, 6}, {7, 
    10}, {1, 10}, {1, 4}, {8, 0}, {8, 9}, {2, 5}, {2, 9}, {3, 1}, {0, 
    6}, {10, 3}, {9, 6}, {8, 7}, {7, 6}, {7, 3}, {8, 9}} 

--- --- modifica

quanto riguarda la complessità di DeleteCases con alternative senza modello, se la dimensione di ingresso è N e l'insieme delle alternative ha m elementi, allora è O (n + m) piuttosto che O (n * m). Questo a partire dalla versione 8 di Mathematica.

Gli esempi che seguono porteranno questa richiesta. Iniziamo con 10^5 elementi e ne eliminiamo circa 18000. Prende .17 secondi. Quindi usiamo 10 volte tanti elementi e ne rimuoviamo più di 10 volte (quindi n ed m entrambi aumentano di un fattore 10 o più). Il tempo totale è 1,6 secondi, o un fattore di circa 10 più grande.

In[90]:= dalist5 = RandomInteger[{-10, 10}, {10^5, 2}]; 
criticalRadius5 = 5; 
Timing[rest5 = 
    DeleteCases[dalist5, 
    Alternatives @@ (closest5 = 
     Nearest[dalist5, {0, 0}, {Infinity, criticalRadius5}])];] 
Length[closest5] 

Out[92]= {0.17, Null} 

Out[93]= 18443 

In[94]:= dalist6 = RandomInteger[{-10, 10}, {10^6, 2}]; 
criticalRadius6 = 6; 
Timing[rest6 = 
    DeleteCases[dalist6, 
    Alternatives @@ (closest6 = 
     Nearest[dalist6, {0, 0}, {Infinity, criticalRadius6}])];] 
Length[closest6] 

Out[96]= {1.61, Null} 

Out[97]= 256465 

- modifica end ---

Daniel Lichtlau

+3

+1 per rivelare questa sintassi più vicina. _less-than-well_ potrebbe significare _non_? –

+1

@Sjoerd Non proprio non. Vedi tutorial/UsingNearest sesta sintassi d'uso. Non sarò sorpreso se questo oscuro frammento di documentazione migra alla pagina di riferimento per Più vicini. –

+0

Devo dire che le soluzioni basate su 'DeleteCases' -' Alternatives' hanno in genere 'm * n' complessità asintotica, dove' m' è la dimensione della lista, e 'n' è un numero di casi in' Alternative '(la fatto che è un po 'nascosto dalla sintassi), e questo caso non fa eccezione. Ciò sarà importante per le liste più grandi. Ciò non toglie nulla all'utilità della funzione 'Nearest'. –