I tried to script that together after the same idea occurred to me. What's interesting is the selection plane affects the outcome quite heavily. As the plane of random line selection increases in size, the probability of a random chord having length>sqrt3 seems to approach about 0.13
My math might be wrong; doesn't seem to be a floating point precision issue.
from math import sqrt
from random import random
def randomPoints(width):
return [
[random()*width-width/2, random()*width-width/2],
[random()*width-width/2, random()*width-width/2]
]
def chordCalc(points):
def quadraticEquation(a,b,c):
descriminant=(b**2 - 4*a*c)
if descriminant <= 0:
return None
x1 = (-b+sqrt(descriminant))/(2*a)
x2 = (-b-sqrt(descriminant))/(2*a)
y1 = sqrt(1-x1**2)
y2 = sqrt(1-x2**2)
return [[x1, y1],[x2,y2]]
m = (points[0][1] - points[1][1]) / (points[0][0] - points[1][0])
b = points[0][1] - m*points[0][0]
qa = 1+m**2
qb = 2*b*m
qc = b**2-1
return quadraticEquation(qa, qb, qc)
def distance(points):
return sqrt((points[0][1] - points[1][1])**2
+ (points[0][0] - points[1][0])**2)
chords=0
largeChords=0
sqrt3=sqrt(3)
while True:
if random() > 0.9999:
print float(largeChords)/chords
points = randomPoints(500) #adjust me down to 0.5 and see probability go to ~0.33
intersections=chordCalc(points)
if intersections is None:
continue
chords += 1
if distance(intersections) > sqrt3:
largeChords += 1
I was wrong. My initial approach appears to be the ninja approach like sampo said above. I got 50% -_-
import numpy as np
import random as rnd
import math as m
chords = []
samp = 10000
for c in range(samp):
#random point on infinite plane is described by a single coordinate
dist = rnd.uniform(1., 1000.)
#DO NOT KNOW HOW TO DO INTERNAL SLICES
#ignore all possible lines that do not intesect circle
xsec_half = m.atan(1./dist)
angle = rnd.uniform(-xsec_half, xsec_half)
#make 2 points on the randomly chosen line
x1, y1 = -dist, 0
x2, y2 = dist, 2*dist*m.tan(angle)
#copy and paste some shit from wolfram alpha
dx = x2-x1
dy = y2-y1
dr = (dx**2 + dy**2)**0.5
D = x1*y2 - x2*y1
sqr = (dr**2 - D**2)**0.5
xa = (D*dy + np.sign(dy)*dx*sqr) / (dr**2)
xb = (D*dy - np.sign(dy)*dx*sqr) / (dr**2)
ya = (-D*dx + np.abs(dy)*sqr) / (dr**2)
yb = (-D*dx - np.abs(dy)*sqr) / (dr**2)
chords.append(((xa-xb)**2 + (ya-yb)**2)**0.5)
print len([a for a in chords if a > 3**0.5])/float(samp)
Basically make the unit circle at 0,0. Pick any radius up to infinity (infinite plane). By symmetry, we don't need 2 coordinates, just a distance from the circle.
Choose any angle from that point which will draw a vector that intersects the circle (to not waste CPU). Calculate the length of the intersecting chord.
I was really surprised by the distribution of chord lengths, it peaks at chord lengths of 2.0, which is the maximum chord length, and falls exponentially with smaller chord lengths. I don't know what I expected, but not that.
My math might be wrong; doesn't seem to be a floating point precision issue.