算法:计算椭圆内的伪随机点
对于我正在制作的简单粒子系统,我需要给定一个具有宽度和高度的椭圆,计算位于该椭圆内的随机点 X, Y。
现在我的数学不是最好的,所以我想在这里问是否有人可以给我指出正确的方向。
也许正确的方法是在宽度范围内选择一个随机浮点,将其作为 X 并从中计算 Y 值?
For a simple particle system I'm making, I need to, given an ellipse with width and height, calculate a random point X, Y which lies in that ellipse.
Now I'm not the best at maths, so I wanted to ask here if anybody could point me in the right direction.
Maybe the right way is to choose a random float in the range of the width, take it for X and from it calculate the Y value?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
在半径为 1 的圆内生成一个随机点。这可以通过在区间
[0, 2*pi)
中取随机角度phi
和区间[0, 1)
内的随机值rho
并计算<前><代码>x = sqrt(rho) * cos(phi)
y = sqrt(rho) * sin(phi)
公式中的平方根确保圆内均匀分布。
将
x
和y
缩放到椭圆的尺寸<前><代码>x = x * 宽度/2.0
y = y * 高度/2.0
Generate a random point inside a circle of radius 1. This can be done by taking a random angle
phi
in the interval[0, 2*pi)
and a random valuerho
in the interval[0, 1)
and computeThe square root in the formula ensures a uniform distribution inside the circle.
Scale
x
andy
to the dimensions of the ellipse使用拒绝采样:在椭圆周围的矩形中选择一个随机点。通过检查 (x-x0)^2/a^2+(y-y0)^2/b^2-1 的符号来测试该点是否在椭圆内部。如果该点不在内部,则重复此操作。 (这假设椭圆与坐标轴对齐。类似的解决方案适用于一般情况,但当然更复杂。)
Use rejection sampling: choose a random point in the rectangle around the ellipse. Test whether the point is inside the ellipse by checking the sign of (x-x0)^2/a^2+(y-y0)^2/b^2-1. Repeat if the point is not inside. (This assumes that the ellipse is aligned with the coordinate axes. A similar solution works in the general case but is more complicated, of course.)
通过仔细考虑极坐标形式的定义,也可以在不使用拒绝采样的情况下生成椭圆内的点。来自 wikipedia 椭圆的极坐标形式由
直观上一般来说,半径越大,我们应该更频繁地采样极角θ。用更数学的方式来说,随机变量 θ 的 PDF 应该是 p(θ) dθ = dA / A,其中 dA 是角度 θ 且宽度为 dθ 的单个线段的面积。使用极角面积方程 dA = 1/2 r2 dθ 且椭圆面积为 π ab,则 PDF 变为
要从此 PDF 中随机采样,请直接方法是逆CDF技术。这需要计算累积密度函数(CDF),然后对该函数求逆。使用 Wolfram Alpha 获得不定积分,然后对其求逆,得到
其中 u 在 0 和 1 之间运行。因此,要采样随机角度 θ,只需生成一个在 0 和 1 之间的均匀随机数 u,并将其代入该方程以获得逆 CDF。
要获得随机半径,可以使用适用于圆的相同技术(参见示例 在圆内生成一个随机点(均匀))。
以下是实现此算法的一些示例 Python 代码:
It is possible to generate points within an ellipse without using rejection sampling too by carefully considering its definition in polar form. From wikipedia the polar form of an ellipse is given by
Intuitively speaking, we should sample polar angle θ more often where the radius is larger. Put more mathematically, our PDF for the random variable θ should be p(θ) dθ = dA / A, where dA is the area of a single segment at angle θ with width dθ. Using the equation for polar angle area dA = 1/2 r2 dθ and the area of an ellipse being π a b, then the PDF becomes
To randomly sample from this PDF, one direct method is the inverse CDF technique. This requires calculating the cumulative density function (CDF) and then inverting this function. Using Wolfram Alpha to get the indefinite integral, then inverting it gives inverse CDF of
where u runs between 0 and 1. So to sample a random angle θ, you just generate a uniform random number u between 0 and 1, and substitute it into this equation for the inverse CDF.
To get the random radius, the same technique that works for a circle can be used (see for example Generate a random point within a circle (uniformly)).
Here is some sample Python code which implements this algorithm:
我知道这是一个老问题,但我认为现有的答案都不够好。
我正在寻找完全相同问题的解决方案,并在 Google 的指导下找到了这里,发现所有现有答案都不是我想要的,所以我完全自己实现了自己的解决方案,使用此处找到的信息: https://en.wikipedia.org/wiki/Ellipse
那么椭圆上的任何点都必须满足该方程,如何在椭圆内制作一个点?
只需用 0 和 1 之间的两个随机数缩放 a 和 b 即可。
我将在这里发布我的代码,我只是想提供帮助。
I know this is an old question, but I think none of the existing answers are good enough.
I was looking for a solution for exactly the same problem and got directed here by Google, found all the existing answers are not what I wanted, so I implemented my own solution entirely by myself, using information found here: https://en.wikipedia.org/wiki/Ellipse
So any point on the ellipse must satisfy that equation, how to make a point inside the ellipse?
Just scale a and b with two random numbers between 0 and 1.
I will post my code here, I just want to help.