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