What Sander proposes, which I agree is the efficient way to proceed, can be done in a fairly simple manner without explicit binning. This assumes the stick length is fixed to some common value (as is the case in the running example set). Simply create a NearestFunction
based on the stick centers. This can be done as below.
nf = Nearest[centers]
Then overlaps for stick k need only be checked against all sticks that have a center within length units of the center of stick k. Code would look like this.
candidates[k_] := Rest[nf[centers[[k]], {Infinity,L}]]
It is now quite fast to find, for every stick, a set of candidate overlapping sticks.
Timing[neighbors = Table[candidates[k], {k, n}];]
(* Out[146]= {0.000913, Null} *)
In this example we find there are around 25 candidates for each stick. Much smaller than the full 149 other sticks.
Map[Length, neighbors]
(* Out[150]= {21, 26, 24, 33, 28, 28, 35, 14, 22, 31, 34, 27, 24, 28, \
29, 20, 12, 19, 25, 27, 23, 26, 18, 28, 30, 11, 23, 33, 26, 23, 31, \
26, 31, 33, 14, 33, 20, 22, 23, 20, 34, 31, 28, 5, 26, 20, 24, 29, \
25, 20, 29, 26, 30, 26, 22, 11, 17, 30, 27, 16, 23, 24, 14, 21, 21, \
35, 21, 24, 20, 33, 28, 22, 34, 32, 33, 29, 24, 24, 13, 32, 31, 21, \
26, 12, 27, 24, 31, 8, 20, 15, 11, 23, 33, 29, 28, 15, 29, 32, 22, \
20, 10, 23, 33, 23, 14, 33, 15, 27, 24, 28, 30, 18, 30, 26, 22, 20, \
22, 22, 35, 34, 13, 15, 27, 19, 28, 19, 33, 28, 10, 28, 24, 17, 31, \
23, 36, 19, 17, 19, 16, 19, 11, 28, 23, 27, 32, 14, 24, 23, 19, 28} *)
Possibly this could be further refined to take into account orientations when computing neighbors. I doubt it will be worth the effort unless one goes into significantly larger simulations.