I have an object with known coordinates in in 3D but on the ground (z=0). The object has a direction vector. My goal is to move this object on the ground (so z stays 0) using its direction vector and via randomly-generated velocity vectors with one condition: I want to ensure that the generate velocity vector can only move the object within a "valid arc", defined in degrees with respect to the direction vector of the object. More specifically, the way I determine valid range is by ensuring that the new position is within 45 degrees of the old object's direction vector (-45 degrees to the left and +45 degrees to the right). Can someone write a pseudocode on how I can achieve this?
Here's my attempt to do this but this doesn't seem to be the correct way to help me achieve what I want:
object_dir = object_position # the direction could be the same as the object's coortinates
while True:
vel_vec=[uniform(-max_vel, max_vel), uniform(-max_vel, max_vel)] # generate a random velocity vector
new_pos = object_dir + vel_vec # compute a new position (and/or object direction vector) for the object
if (compute_angle(new_pos, object_dir) < 45 or compute_angle(new_pos, object_dir) > 315):
break
Based on the comments, I think you just want the direction of motion in each time step to be less than $45$ degrees from the direction of motion in the previous time step. That means you can completely reverse direction if you take enough steps to do it. You can also eventually travel into all four quadrants of the plane regardless of how you started out from the origin.
Moreover, the velocity of the object is a vector in the direction of travel of the object. The only distinction I might make between a "direction vector" and velocity is that a "direction vector" might be normalized to a certain length. Often the direction vector will be defined as the unit-length vector in the same direction as the velocity.
If you can find the angle between arbitrary vectors, not just unit vectors, I don't even see a reason to include any "direction vector" in your code. Just consider velocity.
So I would ignore positions entirely when computing the angle. But you need to remember what the direction vector was in the previous time step.
Here's one way you could do it. In each time step, you compute a new
vel_vec. You then compute the angle betweenvel_vecandprevious_vel_vec(which was the velocity vector in the previous time step). If that angle is in the permitted range, acceptvel_vec, otherwise try again.When you finally find an acceptable
vel_vec, then you use it to compute a new position. And then make the assignmentprevious_vel_vec = vel_vecso that you will have the correctprevious_vel_vecfor the next time step.But I would do it quite differently. For one thing, I don't like the fact that the velocity is more likely to be at about a $45$ degree angle from an axis than parallel to an axis regardless of what the valid arc is at that time. This happens because you distributed the velocity uniformly over a square, and there is more area in the parts of a square within $\pm22.5$ degrees of a diagonal than within $\pm22.5$ degrees of a centerline parallel to a side. I would prefer to distribute the direction uniformly within the limits of the valid arc.
I would keep track of the "compass direction" of the velocity (that is, what angle it makes with the $x$ axis in the $x,y$ plane). Then, at each time step, to find the new velocity I just add a random number uniformly distributed between $-\frac\pi4$ and $\frac\pi4$ (measuring the angle in radians -- if you insist on using degrees, which you will continually have to convert to radians anyway for every trig function, then you want a uniform distribution between $-45$ and $45$). Take another random number $\rho$ uniformly distributed between $0$ and $1,$ and multiply
max_velby $\sqrt{\rho},$ because that's how we get a uniform distribution within a circular sector. (As this answer observes, we get a uniform distribution within an entire circle if we let the angle range over $360$ degrees; we are just restricting the angle in order to sample a sector).