Skip to content

Instantly share code, notes, and snippets.

@jin-x
Last active February 27, 2022 10:07
Show Gist options
  • Save jin-x/9990655e64196117cde063ff29dc653f to your computer and use it in GitHub Desktop.
Save jin-x/9990655e64196117cde063ff29dc653f to your computer and use it in GitHub Desktop.
Трёхкомпонентный вектор
#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