Salut, je développe actuellement un moteur physique mais j'ai quelques problèmes d'imprécision au niveau du produit scalaire.
J'ai codé deux classes, une classe math et une classes vec4 que voici :
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190 #ifndef CONSTANTS #define CONSTANTS #define PI 3.1415926535897932 #define TWO_PI 2*PI #define HALF_PI PI/2 #define INV_PI = 1/PI #define INV_TWO_PI = TWO_PI / 2 #define RAD_TO_DEG 180/PI #define DEG_TO_RAD PI/180 #define ONE_THIRD 1.f / 3.f #define TWO_THIRD 2.f / 3.f #define EPSILON 0.000001 #include <math.h> #include "export.hpp" #include <random> #include <ctime> /** *\namespace odfaeg * the namespace of the Opensource Development Framework Adapted for Every Games. */ namespace odfaeg { class Vec3f; /** * \file math.h * \class Math * \brief Do some math tricks. * \author Duroisin.L * \version 1.0 * \date 1/02/2014 * * Contains some arithmetic functions for floatting numbers. * Defines also some variable : * PI is the value of the number PI. * TWO_PI is the value of the double of PI. * HALF_PI is the value of the half of PI. * INV_PI is the value of the inverse of PI. * INV_TWO_PI is the value of the inverse of the double of PI. * RAD_TO_DEG is the value used to convert radians to degrees. * DEG_TO_RAD is the value used to convert degress to radians. * ONE_THIRD is the value of one divided by 3. * TWO_THIRD is the value of two divided by 3. * EPSILON is a very little value used to avoid to have overflow problems with floatting numbers. */ class ODFAEG_MATH_API Math { public: /** * \fn float acosinus (float value) * \brief return the arc cosinus of a cosinus value. * \param the value of the cosinus. * \return the arc cosinus of the angle. (given in radians) */ static float acosinus(float value); /** * \fn float asinus (float value) * \brief return the arc sinus of a sinus value. * \param the value of the sinus. * \return the arc sinus of the angle. (given in radians) */ static float asinus(float value); /** * \fn float sinus (float value) * \brief return the sinus of an angle. (given in radians) * \param the angle's value. (given in radians) * \return the sinus of the angle */ static float sinus (float value); /** * \fn float cosinus (float value) * \brief return the cosinus of an angle. (given in radians) * \param the angle's value. (given in radians) * \return the cosinus of the angle. */ static float cosinus (float value); /** * \fn float atang (float value) * \brief return the arc tangeant of a tangeant value. * \param the value of the tangeant. * \return the tangeant. */ static float atang(float value); /** * \fn float abs (float value) * \brief return the absolute value of a value. * \param the value. * \return the absolute value of the value. (The absolute value is always positive) */ static float abs (float value); /** * \fn float tang (float value) * \brief return the tangeant of an angle. (given in radians) * \param the value of the angle. (given in radian) * \return the tangeant of the angle. */ static float tang (float value); /** * \fn float sqrt (float value) * \brief return the square root of a number. * \param the value of the number. * \return the square root of the number. */ static float sqrt (float value); /** * \fn float log10 (float value) * \brief return the logarythm of a number in base 10. * \param the value of the logarythm. * \return the logarythm of the value. (Example : the logarythm of 100 in base 10 is 2 because 10² = 100.) */ static float log10(float value); /** * \fn float logn (float value) * \brief return the logarythm of a number in base n. * \param the value of the logarythm. * \return the logarythm of the value. */ static float logn(float value, int base); /** * \fn float power (float value, float p) * \brief return the value of a number exponent p. * \param value : the value of the number. * \param p : the value of the exponent. * \return the value of the number exponent p. */ static float power(float value, float p); /** * \fn round a number. * \brief round a number with the given precision. * \param value : the value of the number. * \param p : the precision. (The number of decimals after the floatting point) * \return the number rounded with p precision. */ static float round(float value, int p); /** * \fn float inversSqrt(float value) * \brief return the inverse of the square root of a number. * \param the value of the number. * \return the value of the inverse of the square root of the number. */ static float inversSqrt(float value); /** * \fn float toRadian (float value) * \brief return the radians value of a given angle. * \param the value of the angle. * \return the radians value of the angle. */ static float toRadians (float value); /** * \fn float toDegrees (float value) * \brief return the gegrees value of a given angle. * \param the value of the angle. * \return the degrees value of the angle. */ static float toDegrees (float value); /** * \fn float exp (float value) * \brief return the exponent of the value. * \return the value of the number exponent. */ static float exp (float value); /** * \fn Vec3f toCartesian (float teta, float phi) * \brief convert polar coordinates to cartesian coordinates. * \param teta : the value of the angle teta. (in radian) * \param phi : the value of the angle phi. (in radian) * \return the Vector of the cartesian coordinates. */ static Vec3f toCartesian (float teta, float phi); /** * \fn int clamp (int value, int min, int max) * \brief restrict the value of a number in a specified interval. * \param value : the value of the number. * \param min : the minimum value of the interval. * \param max : the maximum value of the interval. * \return the value of the number in the specified interval. */ static int clamp (int value, int min, int max); /** * \fn float random (float max, float min = 0) * \brief get a random value in a specified interval. * \param max : the maximum value of the interval. * \param min : the minimum value of the interval. (0 by default) * \return the random value in the specified interval */ static float random(float max, float min = 0); private : static std::mt19937 mrs; }; } #endif
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142 #include "../../../include/odfaeg/Math/maths.h" #include "../../../include/odfaeg/Math/vec4.h" /*Fonctions élémentaires.*/ //Donne l'arc cosinus d'une valeur. namespace odfaeg { std::mt19937 Math::mrs = std::mt19937(static_cast<unsigned long>(std::time(nullptr))); float Math::random(float min, float max) { std::uniform_real_distribution<float> distribution(min, max); return distribution(mrs); } float Math::acosinus(float value) { float result; if(-1.f < value) { if(value < 1.f) result = (float) acos(value); else result = 0.f; } else result = PI; return (result < EPSILON && result > -EPSILON) ? 0 : result; } //Donne l'arc sinus d'une valeur. float Math::asinus(float value) { float result; if(-1.f < value) { if(value < 1.f) result = (float) asin(value); else result = HALF_PI; } else result = -HALF_PI; return (result < EPSILON && result > -EPSILON) ? 0 : result; } //Donne l'arc tangeante d'une valeur. float Math::atang(float value) { float result = (float) atan(value); return (result < EPSILON && result > -EPSILON) ? 0 : result; } //Donne le sinus d'un angle donné en radian. float Math::sinus (float value) { float result, radians = value / TWO_PI; if(abs(radians) > PI) radians -= TWO_PI; if(abs(radians) > HALF_PI) radians = PI - radians; if(abs(radians) <= PI / 4) { result = (float) sin(value); } else { result = (float) cos (PI/2-value); } return (result < EPSILON && result > -EPSILON) ? 0 : result; } //Donne le cosinus d'un angle donnée en radian. float Math::cosinus (float value) { float result = (float) sin(value+HALF_PI); return (result < EPSILON && result > -EPSILON) ? 0 : result; } //Donne la tangeante d'un angle donné en radians. float Math::tang (float value) { float result = (float) tan(value); return (result < EPSILON && result > -EPSILON) ? 0 : result; } //Donne la valeur absolue d'un nombre. float Math::abs(float value) { if (value >= 0) return value; return -value; } //Renvoie la racine carrée d'un nombre. float Math::sqrt(float value){ return std::sqrt(value); } //Donne l'inverse de la racine carrée d'un nombre. float Math::inversSqrt(float value) { return 1.f / sqrt(value); } //Donne le logarithme d'un nombre. (En base 10.) float Math::log10 (float value) { return (float) log(value); } //Donne le logarithme d'un nombre en base base. float Math::logn (float value, int base) { return (float) (log(value)/log(base)); } //Donne le nombre à la puissance n. float Math::power (float value, float exp) { return (float) pow(value, exp); } //Converti un angle en radian. float Math::toRadians(float value) { return value * DEG_TO_RAD; } //Convertis un angle en degrer. float Math::toDegrees(float value) { return value * RAD_TO_DEG; } //Arrondis un nombre à la précision p. float Math::round(float value, int p) { int mult = (int) pow(10, p + 1); int numberToRound = (int) (value * mult); int lastChiffer = numberToRound % 10; if (numberToRound > 0) { if (lastChiffer >= 5) numberToRound += 10; } else { if (lastChiffer <= -5) numberToRound -= 10; } numberToRound = numberToRound - lastChiffer; return numberToRound / mult;; } //Renvoie l'exponetielle d'un nombre. float Math::exp (float value) { return (float) std::exp(value); } //Convertis des coordonnée polaire en coordonée cartésinnes. Vec3f Math::toCartesian (float teta, float phi) { float rTemp = Math::cosinus(phi); float y = Math::sinus(phi); float z = -rTemp * Math::cosinus(teta); float x = -rTemp * Math::sinus(teta); return Vec3f (x, y, z); } int Math::clamp (int value, int min, int max) { if (value < min) value = min; if (value >= max); value = max - 1; return value; } }
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236 #ifndef VEC4 #define VEC4 #include <iostream> #include "maths.h" #include <SFML/System.hpp> #include "../../../include/odfaeg/Core/erreur.h" /** *\namespace odfaeg * the namespace of the Opensource Development Framework Adapted for Every Games. */ namespace odfaeg { class Matrix3f; /** * \file vec4.h * \class Vec3f * \brief Manage a 3D vector * \author Duroisin.L * \version 1.0 * \date 1/02/2014 * * This class defines 3D vectors of floating numbers and all operations about vectors. * This class redefines the class sf::Vector3f and offers more operations. * Vectors are very usefull for physic's and mathematic's algorithms. * In ODFAEG, vectors are used to define a direction or a point. */ class ODFAEG_MATH_API Vec3f : public sf::Vector3f { public : static const Vec3f xAxis; /**< Vec3f the x axis.*/ static const Vec3f yAxis; /**< Vec2f the y axis.*/ static const Vec3f zAxis; /**< Vec3f the z axis.*/ /**\fn Vec3f() * \brief default constructror. * construct a null vector (with 0, 0, 0 as coordinates) */ Vec3f (); /**\fn Vec2f(float x, float y, float) * \brief constructror. * construct a vector with the given coordinates. * \param x : the x coordinate. * \param y : the y coordinate. * \param z : the z coordinate. */ Vec3f (float x, float y, float z); /**\fn Vec2f(float x, float y, float) * \brief constructror. * construct a vector with the given coordinates. * \param x : the x coordinate. * \param y : the y coordinate. * \param z : the z coordinate. * \param w : the w coordinate. (Used for 3D projections) */ Vec3f (float x, float y, float z, float w); /**\fn void set (float x, float y, float) * \brief set the x, y and z coordinates of the vector. * \param x : the x coordinate. * \param y : the y coordinate. * \param z : the z coordinate. */ void set(float x, float y, float z); /** * \fn bool isNulVector() const * \brief return true if the vector is null, false otherwise. * \return true if the vector is null (0, 0, 0). */ bool isNulVector () const; /** * \fn float operator[] (int i) * \brief retrieve one coordinate from the vector. * \param i : the indice of the vector coordinate. (0 = x, 1 = y and 2 = z) * \return the value of the coordinate. */ float& operator[] (int i); /** * \fn Vec3f operator+ (const Vec3f &other) * \brief add a vector to another and return the resulting vector. * \param the vector to be added with. * \return the resulting vector. */ Vec3f operator+ (const Vec3f &other); /** \fn Vec3f operator- (const Vec3f other) * \brief substract the vector from another one and return the resulting vector. * \param the other vector to be substracted from. * \return the resulting vector. */ Vec3f operator- (const Vec3f &other); /** \fn Vec3f operator* (const Vec3f other) * \brief multiply the vector by another one and return the resulting vector. * \param the other vector to be multiplied by. * \return the resulting vector. */ Vec3f operator* (const Vec3f &other); /** \fn Vec2f operator* (const Vec2f other) * \brief divide the vector by another one and return the resulting vector. * \param the other vector to be devided by. * \return the resulting vector. */ Vec3f operator/ (const Vec3f &other); /** \fn bool operator== (const Vec3f &other) * \brief compare if two vectors ar equals. (They are equals of the coordiates are the same) * \param the other vector to be compared with. * \return true if the two vectors are equal, false otherwise. */ Vec3f operator/ (float scalar); Vec3f& operator= (const Vec3f &other); Vec3f projOnVector(Vec3f other); bool isOpposite (const Vec3f &other) const; /** \fn bool operator== (const Vec3f &other) * \brief compare if two vectors ar equals. (They are equals of the coordiates are the same) * \param the other vector to be compared with. * \return true if the two vectors are equal, false otherwise. */ bool operator== (const Vec3f &other); /** \fn Vec2f operator-() * \brief return the opposite of the vector * \return the opposite of the vector. */ Vec3f operator- () const; /** \fn void operator-= (const Vec2f other) * \brief substract the vector from another one. * \param the other vector to be added with. */ Vec3f& operator += (const Vec3f &other); /** \fn void operator*= (const Vec2f other) * \brief multiply the vector by another one. * \param the other vector to be multiplied by. */ void operator -= (const Vec3f &other); /** \fn void operator*= (const Vec2f other) * \brief multiply the vector by another one. * \param the other vector to be multiplied by. */ void operator *= (const Vec3f &other); /** \fn void operator/= (const Vec2f other) * \brief devide the vector by another one. * \param the other vector to be devided by. */ void operator *= (const float scale); /** \fn void operator/= (const Vec2f other) * \brief divide the vector by another one. * \param the other vector to be devided by. */ void operator /= (const Vec3f &other); /** \fn Vec3f fabs() * \brief return absolute coordinates of the vector. * \return the vector with absolute coordinates. */ Vec3f fabs () const; /** \fn void operator*= (const float scalar) * \brief multiply the vector by a scalar. * \param the scalar to be multiplied by. */ Vec3f operator* (const float scale); /** \fn float computeDist (const Vec3f &other) * \brief compute the distance between the two vectors. * \param the other vector. * \return the distance between the two vectors. */ float computeDist (const Vec3f &other); /** \fn float magnitude () * \brief compute the length of the vector. * \return the length of the vector. */ float magnitude () const; /** \fn float magnSquared () * \brief compute the squared length of the vector. * \return the squared length of the vector. */ float magnSquared (); /** \fn Vec2f normalize () * \brief transform the vector to a vector with a length of 1 and return the resulting vector. * \return the resulting vector. */ Vec3f normalize () const ; /** \fn Vec2f normalize () * \brief transform the vector to a 3D vector by dividing the x, y and z component by the w component. * \return the resulting vector. */ Vec3f normalizeToVec3 () const; /** \fn float dot2 (const Vec3f &other) * \brief compute the dot product between to vectors. (using the first method) * the dot product is the cosinus of the angle between the vector and another one. * the length of the two vectors needs to be equal to 1 before performing the dot product. * \return the dot product between the two vectors. */ float dot3 (const Vec3f &other); float dot2 (const Vec3f &other); /** \fn float dot2 (const Vec3f &other) * \brief get the angle between the vector and another one. * the angle is given in radians and he's always between -2PI and 2PI. * \return the angle between the vectors. */ float dot (const Vec3f &other) const; /** \fn Vec3f cross (const Vec3f &other) * \brief do the cross product and return the resulting vector (The perpendicular to the vector and the other vector.) * \param the other vector. * \return the vector witch is perpendicular to another one. */ Vec3f cross (const Vec3f &other); /** \fn float getAngleBetween (const Vec3f &other, const Vec3f &n) * \brief return the angle between two vectors. (depending of the plane's orientation) * the angle is given in radians and is always between -2PI and 2PI. * \param other : the other vector. * \param n : the orientation of the plane formed by the two vectors. (the normal of the plane) * \return the angle between the two vectors. */ float getAngleBetween (const Vec3f &other, const Vec3f &n); /** \fn float projectOnAxis (const Vec3f &other) * \brief Project an other vector on the vector and return the result. * The projection result is the dot product of the two vectors multiplied by the length * of the other vector. * \return the result of the projection. */ float projOnAxis (const Vec3f &other); /** \fn float* getVec3 () const; * \brief return the vector's components to an array. */ float* getVec3 () const; /** \fn sf::Vector3f getVec3sf () const; * \brief transform the vector to an SFML vector. * \return an SFML vector. */ sf::Vector3f getVec3sf() const; /** \fn std::ostream& operator<< (std::ostream &out, const Vec3f &vec3) * \brief set the vector coordinates to an output stream. * \param &out : the output stream. * \param &vec3 : the vector. * \return the final output stream. */ friend std::ostream& operator<< (std::ostream &out, const Vec3f &vec3); float w; /** < the w component of the vector.*/ }; std::ostream& operator<< (std::ostream &out, const Vec3f &vec4); } #endif
Mais le produit scalaire n'est pas bon il devrait être égal à -0.5 vu que l'angle entre mes 2 vecteurs (qui sont 2 diagonales d'un triangle) est égal à 120° ce qui doit me donner un cosinus de -0.5 hors ceci me donne 0.384616 comme résultat.Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242 #include "../../../include/odfaeg/Math/vec4.h" #include "../../../include/odfaeg/Math/matrix3.h" namespace odfaeg { using namespace std; using namespace sf; const Vec3f Vec3f::xAxis(1.f, 0.f, 0.f); const Vec3f Vec3f::yAxis(0.f, 1.f, 0.f); const Vec3f Vec3f::zAxis(0.f, 0.f, 1.f); ostream& operator<< (ostream &out, const Vec3f &vec3) { out<<"x : "<<vec3.x<<" y : "<<vec3.y<<" z : "<<vec3.z<<" w : "<<vec3.w<<endl; return out; } Vec3f::Vec3f () : Vector3f (0.f, 0.f, 0.f) { w = 1.f; } Vec3f::Vec3f(float x, float y, float z) : Vector3f (x, y, z) { w = 1.f; } Vec3f::Vec3f (float x, float y, float z, float w) : Vector3f(x, y, z) { this->w = w; } void Vec3f::set (float x, float y, float z) { this->x = x; this->y = y; this->z = z; } Vec3f Vec3f::normalizeToVec3 () const { Vector3f vec3 = getVec3sf(); if (w != 0.f) { return Vec3f (vec3.x / w, vec3.y / w, vec3.z / w); } else return *this; } bool Vec3f::isNulVector () const { return x==0 && y==0 && z==0; } Vec3f Vec3f::operator- () const { return Vec3f (-this->x, -this->y, -this->z); } Vec3f Vec3f::operator+ (const Vec3f &other) { Vector3f vec3 = this->getVec3sf() + other.getVec3sf(); return Vec3f (x + other.x, y + other.y, z + other.z); } Vec3f Vec3f::operator- (const Vec3f &other) { sf::Vector3f v1 = this->getVec3sf(); sf::Vector3f v2 = other.getVec3sf(); sf::Vector3f vec3 = v1 - v2; return Vec3f (x - other.x, y - other.y, z - other.z); } Vec3f Vec3f::operator* (const Vec3f &other) { float x = this->x * other.x; float y = this->y * other.y; float z = this->z * other.z; return Vec3f (x, y, z); } Vec3f Vec3f::operator* (const float scale) { sf::Vector3f v1 = this->getVec3sf(); sf::Vector3f vec3 = v1 * scale; return Vec3f (x * scale, y * scale, z * scale); } Vec3f Vec3f::operator/ (const float scale) { sf::Vector3f v1 = this->getVec3sf(); sf::Vector3f vec3 = v1 / scale; return Vec3f (vec3.x, vec3.y, vec3.z); } Vec3f Vec3f::operator/ (const Vec3f &other) { try { if (other.x == 0 || other.y == 0 || other.z == 0) throw Erreur(0, "Division by zero.", 1); else return Vec3f (this->x / other.x, this->y / other.y, this->z / other.z); } catch (Erreur err) { cerr<<err.what()<<endl; } } Vec3f& Vec3f::operator+= (const Vec3f &other) { this->x += other.x; this->y += other.y; this->z += other.z; return *this; } void Vec3f::operator-= (const Vec3f &other) { this->x -= other.x; this->y -= other.y; this->z -= other.z; } void Vec3f::operator*= (const Vec3f &other) { this->x *= other.x; this->y *= other.y; this->z *= other.z; } void Vec3f::operator*= (const float scale) { this->x *= scale; this->y *= scale; this->z *= scale; } void Vec3f::operator/= (const Vec3f &other) { try { if (other.x == 0 || other.y == 0 || other.z == 0) throw Erreur(0, "Division by zero.", 1); else { this->x /= other.x; this->y /= other.y; this->z /= other.z; } } catch (Erreur err) { cerr<<err.what()<<endl; } } Vec3f& Vec3f::operator= (const Vec3f &other) { x = other.x; y = other.y; z = other.z; w = other.w; return *this; } bool Vec3f::operator== (const Vec3f &other) { return x==other.x && y==other.y && z==other.z; } float Vec3f::computeDist (const Vec3f &other) { return Math::sqrt(Math::power(x - other.x, 2) + Math::power(y - other.y, 2) + Math::power(z - other.z, 2)); } float Vec3f::magnitude () const { return Math::sqrt(Math::power(x, 2) + Math::power(y, 2) + Math::power(z, 2)); } float Vec3f::magnSquared () { return Math::power(x, 2) + Math::power(y, 2) + Math::power(z, 2); } Vec3f Vec3f::normalize () const { float length = magnitude(); Vec3f v3f; if (length==0) { v3f.set(0.f, 0.f, 0.f); } else { float x = this->x / length; float y = this->y / length; float z = this->z / length; v3f.set (x, y, z); } return v3f; } float Vec3f::dot2 (const Vec3f &other) { if (isNulVector ()) return 0.f; return x * other.x + y * other.y + z * other.z; } float Vec3f::dot3(const Vec3f other) { Vec3f v (x + other.x, y + other.y, z + other.z); return 0.5f * Math::power(v.magnitude(), 2) - Math::power(magnitude(), 2) - Math::power(other.magnitude(), 2); } float Vec3f::dot (const Vec3f &other) const { if(isNulVector ()) return 0; Vec3f n1 = *this; Vec3f n2 = other; if (n1.magnitude() > 1) n1 = n1.normalize (); if (n2.magnitude () > 1) n2 = n2.normalize (); return n1.x * n2.x + n1.y * n2.y + n1.z * n2.z; } float Vec3f::getAngleBetween (const Vec3f &other, const Vec3f &n) { if(isNulVector() || other.isNulVector()) return 0; float dotProduct = dot(other); Matrix3f matrix (x, y, z, other.x, other.y, other.z, n.x, n.y, n.z); float fDet = matrix.getDet(); if (fDet >= 0) return Math::acosinus(dotProduct); else return -Math::acosinus(dotProduct); } Vec3f Vec3f::cross (const Vec3f &other) { return Vec3f (y * other.z - z * other.y, z * other.x - x * other.z, x * other.y - y * other.x); } float Vec3f::projOnAxis (const Vec3f &other) { Vec3f n1 = normalize(); Vec3f n2 = other.normalize(); float dp = n1.dot(n2); return dp * magnitude(); } Vec3f Vec3f::projOnVector(Vec3f other) { Vec3f proj; float dp = dot(other); proj = *this * dp; return proj; } bool Vec3f::isOpposite (const Vec3f &other) const { if (isNulVector() || other.isNulVector()) return false; if ((x > 0.f && other.x < 0.f) || (x < 0.f && other.x > 0.f) && (y > 0.f && other.y < 0.f) || (y < 0.f && other.y > 0.f) && (z > 0.f && other.z < 0.f) || (z < 0.f && other.z > 0.f)) return true; return false; } float* Vec3f::getVec3 () const { float v[3] = {x, y, z}; return v; } Vector3f Vec3f::getVec3sf () const { return Vector3f(x, y, z); } Vec3f Vec3f::fabs () const { float x = Math::abs(this->x); float y = Math::abs(this->y); float z = Math::abs(this->z); return Vec3f (x, y, z); } float& Vec3f::operator[](int i) { if (i == 0) return x; else if (i == 1) return y; else if (i == 2) return z; else return w; } }
Comment ça se fait ???Code:
1
2
3
4 odfaeg::Vec3f v1 (50, 33.3333, 0); odfaeg::Vec3f v2 (-50, 33.3333, 0); std::cout<<v1.dot(v2)<<std::endl;