Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Operations "intra" & "inter" lists

Please Consider the following :

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],
           Point@cog,
           Black, Disk @@@ (lesDisques /. {a_, b_, c_} :> {{a, b}, c})},
           ImageSize -> 600]

enter image description here

For each of the 8 disks,

I would like to compute the minimum distance between its edge and :

-The edge of every other disks (7 values) -Each frame corner {4 values},

I would then obtain 8 lists of 11 values.

The following enables me to "pointize" the disks perimeter :

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

With this I could find the 2 closest points for 2 disks and compute de distance, but I feel this might not be the right way to do it.

like image 580
500 Avatar asked Nov 26 '11 13:11

500


1 Answers

Try this,

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

It works by computing the distance between the centers of the discs, Norm[#1[[;;2]] - #2[[;;2]]], and then subtracting off their radii for all pairs of discs. For a large list, though, this may not be the speediest as it computes all the values twice, but it is straightforward.

For a speed up, first we need to determine what the pairs we want to calculate are. A straightforward way is to determine all unique pairs with

Subsets[Range[Length@lesDisques], {2}]  

which returns

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

Also, it doesn't pair up the discs with themselves, unlike Outer. I'd use it like this

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

Edit: I have a pathological dislike for using variables like lesDisques in more than one place as it makes it more difficult to change later. So, here's a rewrite:

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

Edit: The Subsets version has a flaw that the Outer version does not, as written you can't tell which pair of disks are being compared. Here's a rewritten version,

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

which returns

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

It occurs to me that I never answered the second part of your question, find the minimum distances between the discs and the corners of the frame. This task is best done using Outer as there aren't any redundant calculations. So, this is what I'd do

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

which is only a slight modification of the original code. Note, in the matrix generated by Outer, the rows correspond to the first input (frmCorner in this case) and the columns to the second input, as follows

{{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}}
like image 80
rcollyer Avatar answered Sep 20 '22 02:09

rcollyer