如果我们有两个 Vector2
对象,它们代表矩形的两个角,即一个区域:
Vector2 corner1 = new Vector2(-5, -5);
Vector2 corner2 = new Vector2(5, 5);
如何在这两个 vector 之间生成随机位置(它创建的矩形中的任何位置)?
我想做的是,距x1
和x2
的距离与y1
和y2
的距离相同code>,并从该范围内随机取一个值。
但是如果第一个 vector 是 5, 5
而第二个 vector 是 -5, -5
呢?我必须添加一个负距离,对吗?
最有效的方法是什么?
最佳答案
x和y的计算使用完全相同的方法,所以我们现在只关注x。
Random rand = new Random();
float x1 = Math.min(corner1.x, corner2.x);
float x2 = Math.max(corner1.x, corner2.x);
float deltaX = x2 - x1;
float offsetX = rand.nextFloat() * deltaX;
float randomX = x1 + offsetX;
这可以有效地对 x 值进行排序,以便较小的值被称为 x1
更大的为x2
,计算它们之间的差值并将其存储在 deltaX
中.
然后使用 java.util.Random.nextFloat()
计算随机值,它返回 0.0(含)和 1.0(不含)之间的值,并将随机值乘以增量。这给了我们一个随机值, offsetX
,它是介于零和两个值之间的总差之间的某个值。
最后,我们必须将此随机偏移添加到最小 x 值 x1,以便随机点确实位于矩形内,位于 x1(包含)和 x2(不包含)之间的某个位置。
请注意,我已将其直接写入 Stack Overflow 中,而没有进行任何测试,因此这是您编写一些单元测试的好机会,以确保您使用的任何方法都适用于各种值(负值、正值) ,两者的混合,零坐标等)。
(顺便说一句,我假设 Vector2
类来自 libgdx API,因为核心 Java 8 API 中没有这样的类。)
更新
即使不使用Math.min
对值进行排序,算术也能工作。和Math.max
(我已经通过单元测试证实了这一点),因此您可以简化该方法:
public static float pickRandomPointBetween(float corner1, float corner2) {
if (corner1 == corner2) {
return corner1;
}
float delta = corner2 - corner1;
float offset = rand.nextFloat() * delta;
return corner1 + offset;
}
同样的方法适用于一对 x 或 y 值,并且无论 corner1
的值是否有效都适用。小于、大于或等于 corner2
的值。请注意,检查 corner1 == corner2
只是一种效率快捷方式,如果您知道永远不会(或几乎永远不会)将相等的值传递给此方法,则可以删除它。 (无论有没有快捷方式,单元测试都会通过。)
为了完成您的要求,您将在两个矩形角内创建一个随机点,如下所示:
float randomX = pickRandomPointBetween(corner1.x, corner2.x);
float randomY = pickRandomPointBetween(corner1.y, corner2.y);
Vector2 randomPoint = new Vector2(randomX, randomY);
但是为了保持代码整洁,这个逻辑可能应该放置在一个自己的专用方法中,并给出一个清晰的名称。
关于java - 在 2 个角点之间生成随机位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46370593/