2021东北省赛 J. Transform(计算几何 + 罗德里格斯旋转公式)

链接 J. Transform

题意

给出两个点求第二个点绕从原点到第一个点这条轴旋转 r r r − r -r r ,得到两个点,输出 z z z 坐标最大的那个点;

思路

刚开始想的旋转坐标轴,然后旋转点,再旋转回去,过于复杂了;
这个题用 罗德里格斯旋转公式 可以直接秒
v ′ ⃗ = v ⃗ + s i n θ ∗ k ⃗ × v ⃗ + ( 1 − c o s θ ) ∗ k ⃗ × ( k ⃗ × v ⃗ ) \vec{v'}=\vec{v} + sin\theta*\vec{k}\times\vec{v} + (1-cos\theta) * \vec{k} \times(\vec{k}\times\vec{v}) v =v +sinθk ×v +(1cosθ)k ×(k ×v )

罗德里格斯旋转公式具体证明可以看大佬博客QWQ

AC代码

#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <map>
#include <vector>
#include <queue>

#define x first
#define y second

using namespace std;

typedef long long ll;
typedef pair <int,int> PII;
const int N = 4000010;
const ll mod = 998244353;
const double pi = 3.1415926535897932;
const double eps = 1e-10;

int T;
double A, B, C, x, y, z, r; 
struct Point{
	double a, b, c;
	Point (double aa, double bb, double cc) {
		a = aa, b = bb, c = cc;
	}
};

Point operator +(Point a, Point b) {
	return Point(a.a + b.a, a.b + b.b, a.c + b.c);
}

Point operator *(Point a, double u) {
	return Point(a.a * u, a.b * u, a.c * u);
}

double operator *(Point a, Point b) {
	return a.a * b.a + a.b * b.b + a.c * b.c;
}

Point operator ^(Point a, Point b) {
	return Point(a.b * b.c - b.b * a.c, a.c * b.a - b.c * a.a, a.a * b.b - a.b * b.a);
}

double get_dist(Point a) {
	return sqrt(a.a * a.a + a.b * a.b + a.c * a.c);
}
int dcmp(double x, double y)
{
    if (fabs(x - y) < eps) return 0;
    if (x < y) return -1;
    return 1;
}

Point get_v(Point k, Point a, double angle) {
	double co = cos(angle), si = sin(angle);
	return a + ((k * si) ^ a) + ((k * (1 - co)) ^ (k ^ a));
}

int main()
{
	cin >> T;
	while (T --) {
		cin >> A >> B >> C >> x >> y >> z >> r;
		Point k = Point(A, B, C);
		r = r / 180 * pi;
		double res = get_dist(k);
		k = Point(A / res, B / res, C / res);
		Point v = {x, y, z};
		Point x = get_v(k, v, r);
		Point y = get_v(k, v, -r);
		if (dcmp(x.c, y.c) == 1) printf("%.8lf %.8lf %.8lf\n", x.a, x.b, x.c);
		else printf("%.8lf %.8lf %.8lf\n", y.a, y.b, y.c);
	}
	
	return 0;
}

——END

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

半碗无糖蓝莓冻

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值