Space Junk

本文介绍了一种计算三维空间中两个移动球体何时发生碰撞的方法,通过建立并求解一个关于时间t的二次方程来确定碰撞时刻。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Space Junk

这里写图片描述
.
.
题意:给出两个球三位位置,半径以及速度向量,问什么时候能相撞。
.
.
解法:很明显这是一个不等式方程:
(X1+VX1tX2VX2t)2+(Y1+VY1tY2VY2t)2+(Z1+VZ1tZ2VZ2t)2Z<=r1+r2
然后这条式子两边平方解除t出来就好了。
.
.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

const double eps = 1e-8;
double a, b, c, X1, Y1, z1, X2, Y2, z2;
double vX1, vX2, vY1, vY2, vz1, vz2, r1, r2, t;

double sqr(double X) {
    return X*X;
}

double check(double a, double b, double c) {
    if (fabs(a) < eps) {
        if (fabs(b) < eps) {
            if (fabs(c) < eps) return 0;
            else return -1;
        }
        if ((-c)*b > -eps) return (-c)/b;
        else return -1;
    }
    if (sqr(b)-4*a*c < -eps) return -1;
    if ((-b+sqrt(fabs(sqr(b)-4*a*c)))/(2*a) < -eps) return -1;
    if ((-b-sqrt(fabs(sqr(b)-4*a*c)))/(2*a) < -eps)
        return (-b+sqrt(fabs(sqr(b)-4*a*c)))/(2*a);
    else return (-b-sqrt(fabs(sqr(b)-4*a*c)))/(2*a);
}

int main() {
    int tt;
    scanf("%d", &tt);
    while (tt--) {
        scanf("%lf %lf %lf %lf %lf %lf %lf", &X1, &Y1, &z1, &r1, &vX1, &vY1, &vz1);
        scanf("%lf %lf %lf %lf %lf %lf %lf", &X2, &Y2, &z2, &r2, &vX2, &vY2, &vz2);

        if (sqrt(sqr(X1-X2)+sqr(Y1-Y2)+sqr(z1-z2)) - (r1+r2) < eps) {
            printf("0.000\n");
            continue;
        }

        a = sqr(vX1-vX2)+sqr(vY1-vY2)+sqr(vz1-vz2);
        b = 2*((vX1-vX2)*(X1-X2)+(vY1-vY2)*(Y1-Y2)+(vz1-vz2)*(z1-z2));
        c = sqr(X1-X2)+sqr(Y1-Y2)+sqr(z1-z2)-sqr(r1+r2);
        t = check(a, b, c);
        if (fabs(t+1) < eps) printf("No collision\n");
        else printf("%.3lf\n", fabs(t));
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值