Skip to content

Commit d6a9d42

Browse files
committed
linear done
1 parent 6cf203a commit d6a9d42

File tree

2 files changed

+256
-0
lines changed

2 files changed

+256
-0
lines changed

examples/linear_ex.py

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
"""
2+
Example file demonstrating the use of linear_traj function.
3+
4+
This example shows:
5+
1. How to generate a linear trajectory between two points
6+
2. How to use the function with both scalar and vector positions
7+
3. Visualization of the generated trajectories
8+
"""
9+
10+
import matplotlib.pyplot as plt
11+
import numpy as np
12+
13+
from interpolatepy.linear import linear_traj
14+
15+
16+
def scalar_trajectory_example() -> None:
17+
"""Demonstrate linear_traj with scalar positions."""
18+
print("Scalar Trajectory Example")
19+
print("--------------------------")
20+
21+
# Define start and end points
22+
p0 = 0.0
23+
p1 = 10.0
24+
25+
# Define time interval
26+
t0 = 0.0
27+
t1 = 2.0
28+
29+
# Generate time array
30+
num_points = 100
31+
time_array = np.linspace(t0, t1, num_points)
32+
33+
# Calculate trajectory
34+
positions, velocities, accelerations = linear_traj(p0, p1, t0, t1, time_array)
35+
36+
# Print some values
37+
print(f"Start position: {positions[0]}")
38+
print(f"End position: {positions[-1]}")
39+
print(f"Constant velocity: {velocities[0]}")
40+
print(f"Acceleration: {accelerations[0]}")
41+
42+
# Plot results
43+
plt.figure(figsize=(12, 8))
44+
45+
# Position plot
46+
plt.subplot(3, 1, 1)
47+
plt.plot(time_array, positions, "b-", linewidth=2)
48+
plt.grid(True)
49+
plt.ylabel("Position")
50+
plt.title("Linear Trajectory - Scalar Case")
51+
52+
# Velocity plot
53+
plt.subplot(3, 1, 2)
54+
plt.plot(time_array, velocities, "g-", linewidth=2)
55+
plt.grid(True)
56+
plt.ylabel("Velocity")
57+
58+
# Acceleration plot
59+
plt.subplot(3, 1, 3)
60+
plt.plot(time_array, accelerations, "r-", linewidth=2)
61+
plt.grid(True)
62+
plt.ylabel("Acceleration")
63+
plt.xlabel("Time")
64+
65+
plt.tight_layout()
66+
plt.show()
67+
68+
69+
def vector_trajectory_example() -> None:
70+
"""Demonstrate linear_traj with vector positions (2D points)."""
71+
print("\nVector Trajectory Example (2D)")
72+
print("------------------------------")
73+
74+
# Define start and end points (2D vectors)
75+
p0 = [0.0, 0.0] # Starting at origin
76+
p1 = [10.0, 5.0] # Ending at (10, 5)
77+
78+
# Define time interval
79+
t0 = 0.0
80+
t1 = 3.0
81+
82+
# Generate time array
83+
num_points = 100
84+
time_array = np.linspace(t0, t1, num_points)
85+
86+
# Calculate trajectory
87+
positions, velocities, accelerations = linear_traj(p0, p1, t0, t1, time_array)
88+
89+
# Print some values
90+
print(f"Start position: {positions[0]}")
91+
print(f"End position: {positions[-1]}")
92+
print(f"Constant velocity: {velocities[0]}")
93+
print(f"Acceleration: {accelerations[0]}")
94+
95+
# Extract x and y components
96+
x_positions = positions[:, 0]
97+
y_positions = positions[:, 1]
98+
x_velocities = velocities[:, 0]
99+
y_velocities = velocities[:, 1]
100+
101+
# Plot results
102+
plt.figure(figsize=(12, 10))
103+
104+
# Trajectory in 2D space
105+
plt.subplot(3, 1, 1)
106+
plt.plot(x_positions, y_positions, "b-", linewidth=2)
107+
plt.plot(p0[0], p0[1], "ro", markersize=8, label="Start")
108+
plt.plot(p1[0], p1[1], "go", markersize=8, label="End")
109+
plt.grid(True)
110+
plt.xlabel("X position")
111+
plt.ylabel("Y position")
112+
plt.title("Linear Trajectory in 2D Space")
113+
plt.legend()
114+
115+
# X and Y positions over time
116+
plt.subplot(3, 1, 2)
117+
plt.plot(time_array, x_positions, "b-", linewidth=2, label="X position")
118+
plt.plot(time_array, y_positions, "g-", linewidth=2, label="Y position")
119+
plt.grid(True)
120+
plt.ylabel("Position")
121+
plt.legend()
122+
123+
# X and Y velocities over time
124+
plt.subplot(3, 1, 3)
125+
plt.plot(time_array, x_velocities, "b-", linewidth=2, label="X velocity")
126+
plt.plot(time_array, y_velocities, "g-", linewidth=2, label="Y velocity")
127+
plt.grid(True)
128+
plt.ylabel("Velocity")
129+
plt.xlabel("Time")
130+
plt.legend()
131+
132+
plt.tight_layout()
133+
plt.show()
134+
135+
136+
def main() -> None:
137+
"""Run both examples."""
138+
print("Linear Trajectory Examples")
139+
print("=========================\n")
140+
141+
# Run scalar example
142+
scalar_trajectory_example()
143+
144+
# Run vector example
145+
vector_trajectory_example()
146+
147+
148+
if __name__ == "__main__":
149+
main()

