Search code examples
c++mathrandom

c++ random point in circle - where did I go wrong?


class Solution {
private:
double c_radius;
double xcenter;
double ycenter;

public:
    Solution(double radius, double x_center, double y_center) {
    c_radius = radius;
    xcenter = x_center;
    ycenter = y_center;  
}

vector<double> randPoint() {
    double randomradius= (sqrt((double)rand()) / RAND_MAX) * c_radius;
    double randomangle= ((double)rand() / RAND_MAX) * 360.0;
    double yp= sin(randomangle)*randomradius;
    double xp= cos(randomangle)*randomradius;
    std::vector<double> point= {xp+xcenter, yp+ycenter};
    return point; 
}
};

Hi everyone, I was doing a Leet Code question about finding a random point within a circle. It all goes well until following test: Inputs: [[0.01,-73839.1,-3289891.3]

It is essentially generating a random point within a circle however my result seems to be rounded off and I am not sure why.

My Output after generating point:

[null,[-73839.10**000**,-3289891.30**000**],[-73839.10**000**,-3289891.30000],[-73839.10000,-3289891.30000],[-73839.10000,-3289891.30000],[-73839.10000,-3289891.30000]...

Expected Output

[null,[-73839.10**006**,-3289891.30**228**],[-73839.10**541**,-3289891.30660],[-73839.10634,-3289891.30124],[-73839.10256,-3289891.30684],[-73839.09825,-3289891.29962]...

Now my question is where is the error? Is there a fault in my math? The results are close but not close enough. I cannot seem to pinpoint where this error occurs. Any help is greatly appreciated.


Solution

  • With your current approach you will not get uniform distribution (even when radians are fixed). Points will be focused in a center.

    Task description says points distribution suppose to be uniform, but I have doubts if proper statistical test for it is written.

    Instead making this complicated, just randomly pick coordinates in square containing a circle and keep generating this point until it fits inside a circle.

    class Solution {
        std::mt19937 gen;
        std::uniform_real_distribution<> dis;
        double xc;
        double yc;
        double r2;
    
    public:
        Solution(double radius, double x_center, double y_center) 
            : dis{-radius, radius}
            , xc{x_center}
            , yc{y_center}
            , r2{radius * radius}
        {
        }
        
        std::vector<double> randPoint() {
            double dx, dy;
            do {
                dx = dis(gen);
                dy = dis(gen);
            } while (dx*dx + dy*dy > r2);
            return {xc + dx, yc + dy};
        }
    };