Last active
February 27, 2022 10:07
-
-
Save jin-x/9990655e64196117cde063ff29dc653f to your computer and use it in GitHub Desktop.
Трёхкомпонентный вектор
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cmath> | |
#include <ostream> | |
// Трёхкомпонентный вектор | |
struct vec3 | |
{ | |
double x, y, z; | |
// Длина вектора | |
double length() const { | |
return std::sqrt(dot(*this)); | |
} | |
// Нормализовать вектор | |
void normalize() { | |
*this *= 1 / length(); | |
} | |
// Скалярное произведение | |
double dot(const vec3& b) const { | |
return x*b.x + y*b.y + z*b.z; | |
} | |
// Повернуть вектор вокруг b на угол t | |
void turn_around(const vec3& b, const double t) { | |
turn_around_sin(b, std::sin(t)); | |
} | |
// Повернуть вектор вокруг b на угол, синус которого равен sin_t | |
void turn_around_sin(vec3 b, const double sin_t) { | |
const double cos_t = std::sqrt(1 - sin_t*sin_t); | |
b.normalize(); | |
*this = { | |
(cos_t+(1-cos_t)*b.x*b.x)*x + ((1-cos_t)*b.x*b.y-sin_t*b.z)*y + ((1-cos_t)*b.x*b.z+sin_t*b.y)*z, | |
((1-cos_t)*b.y*b.x+sin_t*b.z)*x + (cos_t+(1-cos_t)*b.y*b.y)*y + ((1-cos_t)*b.y*b.z-sin_t*b.x)*z, | |
((1-cos_t)*b.z*b.x-sin_t*b.y)*x + ((1-cos_t)*b.z*b.y+sin_t*b.x)*y + (cos_t+(1-cos_t)*b.z*b.z)*z | |
}; | |
} | |
// Векторное произведение | |
vec3& operator*=(const vec3& b); | |
// Умножение на число | |
vec3& operator*=(const double n); | |
}; // vec3 | |
// Произведения | |
vec3 operator*(const vec3& a, const vec3& b) | |
{ | |
return { a.y*b.z - b.y*a.z, a.z*b.x - b.z*a.x, a.x*b.y - b.x*a.y }; | |
} | |
vec3 operator*(const vec3& a, const double n) | |
{ | |
return { a.x*n, a.y*n, a.z*n }; | |
} | |
vec3& vec3::operator*=(const vec3& b) | |
{ | |
*this = *this * b; | |
return *this; | |
} | |
vec3& vec3::operator*=(const double n) | |
{ | |
*this = *this * n; | |
return *this; | |
} | |
// Сравнение векторов | |
bool operator==(const vec3& a, const vec3& b) | |
{ | |
return (a.x == b.x && a.y == b.y && a.z == b.z); | |
} | |
bool operator!=(const vec3& a, const vec3& b) | |
{ | |
return !(a == b); | |
} | |
// Вывод вектора в поток | |
std::ostream& operator<<(std::ostream& str, const vec3& a) | |
{ | |
str << "{ " << a.x << ", " << a.y << ", " << a.z << " }"; | |
return str; | |
} | |
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
#include <iostream> | |
using std::cout; | |
using std::endl; | |
void test1() | |
{ | |
cout << "TEST1:" << endl; | |
vec3 a = { 0, 0, 1 }; | |
vec3 b = { 0.3, 0.5, 0.7 }; | |
b.normalize(); | |
cout << "a = " << a << endl; | |
cout << "b = " << b << endl; | |
vec3 c = a * b; | |
double sin_t = c.length(); | |
cout << "a * b = " << c << endl; | |
cout << "sin_t = " << sin_t << endl; | |
a.turn_around_sin(c, sin_t); | |
cout << std::fixed; | |
cout << "turn a (sin_t) = " << a << endl; | |
a.turn_around_sin(c, -sin_t); | |
cout << "turn a (-sin_t) = " << a << endl; | |
} | |
void test2() | |
{ | |
cout << "TEST2:" << endl; | |
vec3 a = { 2, 3, 4 }; | |
vec3 b = { 0, 0, 1 }; | |
vec3 b1 = { 1, 0, 0 }; | |
// b.normalize(); | |
// b1.normalize(); | |
cout << "a = " << a << endl; | |
cout << "b = " << b << endl; | |
cout << "b1 = " << b1 << endl; | |
vec3 bn = b * b1; | |
double sin_t = bn.length(); | |
cout << "b * b1 = " << bn << endl; | |
cout << "sin_t = " << sin_t << endl; | |
a.turn_around_sin(bn, sin_t); | |
cout << std::fixed; | |
cout << "turn a (sin_t) = " << a << endl; | |
a.turn_around_sin(bn, -sin_t); | |
cout << "turn a (-sin_t) = " << a << endl; | |
} | |
int main() | |
{ | |
test1(); | |
cout << endl; | |
test2(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment