Python: How to create trajectory between start and end positions with specified speeds in a vectorized way?
First I think you were fooled by a simple but yet subtle mathematical error you made. In your illustration, you show the first path segment to be from (0,0) to (3,1). This however does not correspond to a "speed" of 4, as your object moves along the diagonal path. For the first line segment you would get a speed of
v = (1**2 + 3**2)**0.5 (= 3.162)
Even less obvious to me is, how you got to a speed of 4 in the second line segment, but you mentioned approximate coordinates, so I will assume, that these are not the exact coordinates that you are looking for.
That put aside, you will not generally be able to get to the exact ending point with different specified speeds, so I will show a solution, that gets just past the ending point and stops there.
import numpy as np
ue_speed = [3, 4, 8, 25]
ue_speed_prob = [0.4, 0.2, 0.3, 0.1]
square_size = 100 # need for scaling
time_interval = 100 # need for scaling
start_coord = [0, 0]
end_coord = [25, 15]
b = end_coord[0] - start_coord[0]
a = end_coord[1] - start_coord[1]
c = (a**2+b**2)**0.5
theta = np.arctan2(a,b)
steps = int(c//(min(ue_speed)*time_interval/square_size) + 1) # fixed scaling issue
v = np.random.choice(ue_speed, size=steps, p=ue_speed_prob)
R = np.cumsum((v * time_interval) / square_size)
R = R[:np.argmax(R>c)+1]
P = np.column_stack((R*np.cos(theta)+start_coord[0],
R*np.sin(theta)+start_coord[1]))
trajectory = P
This will print trajectory
as
[[ 2.57247878 1.54348727]
[ 5.14495755 3.08697453]
[12.00490096 7.20294058]
[33.4422241 20.06533446]]
Note: You also made a very serious error in your code, when your converted the result of the math.asin
to degrees and then used it again in trigonometric functions like np.sin
and np.cos
. I strongly recommand you to stick to radiant angle values and only convert them to degrees if you want to print them out.
Also I recommend the use of an arctan2
like function, to correctly get the angle of an x and y coordinate, as this will also work for negative x directions.