标签:flag clu alpha ack efi 一个 def roo vector
有一个球是障碍物不能走,给你两个点,从起点到终点的最短路程是多少
求出切线,于是路径为两条直线加一个弧段
#include <bits/stdc++.h>
using namespace std;
#define int long long
vector<double> solve_equ(double a, double b, double c)
{
double delta = b * b - 4 * a * c;
if (delta < 0)
return {};
double sqrt_delta = sqrt(delta + 1e-10);
return {(-b + sqrt_delta) / a / 2, (-b - sqrt_delta) / a / 2};
}
struct vec3
{
double x, y, z;
void read()
{
cin >> x >> y >> z;
}
vec3 operator+(const vec3 &rhs)
{
return {x + rhs.x, y + rhs.y, z + rhs.z};
}
vec3 operator-(const vec3 &rhs)
{
return {x - rhs.x, y - rhs.y, z - rhs.z};
}
double operator*(const vec3 &rhs)
{
return x * rhs.x + y * rhs.y + z * rhs.z;
}
vec3 operator*(const double &rhs)
{
return {x * rhs, y * rhs, z * rhs};
}
double dist(const vec3 &rhs)
{
return sqrt((*this - rhs) * (*this - rhs));
}
};
void solve()
{
vec3 o, s, t, d;
o.read();
double r;
cin >> r;
s.read();
t.read();
d = t - s;
double a = d * d;
double b = d * (s - o) * 2;
double c = (s - o) * (s - o) - r * r;
auto roots = solve_equ(a, b, c);
int flag = (s.dist(o) >= r) || (t.dist(o) >= r);
double x = o.dist(s);
double y = o.dist(t);
double z = s.dist(t);
double p = (x + y + z) / 2;
double h = sqrt(p * (p - x) * (p - y) * (p - z)) * 2 / z;
if (x * x >= y * y + z * z || y * y >= x * x + z * z || h >= r)
{
cout << fixed << setprecision(10) << s.dist(t) << endl;
}
else
{
vector<vec3> hit_points;
for (auto i : roots)
{
hit_points.push_back(s + d * i);
}
double l = hit_points[0].dist(hit_points[1]);
double alpha = acos(r / x);
double belta = acos(r / y);
double gamma = acos((x * x + y * y - z * z) / 2 / x / y);
double theta = gamma - alpha - belta;
double ans = r * theta + sqrt(x * x - r * r) + sqrt(y * y - r * r);
cout << fixed << setprecision(10) << ans << endl;
}
}
signed main()
{
ios::sync_with_stdio(false);
int t;
cin >> t;
while (t--)
solve();
}
[ICPC2018西安F] Interstellar … Fantasy - 几何
标签:flag clu alpha ack efi 一个 def roo vector
原文地址:https://www.cnblogs.com/mollnn/p/14591205.html