# Sampling line segments within a box

I'm at a bit of a loss for where to start with a sampling problem I'm having so any and all direction would be helpful. I essentially want to sample line segments of identical length within a bounding square. Imagine dropping a needle down a square cylinder and seeing how it lands (over and over).

If the sides of the square are smaller than the length of the segments, you could imagine the distribution is X-shaped. I want to understand how this changes as the square grows. How does convolution apply here if at all?

Edit: random/uniform in the sense that any valid segment position is equally likely to occur. Valid meaning both endpoints are within the boundary.

• Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking.
– Community Bot
Commented Sep 4 at 5:04
• Your process of producing "random" segments is underspecified. A model is needed, and frequently even a slight modification of the statement could result in quite different answers. It would need to be precise enough that two quite different answers could not both be considered reasonable interpretations of the question. Commented Sep 4 at 5:42
• To appreciate what @Glen_b is saying, look up the Bertrand Paradox. Then come back and clarify the sense in which you mean "equally likely." The physical analogy is good, but the physics of dropping a needle down a pipe are not likely to yield a distribution that is anywhere close to something people would consider "equally likely" or uniform. The simplest would be the uniform distribution of pairs of endpoints (a 4D distribution), but others are possible and might be better models for whatever phenomenon it is you're studying.
– whuber
Commented Sep 4 at 23:19

While the comments are strictly correct that the answer could depend on details of the mechanism, it's easier to answer for some mechanisms than others.

I'm going to use the following model

• midpoints of segments are sampled uniformly at random from $$[0,1]\times [0,1]$$
• angles are sampled uniformly at random from $$[0,\pi)$$
• the segment is kept if it lies entirely in $$[0,1]\times[0,1]$$ and rejected otherwise

This samples uniformly from the subset of $$[0,1]\times[0,1]\times[0,\pi)$$ that gives segments entirely within the permitted square.

Here are segments of lengths 1.3, 1.2, 1.0, and 0.5

And here are the histograms of angles scaled to multiples of $$\pi/4=90^\circ$$

As you can see, you do start out with crosses for lengths longer than the side length -- the maximum possible length is $$\sqrt{2}\approx 1.4$$, but at 1.3 we're getting only about 1 in 1000 samples accepted. As the length decreases relative to the square dimensions, the peaks of the angle broaden and end up uniformish.

In the small-needle limit, the angle distribution will be uniform (because sampling acceptance is 100% at distance from the edge greater than half the needle length), and the endpoint distribution will be uniform over the square except near the edges.

I don't think there's any convolution going on with this model. You are sampling uniformly from a relatively complicated but well-defined subset of $$[0,1]\times[0,1]\times[0,\pi)$$ and the subset converges to that whole set as the needle length decreases.

I think this is actually the same distribution you'd get if you sampled one endpoint, then sampled the other endpoint from the circle whose radius was the length of the needle, then rejected if it wasn't in the square, but I'm not sure. It is not the same model as sampling one endpoint and then sampling the other endpoint from the points at the correct distance within the square (but I think that would be a bad model)

In any case, I think random centre/random angle is a reasonable model for dropping a needle.

Here's the sampling code

needle<-function(l,N){
h<-l/2
x<-runif(N)
y<-runif(N)
angle<-runif(N,0,pi)
lx<-x-h*cos(angle)
ly<-y-h*sin(angle)
ux<-x+h*cos(angle)
uy<-y+h*sin(angle)
keep<- pmin(lx,ly,ux,ux)>0 & pmax(lx,ly,ux,uy)<1
data.frame(x,y,angle,lx,ly,ux,uy)[keep,]
}

• This helps a ton, thanks for such an in depth response. I was starting down the endpoint-endpoint path you mentioned and it felt biased like you alluded to. So I began think about how to augment the CDF, but that seems pretty brutal. I might return to closed form later if I'm still curious. Commented Sep 5 at 3:25