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/mass.h>
11
12
13 int
zsl_phy_mass_center(struct zsl_vec * m,struct zsl_vec * x,struct zsl_vec * y,struct zsl_vec * z,zsl_real_t * mx,zsl_real_t * my,zsl_real_t * mz)14 zsl_phy_mass_center(struct zsl_vec *m, struct zsl_vec *x,
15 struct zsl_vec *y, struct zsl_vec *z, zsl_real_t *mx,
16 zsl_real_t *my, zsl_real_t *mz)
17 {
18 /* TO DO: Check if the number of arguments in m, x, y and z
19 * is equal to n. */
20
21 int rc;
22 zsl_real_t mt = 0.0;
23 zsl_real_t mtx = 0.0;
24 zsl_real_t mty = 0.0;
25 zsl_real_t mtz = 0.0;
26
27 #if CONFIG_ZSL_BOUNDS_CHECKS
28 /* Ensure that all vectors have the same size. */
29 if ((m->sz != x->sz) || (x->sz != y->sz) || (y->sz != z->sz)) {
30 *mx = NAN;
31 *my = NAN;
32 *mz = NAN;
33 return -EINVAL;
34 }
35 #endif
36
37 rc = zsl_vec_dot(m, x, &mtx);
38 if (rc) {
39 return -EINVAL;
40 }
41
42 rc = zsl_vec_dot(m, y, &mty);
43 if (rc) {
44 return -EINVAL;
45 }
46
47 rc = zsl_vec_dot(m, z, &mtz);
48 if (rc) {
49 return -EINVAL;
50 }
51
52 /* Calculate arithematic mean of all masses in vector m. */
53 rc = zsl_vec_ar_mean(m, &mt);
54 if (rc) {
55 return -EINVAL;
56 }
57
58 /* Ensure there are no negative values for mass. */
59 if (zsl_vec_is_nonneg(m) == false) {
60 *mx = NAN;
61 *my = NAN;
62 *mz = NAN;
63 return -EINVAL;
64 }
65
66 mt *= m->sz;
67
68 /* Avoid divide by zero errors. */
69 if (mt == 0.0) {
70 *mx = NAN;
71 *my = NAN;
72 *mz = NAN;
73 return -EINVAL;
74 }
75
76 *mx = mtx / mt;
77 *my = mty / mt;
78 *mz = mtz / mt;
79
80 return 0;
81 }
82