1 /*
2 * Copyright (c) 2019 Kevin Townsend (KTOWN)
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <math.h>
8 #include <errno.h>
9 #include <zsl/zsl.h>
10 #include <zsl/physics/projectiles.h>
11
12 int
zsl_phy_proj_init_vel(zsl_real_t vi,zsl_real_t theta,zsl_real_t * vih,zsl_real_t * viv)13 zsl_phy_proj_init_vel(zsl_real_t vi, zsl_real_t theta, zsl_real_t *vih,
14 zsl_real_t *viv)
15 {
16 *vih = vi * ZSL_COS(theta);
17 *viv = vi * ZSL_SIN(theta);
18
19 return 0;
20 }
21
22 int
zsl_phy_proj_time(zsl_real_t viv,zsl_real_t yi,zsl_real_t yf,zsl_real_t * t)23 zsl_phy_proj_time(zsl_real_t viv, zsl_real_t yi, zsl_real_t yf,
24 zsl_real_t *t)
25 {
26 zsl_real_t disc = viv * viv + 2.0 * ZSL_GRAV_EARTH * (yi - yf);
27
28 if (disc < 0) {
29 *t = NAN;
30 return -EINVAL;
31 }
32
33 *t = (viv + ZSL_SQRT(disc)) / ZSL_GRAV_EARTH;
34
35 return 0;
36 }
37
zsl_phy_proj_time_first(zsl_real_t viv,zsl_real_t yi,zsl_real_t yf,zsl_real_t * t)38 int zsl_phy_proj_time_first(zsl_real_t viv, zsl_real_t yi, zsl_real_t yf,
39 zsl_real_t *t)
40 {
41 zsl_real_t disc = viv * viv + 2.0 * ZSL_GRAV_EARTH * (yi - yf);
42
43 if (disc < 0) {
44 *t = NAN;
45 return -EINVAL;
46 }
47
48 *t = (viv - ZSL_SQRT(disc)) / ZSL_GRAV_EARTH;
49
50 if (*t < 0) {
51 *t = NAN;
52 return -EINVAL;
53 }
54
55 return 0;
56 }
57
58 int
zsl_phy_proj_time2(zsl_real_t viv,zsl_real_t vfv,zsl_real_t * t)59 zsl_phy_proj_time2(zsl_real_t viv, zsl_real_t vfv, zsl_real_t *t)
60 {
61 *t = (viv - vfv) / ZSL_GRAV_EARTH;
62
63 if (*t < 0) {
64 *t = NAN;
65 return -EINVAL;
66 }
67
68 return 0;
69 }
70
71 int
zsl_phy_proj_ver_motion(zsl_real_t viv,zsl_real_t t,zsl_real_t yi,zsl_real_t * yf)72 zsl_phy_proj_ver_motion(zsl_real_t viv, zsl_real_t t, zsl_real_t yi,
73 zsl_real_t *yf)
74 {
75 if (t < 0) {
76 *yf = NAN;
77 return -EINVAL;
78 }
79
80 *yf = yi + viv * t - (ZSL_GRAV_EARTH * t * t) / 2.0;
81
82 return 0;
83 }
84
85 int
zsl_phy_proj_ver_vel(zsl_real_t viv,zsl_real_t t,zsl_real_t * vfv)86 zsl_phy_proj_ver_vel(zsl_real_t viv, zsl_real_t t, zsl_real_t *vfv)
87 {
88 if (t < 0) {
89 *vfv = NAN;
90 return -EINVAL;
91 }
92
93 *vfv = viv - ZSL_GRAV_EARTH * t;
94
95 return 0;
96 }
97
98 int
zsl_phy_proj_hor_motion(zsl_real_t vih,zsl_real_t t,zsl_real_t xi,zsl_real_t * xf)99 zsl_phy_proj_hor_motion(zsl_real_t vih, zsl_real_t t, zsl_real_t xi,
100 zsl_real_t *xf)
101 {
102 *xf = xi + vih * t;
103
104 if (t < 0) {
105 *xf = NAN;
106 return -EINVAL;
107 }
108
109 return 0;
110 }
111
112 int
zsl_phy_proj_trajectory(zsl_real_t vih,zsl_real_t viv,zsl_real_t xi,zsl_real_t yi,zsl_real_t xf,zsl_real_t * yf)113 zsl_phy_proj_trajectory(zsl_real_t vih, zsl_real_t viv, zsl_real_t xi,
114 zsl_real_t yi, zsl_real_t xf, zsl_real_t *yf)
115 {
116 zsl_real_t t = (xf - xi) / vih;
117
118 if (vih == 0 || t < 0) {
119 *yf = NAN;
120 return -EINVAL;
121 }
122
123 zsl_phy_proj_ver_motion(viv, t, yi, yf);
124
125 return 0;
126 }
127
128 int
zsl_phy_proj_vel(zsl_real_t vfh,zsl_real_t vfv,zsl_real_t * vf)129 zsl_phy_proj_vel(zsl_real_t vfh, zsl_real_t vfv, zsl_real_t *vf)
130 {
131 *vf = ZSL_SQRT(vfh * vfh + vfv * vfv);
132
133 return 0;
134 }
135
136 int
zsl_phy_proj_angle(zsl_real_t vfh,zsl_real_t vfv,zsl_real_t * theta)137 zsl_phy_proj_angle(zsl_real_t vfh, zsl_real_t vfv, zsl_real_t *theta)
138 {
139 if (vfh == 0) {
140 *theta = ZSL_PI / 2.0;
141 return 0;
142 }
143
144 *theta = ZSL_ATAN(vfv / vfh);
145
146 return 0;
147 }
148
149 int
zsl_phy_proj_range(zsl_real_t vih,zsl_real_t viv,zsl_real_t xi,zsl_real_t yi,zsl_real_t * dist)150 zsl_phy_proj_range(zsl_real_t vih, zsl_real_t viv, zsl_real_t xi,
151 zsl_real_t yi, zsl_real_t *dist)
152 {
153 zsl_real_t t, xf;
154
155 zsl_phy_proj_time(viv, yi, 0.0, &t);
156
157 zsl_phy_proj_hor_motion(vih, t, xi, &xf);
158
159 *dist = xf - xi;
160
161 return 0;
162 }
163