Statistics
| Branch: | Revision:

adafruit_bno055 / utility / vector.h @ a6c06c10

History | View | Annotate | Download (4.875 KB)

1 4bc1c0c1 Kevin Townsend
/*
2
    Inertial Measurement Unit Maths Library
3
    Copyright (C) 2013-2014  Samuel Cowen
4 d964148c Tony DiCola
    www.camelsoftware.com
5 4bc1c0c1 Kevin Townsend

6
    This program is free software: you can redistribute it and/or modify
7
    it under the terms of the GNU General Public License as published by
8
    the Free Software Foundation, either version 3 of the License, or
9
    (at your option) any later version.
10

11
    This program is distributed in the hope that it will be useful,
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
    GNU General Public License for more details.
15

16
    You should have received a copy of the GNU General Public License
17
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
*/
19
20
#ifndef IMUMATH_VECTOR_HPP
21
#define IMUMATH_VECTOR_HPP
22
23
#include <string.h>
24
#include <stdint.h>
25
#include <math.h>
26
27
28
namespace imu
29
{
30
31
template <uint8_t N> class Vector
32
{
33
public:
34 d964148c Tony DiCola
    Vector()
35
    {
36 4bc1c0c1 Kevin Townsend
        memset(p_vec, 0, sizeof(double)*N);
37 d964148c Tony DiCola
    }
38 4bc1c0c1 Kevin Townsend
39 d964148c Tony DiCola
    Vector(double a)
40
    {
41 4bc1c0c1 Kevin Townsend
        memset(p_vec, 0, sizeof(double)*N);
42 d964148c Tony DiCola
        p_vec[0] = a;
43
    }
44 4bc1c0c1 Kevin Townsend
45 d964148c Tony DiCola
    Vector(double a, double b)
46
    {
47 4bc1c0c1 Kevin Townsend
        memset(p_vec, 0, sizeof(double)*N);
48 d964148c Tony DiCola
        p_vec[0] = a;
49
        p_vec[1] = b;
50
    }
51 4bc1c0c1 Kevin Townsend
52 d964148c Tony DiCola
    Vector(double a, double b, double c)
53
    {
54 4bc1c0c1 Kevin Townsend
        memset(p_vec, 0, sizeof(double)*N);
55 d964148c Tony DiCola
        p_vec[0] = a;
56
        p_vec[1] = b;
57
        p_vec[2] = c;
58
    }
59 4bc1c0c1 Kevin Townsend
60
    Vector(double a, double b, double c, double d)
61
    {
62
        memset(p_vec, 0, sizeof(double)*N);
63
        p_vec[0] = a;
64 d964148c Tony DiCola
        p_vec[1] = b;
65
        p_vec[2] = c;
66
        p_vec[3] = d;
67 4bc1c0c1 Kevin Townsend
    }
68
69
    Vector(const Vector<N> &v)
70
    {
71 b2d499c7 Paul Du Bois (laptop)
        for (int x = 0; x < N; x++)
72 4bc1c0c1 Kevin Townsend
            p_vec[x] = v.p_vec[x];
73
    }
74
75
    ~Vector()
76
    {
77
    }
78
79
    uint8_t n() { return N; }
80
81
    double magnitude()
82
    {
83
        double res = 0;
84
        int i;
85
        for(i = 0; i < N; i++)
86
            res += (p_vec[i] * p_vec[i]);
87
88
        if(isnan(res))
89
            return 0;
90 abce6607 Paul Du Bois (laptop)
        if((fabs(res-1)) >= 0.000001) // Avoid a sqrt if possible.
91 4bc1c0c1 Kevin Townsend
            return sqrt(res);
92
        return 1;
93
    }
94
95
    void normalize()
96
    {
97
        double mag = magnitude();
98
        if(abs(mag) <= 0.0001)
99
            return;
100
101
        int i;
102
        for(i = 0; i < N; i++)
103
            p_vec[i] = p_vec[i]/mag;
104
    }
105
106
    double dot(Vector v)
107
    {
108
        double ret = 0;
109
        int i;
110
        for(i = 0; i < N; i++)
111
            ret += p_vec[i] * v.p_vec[i];
112
113
        return ret;
114
    }
115
116 fd9de024 Gé Vissers
    // The cross product is only valid for vectors with 3 dimensions,
117
    // with the exception of higher dimensional stuff that is beyond
118
    // the intended scope of this library.
119
    // Only a definition for N==3 is given below this class, using
120
    // cross() with another value for N will result in a link error.
121
    Vector cross(const Vector& v) const;
122 4bc1c0c1 Kevin Townsend
123 0695bf91 Paul Du Bois (laptop)
    Vector scale(double scalar) const
124 4bc1c0c1 Kevin Townsend
    {
125
        Vector ret;
126
        for(int i = 0; i < N; i++)
127
            ret.p_vec[i] = p_vec[i] * scalar;
128
        return ret;
129
    }
130
131 0695bf91 Paul Du Bois (laptop)
    Vector invert() const
132 4bc1c0c1 Kevin Townsend
    {
133
        Vector ret;
134
        for(int i = 0; i < N; i++)
135
            ret.p_vec[i] = -p_vec[i];
136
        return ret;
137
    }
138
139
    Vector operator = (Vector v)
140
    {
141
        for (int x = 0; x < N; x++ )
142
            p_vec[x] = v.p_vec[x];
143 d964148c Tony DiCola
        return *this;
144 4bc1c0c1 Kevin Townsend
    }
145
146
    double& operator [](int n)
147
    {
148
        return p_vec[n];
149
    }
150
151 0695bf91 Paul Du Bois (laptop)
    double operator [](int n) const
152
    {
153
        return p_vec[n];
154
    }
155
156 4bc1c0c1 Kevin Townsend
    double& operator ()(int n)
157
    {
158
        return p_vec[n];
159
    }
160
161 0695bf91 Paul Du Bois (laptop)
    double operator ()(int n) const
162
    {
163
        return p_vec[n];
164
    }
165
166
    Vector operator + (Vector v) const
167 4bc1c0c1 Kevin Townsend
    {
168
        Vector ret;
169
        for(int i = 0; i < N; i++)
170
            ret.p_vec[i] = p_vec[i] + v.p_vec[i];
171
        return ret;
172
    }
173
174 0695bf91 Paul Du Bois (laptop)
    Vector operator - (Vector v) const
175 4bc1c0c1 Kevin Townsend
    {
176
        Vector ret;
177
        for(int i = 0; i < N; i++)
178
            ret.p_vec[i] = p_vec[i] - v.p_vec[i];
179
        return ret;
180
    }
181
182 0695bf91 Paul Du Bois (laptop)
    Vector operator * (double scalar) const
183 4bc1c0c1 Kevin Townsend
    {
184
        return scale(scalar);
185
    }
186
187 0695bf91 Paul Du Bois (laptop)
    Vector operator / (double scalar) const
188 4bc1c0c1 Kevin Townsend
    {
189
        Vector ret;
190
        for(int i = 0; i < N; i++)
191
            ret.p_vec[i] = p_vec[i] / scalar;
192
        return ret;
193
    }
194
195
    void toDegrees()
196
    {
197
        for(int i = 0; i < N; i++)
198
            p_vec[i] *= 57.2957795131; //180/pi
199
    }
200
201
    void toRadians()
202
    {
203
        for(int i = 0; i < N; i++)
204
            p_vec[i] *= 0.01745329251;  //pi/180
205
    }
206
207
    double& x() { return p_vec[0]; }
208
    double& y() { return p_vec[1]; }
209
    double& z() { return p_vec[2]; }
210 0695bf91 Paul Du Bois (laptop)
    double x() const { return p_vec[0]; }
211
    double y() const { return p_vec[1]; }
212
    double z() const { return p_vec[2]; }
213 4bc1c0c1 Kevin Townsend
214
215
private:
216 b2d499c7 Paul Du Bois (laptop)
    double  p_vec[N];
217 4bc1c0c1 Kevin Townsend
};
218
219
220 fd9de024 Gé Vissers
template <>
221
inline Vector<3> Vector<3>::cross(const Vector& v) const
222
{
223
    return Vector(
224
        p_vec[1] * v.p_vec[2] - p_vec[2] * v.p_vec[1],
225
        p_vec[2] * v.p_vec[0] - p_vec[0] * v.p_vec[2],
226
        p_vec[0] * v.p_vec[1] - p_vec[1] * v.p_vec[0]
227
    );
228
}
229
230
} // namespace
231 4bc1c0c1 Kevin Townsend
232
#endif