Hacker Newsnew | past | comments | ask | show | jobs | submit | arexsutton's commentslogin

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.


You might have a bug in the code.

    >>> horizontal = chordCalc([[-1,0],[1,0]])
    >>> distance(horizontal)
    2.0
All good so far, but

    >>> diagonal = chordCalc([[-1,-1],[1,1]])
    >>> distance(diagonal)
    1.4142135623730951
shouldn't this give 2.0 as well?


The 1/4th answer has a typo.

"The probability of being hit is the probability of being inside the area of fire divided by the total area"

No.

The probability of being hit is the probability of being inside the area of fire.

The probability of being inside the area of fire is the area of fire divided by the entire area.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: