如何在四边形中找到随机点?

发布于 2024-09-06 14:43:30 字数 474 浏览 9 评论 0 原文

我必须能够为飞行模拟的航路点设置随机位置。数学挑战很简单:

“在四边形内找到一个随机位置,其中该点位于任何位置的机会均等。”

视觉效果如下:

 alt text

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:

alt text

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

知足的幸福 2024-09-13 14:43:31

您是否可以重复尝试包围四边形的矩形内的任何位置,直到在四边形内得到某些东西?这可能比某些奇特的算法更快,以确保您在四边形中选择某些内容吗?

顺便说一句,在该问题陈述中,我认为“查找”一词的使用令人困惑。您无法真正找到满足条件的随机值;随机发生器只是将其提供给您。您要做的就是在随机发生器上设置参数,以便为您提供符合特定条件的值。

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.

宫墨修音 2024-09-13 14:43:31

我会将您的四边形分成多个图形,其中每个图形都是一个正多边形,其一侧(或两侧)平行于其中一个轴。例如,对于上图,我首先找到适合四边形内的最大矩形,该矩形必须平行于 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

手长情犹 2024-09-13 14:43:31

您可以在边界框中随机创建点,只有在找到位于多边形内部的点后才停止。

所以:

  1. 找到包含多边形所有点的框。
  2. 在先前找到的框的边界内创建一个随机点。使用随机函数生成 x 和 y 值。
  3. 检查该点是否在多边形内部(参见此处此处
  4. 如果该点位于多边形内部停止,你就完成了,如果没有,请转到步骤 2

You may randomly create points in a bound-in-box only stopping after you find one that it's inside your polygon.

So:

  1. Find the box that contains all the points of your polygon.
  2. Create a random point inside the bounds of the previously box found. Use random functions to generate x and y values.
  3. Check if that point is inside the polygon (See how here or here)
  4. If that point is inside the polygon stop, you're done, if not go to step 2
一江春梦 2024-09-13 14:43:31

因此,这取决于您想要如何分配。

如果您希望在二维视图空间中随机采样点,那么雅各布的答案很好。如果您希望这些点有点像透视图(在示例图像中,右上角比左下角密度更大),那么您可以使用双线性插值。

双线性插值非常简单。生成 [0..1] 范围内的两个随机数 s 和 t。那么,如果您的输入点是 p0,p1,p2,p3,则双线性插值是:

bilerp(s,t) = t*(s*p3+(1-s)*p2) + (1-t)*(s*p1+(1-s)*p0)

主要区别在于您希望分布在 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:

bilerp(s,t) = t*(s*p3+(1-s)*p2) + (1-t)*(s*p1+(1-s)*p0)

The main difference is whether you want your distribution to be uniform in your 2d space (Jacob's method) or uniform in parameter space.

薄荷→糖丶微凉 2024-09-13 14:43:31

这是一个有趣的问题,可能也有非常有趣的答案,但如果您只是想让它起作用,让我为您提供一些简单的东西。

算法如下:

  1. 在包围四边形的矩形内选择一个随机点。
  2. 如果它不在四边形(或任何形状)内,请重复。
  3. 利润!

编辑

根据 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:

  1. Pick a random point that is within the rectangle that bounds the quadrangle.
  2. If it is not within the quadrangle (or whatever shape), repeat.
  3. Profit!

edit

I updated the first step to mention the bounding box, per Bart K.'s suggestion.

淡忘如思 2024-09-13 14:43:30

将您的四边形分成两个三角形,然后使用这个优秀的答案来快速找到其中一个随机点。

更新:

链接 /3058150/how-to-find-a-random-point-in-a-quadrangle/3058274#3058274">Akusete 在三角形中选取随机点。

主图
(来自 MathWorld - Wolfram 网络资源:wolfram.com

给定一个三角形,其一个顶点位于
原点和其他位置 v1
v2,选择
x
(来自 MathWorld - Wolfram 网络资源:wolfram.com )
其中A1
A2 是统一的
在区间 [0,1] 中变化,给出
点均匀分布在
四边形(左图)。这
不在三角形内部的点
然后可以被丢弃,或者
转化为对应的
三角形内的点(右
图)。

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.

main figure
(from MathWorld - A Wolfram Web Resource: wolfram.com)

Given a triangle with one vertex at
the origin and the others at positions v1
and v2, pick
x
(from MathWorld - A Wolfram Web Resource: wolfram.com)
where A1
and A2 are uniform
variates in the interval [0,1] , which gives
points uniformly distributed in a
quadrilateral (left figure). The
points not in the triangle interior
can then either be discarded, or
transformed into the corresponding
point inside the triangle (right
figure).

執念 2024-09-13 14:43:30

我相信有两种合适的方法可以解决这个问题。

其他发帖者首先提到的是找到包围矩形的最小边界框,然后在该框中生成点,直到找到位于矩形内部的点。

  Find Bounding box (x,y,width, height)
  Pick Random Point x1,y1 with ranges [x to x+width] and [y to y+height]
  while (x1 or y1 is no inside the quadrangle){
       Select new x1,y1
  }

假设您的四边形面积为 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.

  Find Bounding box (x,y,width, height)
  Pick Random Point x1,y1 with ranges [x to x+width] and [y to y+height]
  while (x1 or y1 is no inside the quadrangle){
       Select new x1,y1
  }

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

倾`听者〃 2024-09-13 14:43:30

“蛮力”方法只是循环遍历,直到获得有效的坐标。在伪代码中:

left   = min(pa.x, pb.x, pc.x, pd.x)
right  = max(pa.x, pb.x, pc.x, pd.x)
bottom = min(pa.y, pb.y, pc.y, pd.y)
top    = max(pa.y, pb.y, pc.y, pd.y)
do {
    x = left   + fmod(rand, right-left)
    y = bottom + fmod(rand, top-bottom)
} while (!isin(x, y, pa, pb, pc, pd));

您可以使用从网络中提取的股票函数作为“isin”。我意识到这不是世界上执行速度最快的东西,但我认为它会起作用。

The "brute force" approach is simply to loop through until you have a valid coordinate. In pseudocode:

left   = min(pa.x, pb.x, pc.x, pd.x)
right  = max(pa.x, pb.x, pc.x, pd.x)
bottom = min(pa.y, pb.y, pc.y, pd.y)
top    = max(pa.y, pb.y, pc.y, pd.y)
do {
    x = left   + fmod(rand, right-left)
    y = bottom + fmod(rand, top-bottom)
} while (!isin(x, y, pa, pb, pc, pd));

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.

苍风燃霜 2024-09-13 14:43:30

所以,这次我们要解决的是如何确定一个点是否在四边形内:

四个边可以用 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文