2011-11-26 11 views
6

perche il seguente:operazioni "intra" e "inter" elenca

lesDisques={{14.2065, 10.609, 0.974938}, {19.5653, 6.92721, 0.974938}, 
      {30.4607,17.4802, 0.974938}, {27.4621, 10.0393, 0.974938}, 
      {15.915, 20.4278,0.974938}, {28.6921, 5.2132, 1.53205}, 
      {27.0317, 24.8346,1.53205}, {20.8853, 18.8588, 1.53205}} 

where lesDisques[[#]] is {X,Y,R} 

frmCorner = {{6.5946, 1.5946`}, {6.5946, 28.4054`}, 
       {60.2162`,28.4054`}, {33.4054`, 28.4054`}} 

cog = {23.91871026577044`, 15.010499627383863`} 

scrCenter = {20, 15} 

frmXY={{6.5946, 1.5946}, {33.4054, 28.4054}} 

Graphics[{ 
      White, EdgeForm[Thick], 
      Rectangle @@ frmXY, 
      Red, PointSize[.04], 
      [email protected], 
      Black, Disk @@@ (lesDisques /. {a_, b_, c_} :> {{a, b}, c})}, 
      ImageSize -> 600] 

enter image description here

Per ciascuna delle 8 dischi,

Vorrei calcolare la distanza minima tra la sua bordo e:

bordo -La di ogni altri dischi (7 valori) -Ogni angolo telaio {4} valori,

01.235.

Vorrei quindi ottenere 8 liste di 11 valori.

Di seguito mi permette di "pointize" la dischi perimetro:

pointize[{{x_,y_},r_},size_:12]:=Table[{x+r Cos[i ((2\[Pi])/size)], 
            y+r Sin[i ((2\[Pi])/size)]},{i,0,size}] 

Con questo sono riuscito a trovare i 2 punti più vicini per 2 dischi e di calcolo de distanza, ma mi sento questo potrebbe non essere il modo giusto per farlo.

+0

Qual è 'rettangolo @@ frmXY' intendeva fare? – DavidC

+0

Modificato, grazie David! È solo lì per disegnare la cornice! – 500

risposta

10

Prova questo,

Outer[ Norm[#1[[;;2]] - #2[[;;2]]] - #1[[3]] - #2[[3]]&, #, #, 1]& @ lesDisques 

Funziona calcolando la distanza tra i centri dei dischi, Norm[#1[[;;2]] - #2[[;;2]]], e poi sottraendo la loro radio per tutte le coppie di dischi. Per un elenco di grandi dimensioni, tuttavia, questo potrebbe non essere il più veloce in quanto calcola tutti i valori due volte, ma è semplice.

Per accelerare, per prima cosa dobbiamo determinare quali sono le coppie che vogliamo calcolare. Un modo semplice è quello di determinare tutte le coppie uniche con

Subsets[Range[[email protected]], {2}] 

che restituisce

{{1, 2}, {1, 3}, {1, 4}, {1, 5}, {1, 6}, {1, 7}, {1, 8}, {2, 3}, 
{2, 4}, {2, 5}, {2, 6}, {2, 7}, {2, 8}, {3, 4}, {3, 5}, {3, 6}, 
{3, 7}, {3, 8}, {4, 5}, {4, 6}, {4, 7}, {4, 8}, {5, 6}, {5, 7}, 
{5, 8}, {6, 7}, {6, 8}, {7, 8}} 

Inoltre, non accoppiare i dischi con se stessi, a differenza Outer. Mi piacerebbe usare in questo modo

With[{ps = lesDisques[[ # ]]}, 
    Norm[#1[[;;2]] - #2[[;;2]]] - #1[[3]] - #2[[3]]& @@ ps ]& /@ 
Subsets[Range[[email protected]], {2}] 

Edit: ho un'antipatia patologica per l'utilizzo di variabili come lesDisques in più di un posto, perché si rende più difficile da cambiare in seguito. Quindi, ecco una riscrittura:

With[{ps = #}, 
    Norm[Subtract @@ ps[[#1,;;2]]] - Plus @@ ps[[#1,3]]& /@ 
    Subsets[Range[[email protected]], {2}] 
]& @ lesDisques 

Edit: La versione Subsets ha un difetto che la versione Outer non lo fa, come scritto non si può dire quale coppia di dischi vengono confrontati. Ecco una versione riscritta,

With[{ps = #}, 
    Rule[#1,Norm[Subtract @@ ps[[#1,;;2]]] - Plus @@ ps[[#1,3]]]& /@ 
    Subsets[Range[[email protected]], {2}] 
]& @ lesDisques 

che restituisce

{{1, 2} -> 4.55184, {1, 3} -> 15.697, {1, 4} -> 11.318, 
{1, 5} -> 8.01646, {1, 6} -> 12.9509, {1, 7} -> 16.6464, 
{1, 8} -> 8.10742, {2, 3} -> 13.2184, {2, 4} -> 6.53803, 
{2, 5} -> 12.0355, {2, 6} -> 6.77936, {2, 7} -> 16.8946, 
{2, 8} -> 9.4974, {3, 4} -> 6.0725, {3, 5} -> 12.8915, 
{3, 6} -> 9.88685, {3, 7} -> 5.60752, {3, 8} -> 7.16714, 
{4, 5} -> 13.5826, {4, 6} -> 2.47339, {4, 7} -> 12.2946, 
{4, 8} -> 8.49473, {5, 6} -> 17.361, {5, 7} -> 9.45131, 
{5, 8} -> 2.70508, {6, 7} -> 16.6274, {6, 8} -> 12.6569, 
{7, 8} -> 5.50844} 

Mi viene in mente che non ho mai risposto alla seconda parte della tua domanda, trovare le distanze minime tra i dischi e gli angoli di la cornice. È meglio eseguire questa operazione utilizzando Outer in quanto non ci sono calcoli ridondanti.Quindi, questo è quello che farei

Outer[ Norm[#1 - #2[[;;2]]]- #2[[3]]&, #1, #2, 1]& @@ {frmCorner, lesDisques} 

che è solo una leggera modifica del codice originale. Nota, nella matrice generata da Outer, le righe corrispondono al primo ingresso (frmCorner in questo caso) e le colonne al secondo ingresso, come segue

{{10.8234, 13.0492, 27.6946, 21.5365, 20.0384, 20.8598, 29.4159, 20.8795}, 
{18.381, 24.1159, 25.2729, 26.8237, 11.2934, 30.502, 19.2147, 15.654}, 
{48.3566, 45.0012, 30.7229, 36.577, 44.0388, 37.6042, 31.844, 38.9409}, 
{25.2035, 24.5762, 10.3402, 18.3289, 18.2489, 22.1342, 5.77375, 14.2125}} 
+0

Grazie! Potresti spiegarmi "ps". Non è la prima volta che vedo questo essere usato con "Con". – 500

+1

@ 500 È letteralmente una scorciatoia per 'punti'. Ma puoi nominare le tue variabili come vuoi. – rcollyer

+0

Ah, grazie! – 500

5
dist[{d1_, d2_}] :=EuclideanDistance[d1[[1 ;; 2]], d2[[1 ;; 2]]]-d1[[3]]-d2[[3]]; 
l = Subsets[lesDisques, {2}]; 
(*Nearest disks*) 
nD = l[[Ordering[dist /@ l]]][[1]] 
(*minmum distance*) 
minD = dist[nD] 

Graphics[{White, EdgeForm[Thick], Rectangle @@ frmXY, Red, 
    PointSize[.04], [email protected], Black, 
    Disk @@@ (lesDisques /. {a_, b_, c_} :> {{a, b}, c}), 
    Line[{nD[[1, 1 ;; 2]], nD[[2, 1 ;; 2]]}]}, ImageSize -> 600] 

enter image description here

+1

La tua matematica non è corretta, entrambi i raggi devono essere sottratti e la tua sola sottrazione dalla loro differenza. – rcollyer

+1

@rcollyer La mia matematica era corretta, la mia geometria no. Grazie! –