Kismet has a function for random point in bounding box, but I’m looking for a random point along a bounding box perimeter.
I have a fixed location for the bounding box origin and have access to the box extent.
Thanks,
Mark
Kismet has a function for random point in bounding box, but I’m looking for a random point along a bounding box perimeter.
I have a fixed location for the bounding box origin and have access to the box extent.
Thanks,
Mark
Why not just pick a random pair of coordiates from the box extent (in world space) and get a random distance between them (clamped with thir own dustance) as the offset?
Oh and uou need a function to check that the verts are on the same plane (not diagonally across from each other)
Hi thanks for the reply. I’m not sure I understand your suggestion. I might not have explained what I’m looking for well enough.
The final result that I’m looking for is the random point on the bounding box perimeter. If i picked two coordinates in the box extent and got their distance, what exactly would that be accomplishing?
I don’t know if this help you and if I understood what you need.
You want a point from the SURFACE of the bounding box instead
a random point of the VOLUME?
What about this:
put a cube in the location of the bounding box and same dimmensions
The cube is just to generate a trace hit.
Then you make a trace by channel from a random place of the outside to the center of the cube…something similar to this:
Oh I think a line trace could work. I should’ve mentioned that I’m using the bounding box as a 2-dimensional square, with the X value of the box extent being zero.
wait…you want a point in the perimeter of a 2D box??
how about this:
basically it takes a random value for X and Y (like in the surface) and then it
‘clamps’ the value to one of the 4 sides
Sorry! I’m still interested in how you accomplished this if you’re willing to share. Eventually I’ll have to implement in 3D, but for now I’m doing 2D.
It’s this:
But something is not entirely correct here, it seems to overfocus on the edges too much. Would like to fix it up but need to fix dinner first ;p
Do experiment with the Vector Bounded to Box node - perhaps it will get you there.
I like the approach. Just wondering why it seems hit points tend so much to the edges of the box
I had had to do something similar in the past but couldn’t get the distribution right. What I ended up doing was tracing from a random point on the sphere surface towards a random point in the volume.
And then finding Closest Point on Line
It was too long ago. This created no hot-spots afaik.
There might be a better way.
If you want the points to be evenly distributed across the surface, you need to do this in two steps:
BoundedToBox sticks to the egdes because it’s a simple clamp, no projection.
The sphere has to be larger than the box, so it has high chance of generating points where two axis (say X and Y) are both larger than box extent. BoundedToBox will simply clamp that to BoxExtent.X and BoxExtent.Y so the points end up on egde.
Here’s my attempt ![]()
FVector RandomPointOnBoundingBoxPerimeter(FVector Origin, FVector BoxExtent)
{
const FVector Dir = FMath::VRand();
const FVector Dist = BoxExtent / Dir;
return Origin + Dir * Dist.GetAbsMin();
}
Since my question (although vague) was how to choose a random point on the perimeter of a 2D box, @eldany.uy was the first to point me in the right direction. This is how I ended up implemented in C++. I’m kind of embarrassed I didn’t think of this before… but I’m glad there was also a discussion about how to do it in 3D. Thanks everyone!
SpawnLocation = BoxBounds.Origin;
// Y is left-right Z is up-down
const float OffsetX = 0.f;
float OffsetY;
float OffsetZ;
if (const int32 RandomDirection = UKismetMathLibrary::RandomIntegerInRange(0, 3);
RandomDirection == 0)
{
// top
OffsetY = UKismetMathLibrary::RandomFloatInRange(-ScaledBoxBounds.Y, ScaledBoxBounds.Y);
OffsetZ = ScaledBoxBounds.Z;
}
else if (RandomDirection == 1)
{
// right
OffsetY = ScaledBoxBounds.Y;
OffsetZ = UKismetMathLibrary::RandomFloatInRange(-ScaledBoxBounds.Z, ScaledBoxBounds.Z);
}
else if (RandomDirection == 2)
{
// left
OffsetY = -ScaledBoxBounds.Y;
OffsetZ = UKismetMathLibrary::RandomFloatInRange(-ScaledBoxBounds.Z, ScaledBoxBounds.Z);
}
else
{
// bottom
OffsetY = UKismetMathLibrary::RandomFloatInRange(-ScaledBoxBounds.Y, ScaledBoxBounds.Y);
OffsetZ = -ScaledBoxBounds.Z;
}
FVector Offset = { OffsetX, OffsetY, OffsetZ };
SpawnLocation = FirstSpawnLocation + Offset;
Glad to help in the brainstorming process!
There are always a lot of ways of achieve a goal and
I am sure there are many better than this one but hey! it works ![]()
instead of nested If conditions you can use switch like this:
switch (RandomDirection)
{
case 0:
// top
OffsetY = UKismetMathLibrary::RandomFloatInRange(-ScaledBoxBounds.Y, ScaledBoxBounds.Y);
OffsetZ = ScaledBoxBounds.Z;
case 1:
// right
OffsetY = ScaledBoxBounds.Y;
OffsetZ = UKismetMathLibrary::RandomFloatInRange(-ScaledBoxBounds.Z, ScaledBoxBounds.Z);
case 2:
// left
OffsetY = -ScaledBoxBounds.Y;
OffsetZ = UKismetMathLibrary::RandomFloatInRange(-ScaledBoxBounds.Z, ScaledBoxBounds.Z);
default:
// bottom
OffsetY = UKismetMathLibrary::RandomFloatInRange(-ScaledBoxBounds.Y, ScaledBoxBounds.Y);
OffsetZ = -ScaledBoxBounds.Z;
}
Greetz!
Dany
Thank you so much for providing this approach!!