跳转至

杂题(1)

求三维空间上两个圆面的交线的长度

Code

输入是两个圆面的半径,圆形、法向量

C++
// Problem: H - Circle Intersection
// Contest: Virtual Judge - 湖南省第十七届大学生计算机程序设计竞赛(HNCPC2021) [Cloned]
// URL: https://vjudge.net/contest/577909#problem/H
// Memory Limit: 128 MB
// Time Limit: 1000 ms
#include <bits/stdc++.h>
using namespace std;
// 2023 OneWan
{ 基础计算几何 }
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    Point3D A, C;
    Vector3D B, D;
    Tdouble R1, R2;
    while (cin >> R1 >> A >> B) {
        cin >> R2 >> C >> D;
        Vector3D G = cross(B, D);
        Line3D v = getPlaneIntersection(Line3D(A, B), Line3D(C, D));
        if (sgn(distanceLine(A, v) - R1) > 0 || sgn(distanceLine(C, v) - R2) > 0) {
            cout << 0 << "\n";
            continue;
        }
        Line3D C1(A, cross(v.v, B));
        Point3D mid1 = getLineIntersection(C1, v);
        Tdouble d1 = (A - mid1).length();
        Vector3D t1 = v.v * (sqrt(R1 * R1 - d1 * d1) / v.v.length());
        Point3D p1 = mid1 + t1;
        Point3D p2 = mid1 - t1;
        Line3D C2(C, cross(v.v, D));
        Point3D mid2 = getLineIntersection(C2, v);
        Tdouble d2 = (C - mid2).length();
        Vector3D t2 = v.v * (sqrt(R2 * R2 - d2 * d2) / v.v.length());
        Point3D p3 = mid2 + t2;
        Point3D p4 = mid2 - t2;
        Tdouble res = 0.0;
        if (sgn(dot(p1 - p3, p1 - p4)) <= 0) {
            res = min(distance(p1, p2), distance(p1, p4));
        } else if (sgn(dot(p2 - p3, p2 - p4)) <= 0) {
            res = min(distance(p2, p1), distance(p2, p3));
        } else if (sgn(dot(p3 - p1, p3 - p2)) <= 0) {
            res = min(distance(p3, p4), distance(p3, p2));
        } else if (sgn(dot(p4 - p1, p4 - p2)) <= 0) {
            res = min(distance(p4, p3), distance(p4, p1));
        }
        if (sgn(res) <= 0) cout << 0 << "\n";
        else cout << fixed << setprecision(8) << res << "\n";
    }
    return 0;
}