开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第39天,点击查看活动详情
给定圆的半径和圆心的位置,实现函数 randPoint ,在圆中产生均匀随机点。
实现 Solution 类:
Solution(double radius, double x_center, double y_center)用圆的半径radius和圆心的位置(x_center, y_center)初始化对象randPoint()返回圆内的一个随机点。圆周上的一点被认为在圆内。答案作为数组返回[x, y]。
示例 1:
输入:
["Solution","randPoint","randPoint","randPoint"]
[[1.0, 0.0, 0.0], [], [], []]
输出: [null, [-0.02493, -0.38077], [0.82314, 0.38945], [0.36572, 0.17248]]
解释:
Solution solution = new Solution(1.0, 0.0, 0.0);
solution.randPoint ();//返回[-0.02493,-0.38077]
solution.randPoint ();//返回[0.82314,0.38945]
solution.randPoint ();//返回[0.36572,0.17248]
提示:
0 < radius <= 10^8-10^7 <= x_center, y_center <= 10^7randPoint最多被调用3 * 10^4次
思路
看到题目首先想到的是随机一个半径值r(0 <= r <= radius),随机一个角度deg(0 <= deg < 360),然后根据r和deg求出一个随机点,但仔细分析,这样随机出来的点是不能均匀分布的,越靠近圆心,点分布的概率越大。我们假设有r1、r2和r3,且r1 > r2 > r3,r1 - r2 == r2 - r3,由于r随机生成,r落到[r1,r2)和[r2,r3)之间概率是相等,落到[r1,r2)和[r2,r3)环中的点是一样多的,显然[r1,r2)环面积更大,点分布的更稀疏。
我们可以在一个边长为2*radius的正方形中随机生成点,然后判断点是否可以落到半径为radius的圆中,如果点距正方形中心距离小于等于radius,就返回这个点,否则继续随机点,代码如下。
解题
/**
* @param {number} radius
* @param {number} x_center
* @param {number} y_center
*/
var Solution = function (radius, x_center, y_center) {
this.r = radius;
this.x = x_center;
this.y = y_center;
};
/**
* @return {number[]}
*/
Solution.prototype.randPoint = function () {
const R = this.r * this.r;
while (true) {
const x = Math.random() * 2 * this.r - this.r;
const y = Math.random() * 2 * this.r - this.r;
if (x * x + y * y <= R) {
return [this.x + x, this.y + y];
}
}
};
/**
* Your Solution object will be instantiated and called as such:
* var obj = new Solution(radius, x_center, y_center)
* var param_1 = obj.randPoint()
*/
module.exports = Solution;