interpolatepy/linear.py

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import numpy as np
2+
3+
4+
def linear_traj(
5+
p0: float | list[float] | np.ndarray,
6+
p1: float | list[float] | np.ndarray,
7+
t0: float,
8+
t1: float,
9+
time_array: np.ndarray,
10+
) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
11+
"""
12+
Generate points along a linear trajectory using NumPy vectorization.
13+
14+
This function computes positions, velocities, and accelerations for points
15+
along a linear trajectory between starting position p0 and ending position p1.
16+
The trajectory is calculated for each time point in time_array.
17+
18+
Parameters
19+
----------
20+
p0 : float or list[float] or np.ndarray
21+
Starting position. Can be a scalar for 1D motion or an array/list for
22+
multi-dimensional motion.
23+
p1 : float or list[float] or np.ndarray
24+
Ending position. Must have the same dimensionality as p0.
25+
t0 : float
26+
Start time of the trajectory.
27+
t1 : float
28+
End time of the trajectory.
29+
time_array : np.ndarray
30+
Array of time points at which to calculate the trajectory.
31+
32+
Returns
33+
-------
34+
positions : np.ndarray
35+
Array of positions at each time point. For scalar inputs, shape is (len(time_array),).
36+
For vector inputs, shape is (len(time_array), dim) where dim is the dimension of p0/p1.
37+
velocities : np.ndarray
38+
Constant velocity at each time point, with the same shape as positions.
39+
accelerations : np.ndarray
40+
Zero acceleration at each time point, with the same shape as positions.
41+
42+
Examples
43+
--------
44+
Scalar positions (1D motion):
45+
46+
>>> import numpy as np
47+
>>> times = np.linspace(0, 1, 5)
48+
>>> pos, vel, acc = linear_traj(0, 1, 0, 1, times)
49+
>>> print(pos)
50+
[0. 0.25 0.5 0.75 1. ]
51+
>>> print(vel)
52+
[1. 1. 1. 1. 1.]
53+
>>> print(acc)
54+
[0. 0. 0. 0. 0.]
55+
56+
Vector positions (2D motion):
57+
58+
>>> import numpy as np
59+
>>> times = np.linspace(0, 2, 3)
60+
>>> p0 = [0, 0] # Start at origin
61+
>>> p1 = [4, 6] # End at point (4, 6)
62+
>>> pos, vel, acc = linear_traj(p0, p1, 0, 2, times)
63+
>>> print(pos)
64+
[[0. 0.]
65+
[2. 3.]
66+
[4. 6.]]
67+
>>> print(vel)
68+
[[2. 3.]
69+
[2. 3.]
70+
[2. 3.]]
71+
72+
Notes
73+
-----
74+
- This function implements linear interpolation with constant velocity and
75+
zero acceleration.
76+
- For vector inputs (multi-dimensional motion), proper broadcasting is applied
77+
to ensure correct calculation across all dimensions.
78+
- The function handles both scalar and vector inputs automatically:
79+
* For scalar inputs: outputs have shape (len(time_array),)
80+
* For vector inputs: outputs have shape (len(time_array), dim)
81+
- Time points outside the range [t0, t1] will still produce valid positions
82+
by extrapolating the linear trajectory.
83+
- The velocity is always constant and equal to (p1 - p0) / (t1 - t0).
84+
- The acceleration is always zero.
85+
"""
86+
# Convert inputs to numpy arrays if they aren't already
87+
p0 = np.array(p0)
88+
p1 = np.array(p1)
89+
time_array = np.array(time_array)
90+
91+
# Calculate coefficients
92+
a0 = p0
93+
a1 = (p1 - p0) / (t1 - t0)
94+
95+
# Handle broadcasting differently based on whether positions are scalar or vector
96+
if np.isscalar(p0) or p0.ndim == 0:
97+
positions = a0 + a1 * (time_array - t0)
98+
velocities = np.ones_like(time_array) * a1
99+
accelerations = np.zeros_like(time_array)
100+
else:
101+
# Vector case - reshape for proper broadcasting
102+
time_offset = (time_array - t0).reshape(-1, 1)
103+
positions = a0 + a1 * time_offset
104+
velocities = np.tile(a1, (len(time_array), 1))
105+
accelerations = np.zeros((len(time_array), len(a0)))
106+
107+
return positions, velocities, accelerations

0 commit comments

Comments
 (0)