我必须能够为飞行模拟的航路点设置随机位置。数学挑战很简单:
“在四边形内找到一个随机位置,其中该点位于任何位置的机会均等。”
视觉效果如下:
ABCD 四边形示例如下:
答:[21417.78 37105.97]
乙:[38197.32 24009.74]
C:[1364.19 2455.54]
D:[1227.77 37378.81]
预先感谢您提供的任何帮助。 :-)
编辑
感谢大家的回复。我将在周末查看此问题,然后授予已接受的答案。顺便说一句,我应该提到四边形可以是凸的或凹的。抱歉。
I have to be able to set a random location for a waypoint for a flight sim. The maths challenge is straightforward:
"To find a single random location within a quadrangle, where there's an equal chance of the point being at any location."
Visually like this:
An example ABCD quadrangle is:
A:[21417.78 37105.97]
B:[38197.32 24009.74]
C:[1364.19 2455.54]
D:[1227.77 37378.81]
Thanks in advance for any help you can provide. :-)
EDIT
Thanks all for your replies. I'll be taking a look at this at the weekend and will award the accepted answer then. BTW I should have mentioned that the quadrangle can be CONVEX OR CONCAVE. Sry 'bout dat.
发布评论
评论(9)
您是否可以重复尝试包围四边形的矩形内的任何位置,直到在四边形内得到某些东西?这可能比某些奇特的算法更快,以确保您在四边形中选择某些内容吗?
顺便说一句,在该问题陈述中,我认为“查找”一词的使用令人困惑。您无法真正找到满足条件的随机值;随机发生器只是将其提供给您。您要做的就是在随机发生器上设置参数,以便为您提供符合特定条件的值。
Are you allowed to just repeatedly try anywhere within the rectangle which bounds the quadrangle, until you get something within the quad? Might this even be faster than some fancy algorithm to ensure that you pick something within the quad?
Incidentally, in that problem statement, I think the use of the word "find" is confusing. You can't really find a random value that satisfies a condition; the randomizer just gives it to you. What you're trying to do is set parameters on the randomizer to give you values matching certain criteria.
我会将您的四边形分成多个图形,其中每个图形都是一个正多边形,其一侧(或两侧)平行于其中一个轴。例如,对于上图,我首先找到适合四边形内的最大矩形,该矩形必须平行于 X/Y 轴。然后在剩余的区域中,我将安装三角形,这样的三角形将与矩形的每条边相邻。
那么写一个函数就很简单了:
1)随机得到一个数字。
2)在图中随机找到一个点。
如果#1中选择的图形是一个矩形,那么在其中找到一个随机点应该很容易。棘手的部分是编写一个可以在三角形内找到随机点的例程
I would divide your quadrangle into multiple figures, where each figure is a regular polygon with one side (or both sides) parallel to one of the axes. For eg, for the figure above, I would first find the maximum rectangle that fits inside the quadrangle, the rectangle has to be parallel to the X/Y axes. Then in the remaining area, I would fit triangles, such triangles will be adjacent to each side of the rectangle.
then it is simple to write a function:
1) get a figure at random.
2) find a random point in the figure.
If the figure chosen in #1 is a rectangle, it should be pretty easy to find a random point in it. The tricky part is to write a routine which can find a random point inside the triangle
您可以在边界框中随机创建点,只有在找到位于多边形内部的点后才停止。
所以:
You may randomly create points in a bound-in-box only stopping after you find one that it's inside your polygon.
So:
因此,这取决于您想要如何分配。
如果您希望在二维视图空间中随机采样点,那么雅各布的答案很好。如果您希望这些点有点像透视图(在示例图像中,右上角比左下角密度更大),那么您可以使用双线性插值。
双线性插值非常简单。生成 [0..1] 范围内的两个随机数 s 和 t。那么,如果您的输入点是 p0,p1,p2,p3,则双线性插值是:
主要区别在于您希望分布在 2d 空间中均匀(雅各布方法)还是在参数空间中均匀。
So, it depends on how you want your distribution.
If you want the points randomly sampled in your 2d view space, then Jacob's answer is great. If you want the points to be sort of like a perspective view (in your example image, more density in top right than bottom left), then you can use bilinear interpolation.
Bilinear interpolation is pretty easy. Generate two random numbers s and t in the range [0..1]. Then if your input points are p0,p1,p2,p3 the bilinear interpolation is:
The main difference is whether you want your distribution to be uniform in your 2d space (Jacob's method) or uniform in parameter space.
这是一个有趣的问题,可能也有非常有趣的答案,但如果您只是想让它起作用,让我为您提供一些简单的东西。
算法如下:
编辑
根据 Bart K. 的建议,我更新了第一步以提及边界框。
This is an interesting problem and there's probably as really interesting answer, but in case you just want it to work, let me offer you something simple.
Here's the algorithm:
edit
I updated the first step to mention the bounding box, per Bart K.'s suggestion.
将您的四边形分成两个三角形,然后使用这个优秀的答案来快速找到其中一个随机点。
更新:
从 链接 /3058150/how-to-find-a-random-point-in-a-quadrangle/3058274#3058274">Akusete 在三角形中选取随机点。
(来自 MathWorld - Wolfram 网络资源:wolfram.com )
Split your quadrangle into two triangles and then use this excellent SO answer to quickly find a random point in one of them.
Update:
Borrowing this great link from Akusete on picking a random point in a triangle.
(from MathWorld - A Wolfram Web Resource: wolfram.com)
我相信有两种合适的方法可以解决这个问题。
其他发帖者首先提到的是找到包围矩形的最小边界框,然后在该框中生成点,直到找到位于矩形内部的点。
假设您的四边形面积为 Q,边界框为 A,则您需要生成 N 对点的概率为 1-(Q/A)^N,以指数方式接近 0。
我会推荐上述方法,特别是在二维方面。生成点和测试非常快。
如果您想要终止的保证,那么您可以创建一个算法来仅生成四边形内的点(简单),但您必须确保点的概率分布均匀在四边形之外。
http://mathworld.wolfram.com/TrianglePointPicking.html
给出了很好的解释
I believe there are two suitable ways to solve this problem.
The first mentioned by other posters is to find the smallest bounding box that encloses the rectangle, then generate points in that box until you find a point which lies inside the rectangle.
Assuming your quadrangle area is Q and the bounding box is A, the probability that you would need to generate N pairs of points is 1-(Q/A)^N, which approaches 0 inverse exponentially.
I would reccommend the above approach, espesially in two dimensions. It is very fast to generate the points and test.
If you wanted a gaurentee of termination, then you can create an algorithm to only generate points within the quadrangle (easy) but you must ensure the probablity distribution of the points are even thoughout the quadrangle.
http://mathworld.wolfram.com/TrianglePointPicking.html
Gives a very good explination
“蛮力”方法只是循环遍历,直到获得有效的坐标。在伪代码中:
您可以使用从网络中提取的股票函数作为“isin”。我意识到这不是世界上执行速度最快的东西,但我认为它会起作用。
The "brute force" approach is simply to loop through until you have a valid coordinate. In pseudocode:
You can use a stock function pulled from the net for "isin". I realize that this isn't the fastest-executing thing in the world, but I think it'll work.
所以,这次我们要解决的是如何确定一个点是否在四边形内:
四个边可以用
y = mx + b
形式的线表示。检查该点是在四条线的上方还是下方,综合起来就可以判断它是在里面还是在外面。So, this time tackling how to figure out if a point is within the quad:
The four edges can be expressed as lines in
y = mx + b
form. Check if the point is above or below each of the four lines, and taken together you can figure out if it's inside or outside.