2011-11-26 14 views
6

Hãy cân nhắc những điều sau đây:Operations "nội" và "liên" liệt kê

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

Đối với mỗi 8 đĩa,

tôi muốn để tính toán khoảng cách tối thiểu giữa của nó cạnh và:

-Bìa của mọi đĩa khác (7 giá trị) -Mỗi góc khung {4 values},

Sau đó tôi sẽ nhận được 8 danh sách gồm 11 giá trị.

Sau đây cho phép tôi "pointize" đĩa vành đai:

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

Với điều này tôi có thể tìm ra 2 điểm gần nhất trong 2 đĩa và tính toán de xa, nhưng tôi cảm thấy điều này có thể không đúng cách để làm điều đó.

+0

là gì 'Rectangle @@ frmXY' có nghĩa là để làm gì? – DavidC

+0

Đã chỉnh sửa, Cảm ơn David! Nó chỉ ở đó để vẽ Frame! – 500

Trả lời

10

Hãy thử điều này,

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

Nó hoạt động bằng cách tính toán khoảng cách giữa các trung tâm của đĩa, Norm[#1[[;;2]] - #2[[;;2]]], và sau đó trừ ra khỏi bán kính của họ đối với tất cả các cặp đĩa. Tuy nhiên, đối với một danh sách lớn, điều này có thể không phải là nhanh nhất vì nó tính toán tất cả các giá trị hai lần, nhưng nó rất đơn giản.

Để tăng tốc, trước tiên chúng ta cần phải xác định xem cặp mà chúng tôi muốn tính là bao nhiêu. Một cách đơn giản là để xác định tất cả các cặp độc đáo với

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

trả về

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

Ngoài ra, nó không ghép lên đĩa với chính mình, không giống như Outer. Tôi muốn sử dụng nó như thế này

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

Sửa: Tôi có một không thích bệnh lý cho việc sử dụng các biến như lesDisques trong hơn một nơi vì nó làm cho nó khó khăn hơn để thay đổi sau đó. Vì vậy, đây là một viết lại:

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

Sửa: Phiên bản Subsets có một lỗ hổng rằng phiên bản Outer không, như viết cho bạn không thể nói mà cặp đĩa đang được so sánh. Dưới đây là một phiên bản viết lại,

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

trả về

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

Nó xảy ra với tôi rằng tôi không bao giờ trả lời phần thứ hai của câu hỏi của bạn, tìm ra khoảng cách tối thiểu giữa các đĩa và các góc của khung. Nhiệm vụ này được thực hiện tốt nhất bằng cách sử dụng Outer vì không có bất kỳ phép tính dư thừa nào.Vì vậy, đây là những gì tôi muốn làm

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

mà chỉ là một sửa đổi nhỏ của mã gốc. Lưu ý, trong ma trận được tạo ra bởi Outer, các hàng tương ứng với đầu vào đầu tiên (frmCorner trong trường hợp này) và cột vào đầu vào thứ hai, như sau

{{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

Cảm ơn bạn! Bạn có thể giải thích cho tôi "ps". Đây không phải là lần đầu tiên tôi thấy điều này được sử dụng với "With". – 500

+1

@ 500 Nó có nghĩa là viết tắt của 'điểm'. Tuy nhiên, bạn có thể đặt tên biến của mình bất cứ điều gì bạn muốn. – rcollyer

+0

Ah, cảm ơn bạn! – 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

Toán của bạn không chính xác, cả hai bán kính phải được trừ đi, và bạn chỉ trừ đi sự khác biệt của chúng. – rcollyer

+1

@rcollyer Toán của tôi là chính xác, hình học của tôi thì không. Cảm ơn! –