在两个角点之间生成一个随机位置
Generate a random position between 2 corners points
如果我们有两个 Vector2
的对象,代表一个矩形的两个角,一个区域:
Vector2 corner1 = new Vector2(-5, -5);
Vector2 corner2 = new Vector2(5, 5);
如何在这两个向量之间生成随机位置(它创建的矩形中的任何位置)?
我想做的是,从 x1
和 x2
到 y1
和 y2
的距离相同,然后从中做一个随机值范围。
但是如果第一个向量是 5, 5
而第二个向量是 -5, -5
呢?我将不得不添加一个负距离,对吗?
最有效的方法是什么?
这是一些示例代码,我将解释它的作用。首先你需要找到 x1 和 x2 之间的距离以及 y1 和 y2 之间的距离得到总距离之间的随机值然后减去该距离的一半所以如果我们有总距离 10 我们将得到一个随机数 (0 - 10) 减去 5我们得到 -5 到 5 的范围。
int x1 = 5;
int x2 = -5;
int y1 = 5;
int y2 = -5;
Random rand = new Random();
int distanceX = Math.abs(x1 - x2);
int distanceY = Math.abs(y1 - y2);
int offsetX = (x1 + x2)/2;
int offsetY = (y1 + y2)/2;
int randX = (rand.nextInt(distanceX) - (distanceX/2)) + offsetX;
int randY = (rand.nextInt(distanceY) - (distanceY/2)) + offsetY;
System.out.println(randX + " " + randY);
你只需要使用 Vector 2 所以
distanceX = Math.abs(corner1.x - corner2.x);
等...
您可能需要根据 Vector2 包含的内容将整数更改为浮点数。
float randX = ((rand.nextFloat()*distanceX) - (distanceX/2));
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()
计算一个随机值,returns一个介于0.0(含)和1.0(不含)之间的值,并将随机值乘以delta。这给了我们一个随机值,offsetX
,它介于零和两个值的总差之间。
最后,我们必须将此随机偏移量添加到最小 x 值 x1,以便随机点确实位于矩形内,介于 x1(含)和 x2(不含)之间。
请注意,我在没有进行任何测试的情况下将其直接写入 Stack Overflow,因此这是您编写一些单元测试以确保您使用的任何方法都适用于各种值(负值)的好机会,正数,两者的混合,零坐标等)。
(顺便说一下,我假设 Vector2
class 来自 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
的值是否小于、大于或等于 [=22 的值都适用=].请注意,检查 corner1 == corner2
只是一种提高效率的捷径,如果您知道永远不会(或几乎永远不会)将相等的值传递给此方法,则可以删除它。 (单元测试通过或不通过快捷方式。)
为了完成您的要求,您可以像这样在两个矩形角内创建一个随机点:
float randomX = pickRandomPointBetween(corner1.x, corner2.x);
float randomY = pickRandomPointBetween(corner1.y, corner2.y);
Vector2 randomPoint = new Vector2(randomX, randomY);
但是为了让您的代码保持整洁,这个逻辑可能应该完全放入一个专用的方法中,并给出一个清晰的名称。
如果我们有两个 Vector2
的对象,代表一个矩形的两个角,一个区域:
Vector2 corner1 = new Vector2(-5, -5);
Vector2 corner2 = new Vector2(5, 5);
如何在这两个向量之间生成随机位置(它创建的矩形中的任何位置)?
我想做的是,从 x1
和 x2
到 y1
和 y2
的距离相同,然后从中做一个随机值范围。
但是如果第一个向量是 5, 5
而第二个向量是 -5, -5
呢?我将不得不添加一个负距离,对吗?
最有效的方法是什么?
这是一些示例代码,我将解释它的作用。首先你需要找到 x1 和 x2 之间的距离以及 y1 和 y2 之间的距离得到总距离之间的随机值然后减去该距离的一半所以如果我们有总距离 10 我们将得到一个随机数 (0 - 10) 减去 5我们得到 -5 到 5 的范围。
int x1 = 5;
int x2 = -5;
int y1 = 5;
int y2 = -5;
Random rand = new Random();
int distanceX = Math.abs(x1 - x2);
int distanceY = Math.abs(y1 - y2);
int offsetX = (x1 + x2)/2;
int offsetY = (y1 + y2)/2;
int randX = (rand.nextInt(distanceX) - (distanceX/2)) + offsetX;
int randY = (rand.nextInt(distanceY) - (distanceY/2)) + offsetY;
System.out.println(randX + " " + randY);
你只需要使用 Vector 2 所以
distanceX = Math.abs(corner1.x - corner2.x);
等... 您可能需要根据 Vector2 包含的内容将整数更改为浮点数。
float randX = ((rand.nextFloat()*distanceX) - (distanceX/2));
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()
计算一个随机值,returns一个介于0.0(含)和1.0(不含)之间的值,并将随机值乘以delta。这给了我们一个随机值,offsetX
,它介于零和两个值的总差之间。
最后,我们必须将此随机偏移量添加到最小 x 值 x1,以便随机点确实位于矩形内,介于 x1(含)和 x2(不含)之间。
请注意,我在没有进行任何测试的情况下将其直接写入 Stack Overflow,因此这是您编写一些单元测试以确保您使用的任何方法都适用于各种值(负值)的好机会,正数,两者的混合,零坐标等)。
(顺便说一下,我假设 Vector2
class 来自 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
的值是否小于、大于或等于 [=22 的值都适用=].请注意,检查 corner1 == corner2
只是一种提高效率的捷径,如果您知道永远不会(或几乎永远不会)将相等的值传递给此方法,则可以删除它。 (单元测试通过或不通过快捷方式。)
为了完成您的要求,您可以像这样在两个矩形角内创建一个随机点:
float randomX = pickRandomPointBetween(corner1.x, corner2.x);
float randomY = pickRandomPointBetween(corner1.y, corner2.y);
Vector2 randomPoint = new Vector2(randomX, randomY);
但是为了让您的代码保持整洁,这个逻辑可能应该完全放入一个专用的方法中,并给出一个清晰的名称。