下午在vj的训练赛考到了又裸又板的三维向量旋转,赛时为了方便直接封了一个板子出来,现进行一个板子的贴:
题目翻译
给定三维空间中的两点 ((A, B, C)) 和 ((x, y, z))。设 (L) 为通过点 ((A, B, C)) 和原点 ((0, 0, 0)) 的直线。将点 ((x, y, z)) 绕着直线 (L) 旋转 (r) 度和 (-r) 度,会得到两个点 (P) 和 (Q)。如果点 (P) 的 (z) 坐标大于 (Q) 的 (z) 坐标,则输出点 (P);否则,输出点 (Q)。保证解是唯一的。
罗德里格公式简介
罗德里格旋转公式(Rodrigues' rotation formula)是一种用于描述一个向量绕着固定轴旋转的方法。在三维空间中,它可以用来计算一个向量绕某个轴旋转一定角度后的新坐标。该公式在计算机图形学、物理学和工程学中有广泛应用。GPT
假设有一个向量 (\mathbf{v}),它绕一个单位向量 (\mathbf{k}) 旋转一个角度 (\theta) 后得到的新向量 (\mathbf{v}')。罗德里格旋转公式如下:
公式描述
罗德里格旋转公式用于计算一个向量绕固定轴旋转后的新向量。假设有一个向量 (\mathbf{v}),它绕一个单位向量 (\mathbf{k}) 旋转一个角度 (\theta) 后得到的新向量 (\mathbf{v}')。罗德里格旋转公式如下:
$$\mathbf{v}' = \mathbf{v} \cos \theta + (\mathbf{k} \times \mathbf{v}) \sin \theta + \mathbf{k} (\mathbf{k} \cdot \mathbf{v}) (1 - \cos \theta)$$
其中:
- (\mathbf{v}) 是要旋转的向量。
- (\mathbf{k}) 是旋转轴的单位向量。
- (\theta) 是旋转角度。
- (\mathbf{k} \times \mathbf{v}) 表示 (\mathbf{k}) 和 (\mathbf{v}) 的叉积。
- (\mathbf{k} \cdot \mathbf{v}) 表示 (\mathbf{k}) 和 (\mathbf{v}) 的点积。
代码
模板部分
class Vector
{
public:
double x, y, z;
const double pi = acos(-1.0);
double dot(const Vector& A, const Vector& B)
{
return A.x * B.x + A.y * B.y + A.z * B.z;
}
Vector cross(const Vector& A, const Vector& B)
{
return Vector(A.y * B.z - A.z * B.y, A.z * B.x - A.x * B.z, A.x * B.y - A.y * B.x);
}
Vector to_unit(const Vector& A)
{
double len = sqrt(dot(A, A));
return Vector(A / len);
}
Vector rotate(const Vector& Uni, const Vector& A, double rad)
{
return A * cos(rad) + Uni * dot(Uni, A) * (1 - cos(rad)) + cross(Uni, A) * sin(rad);
}
double rad_to_deg(double rad)
{
return rad * 180 / pi;
}
double deg_to_rad(double deg)
{
return deg * pi / 180;
}
Vector(double x = 0, double y = 0, double z = 0) : x(x), y(y), z(z) {}
Vector operator+(const Vector& B) const
{
return Vector(x + B.x, y + B.y, z + B.z);
}
Vector operator-(const Vector& B) const
{
return Vector(x - B.x, y - B.y, z - B.z);
}
Vector operator*(double p) const
{
return Vector(x * p, y * p, z * p);
}
Vector operator/(double p) const
{
return Vector(x / p, y / p, z / p);
}
bool operator<(const Vector& B) const
{
if (x == B.x)
{
if (y == B.y)
return z < B.z;
return y < B.y;
}
return x < B.x;
}
}; 完整代码
#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;
#define int long long
#define endl '\n'
#define ULL unsigned long long
#define xx first
#define yy second
#define PII pair
const int MAXN = 1e6 + 10;
const int MOD = 998244353;
const int mod = 1e9 + 7;
const double eps = 1e-8;
int _x[] = { 1,-1,0,0 };
int _y[] = { 0,0,1,-1 };
int arr[MAXN];
class Vector
{
public:
double x, y, z;
const double pi = acos(-1.0);
double dot(const Vector& A, const Vector& B)
{
return A.x * B.x + A.y * B.y + A.z * B.z;
}
Vector cross(const Vector& A, const Vector& B)
{
return Vector(A.y * B.z - A.z * B.y, A.z * B.x - A.x * B.z, A.x * B.y - A.y * B.x);
}
Vector to_unit(const Vector& A)
{
double len = sqrt(dot(A, A));
return Vector(A / len);
}
Vector rotate(const Vector& Uni, const Vector& A, double rad)
{
return A * cos(rad) + Uni * dot(Uni, A) * (1 - cos(rad)) + cross(Uni, A) * sin(rad);
}
double rad_to_deg(double rad)
{
return rad * 180 / pi;
}
double deg_to_rad(double deg)
{
return deg * pi / 180;
}
Vector(double x = 0, double y = 0, double z = 0) : x(x), y(y), z(z) {}
Vector operator+(const Vector& B) const
{
return Vector(x + B.x, y + B.y, z + B.z);
}
Vector operator-(const Vector& B) const
{
return Vector(x - B.x, y - B.y, z - B.z);
}
Vector operator*(double p) const
{
return Vector(x * p, y * p, z * p);
}
Vector operator/(double p) const
{
return Vector(x / p, y / p, z / p);
}
bool operator<(const Vector& B) const
{
if (x == B.x)
{
if (y == B.y)
return z < B.z;
return y < B.y;
}
return x < B.x;
}
};
signed main(void)
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--)
{
double a, b, c, x, y, z, r;
cin >> a >> b >> c >> x >> y >> z >> r;
Vector A(a, b, c), B(x, y, z);
Vector Uni = Vector().to_unit(A);
Vector End1 = Vector().rotate(Uni, B, Vector().deg_to_rad(r));
Vector End2 = Vector().rotate(Uni, B, -Vector().deg_to_rad(r));
Vector Ans = End1.z > End2.z ? End1 : End2;
cout << fixed << setprecision(9) << Ans.x << " " << Ans.y << " " << Ans.z << endl;
}
return 0;
}
···
2025年10月新盘 做第一批吃螃蟹的人coinsrore.com
新车新盘 嘎嘎稳 嘎嘎靠谱coinsrore.com
新车首发,新的一年,只带想赚米的人coinsrore.com
新盘 上车集合 留下 我要发发 立马进裙coinsrore.com
做了几十年的项目 我总结了最好的一个盘(纯干货)coinsrore.com
新车上路,只带前10个人coinsrore.com
新盘首开 新盘首开 征召客户!!!coinsrore.com
新项目准备上线,寻找志同道合的合作伙伴coinsrore.com
新车即将上线 真正的项目,期待你的参与coinsrore.com
新盘新项目,不再等待,现在就是最佳上车机会!coinsrore.com
新盘新盘 这个月刚上新盘 新车第一个吃螃蟹!coinsrore.com
2025年10月新盘 做第一批吃螃蟹的人coinsrore.com
新车新盘 嘎嘎稳 嘎嘎靠谱coinsrore.com
新车首发,新的一年,只带想赚米的人coinsrore.com
新盘 上车集合 留下 我要发发 立马进裙coinsrore.com
做了几十年的项目 我总结了最好的一个盘(纯干货)coinsrore.com
新车上路,只带前10个人coinsrore.com
新盘首开 新盘首开 征召客户!!!coinsrore.com
新项目准备上线,寻找志同道合的合作伙伴coinsrore.com
新车即将上线 真正的项目,期待你的参与coinsrore.com
新盘新项目,不再等待,现在就是最佳上车机会!coinsrore.com
新盘新盘 这个月刚上新盘 新车第一个吃螃蟹!coinsrore.com