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!!