[数]昨天欠下的一道立体几何题HDU-4741

时间:2023-02-10 19:25:22

并没有做到这道题,后来听学长说了题意,总之就是立体几何嗯

 

  看了好几份题解,是的我知道是异面线段的距离了,可是看码完全不明orz。

  这时候出现了一份清晰易懂甚至给出了公式来源的blog╰(*°▽°*)╯

  仔细一看是kuangbin的blogΣ(⊙▽⊙"让我先%一%orz

  http://blog.sina.com.cn/s/blog_a401a1ea0101ij9z.html公式Time Tunnel在此

  <!----------这部分是解释给以后看不懂的自己的---------->

       [数]昨天欠下的一道立体几何题HDU-4741(一张简约线条的示意图)

    首先获得两线段的向量(e1,e2),然后叉乘得到垂直于两线段的直线p,p与其中一条线段形成的平面截另一线段于一点,同理得两线段(的延长线)上各一点,则该两点间的距离为两线段最短距离。

    那么一线段指向另一线段的向量AB在p上的投影即为最短距离。

    需要记住的公式  d=|p·AB/p|  交点R1=A+t1·e1  

             t1=((B-A)Xe2)·(e1Xe2)/|e1Xe2|2    t2=((B-A)Xe1)·(e1Xe2)/|e1Xe2| 

  <!-------OVER------->

  那么就放一下最后按照蒟蒻习惯敲的乱码,似乎并不需要求两点距离,所以kuangbin的题解里有dis而蒟蒻偷懒没写

[数]昨天欠下的一道立体几何题HDU-4741[数]昨天欠下的一道立体几何题HDU-4741
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
struct node {
    double x, y, z;
    node(double a=0, double b=0, double c=0) {
        x = a; y = b; z = c;
    }
    node operator + (const node &p) const { return node(x + p.x, y + p.y, z + p.z); }
    node operator - (const node &p) const { return node(x - p.x, y - p.y, z - p.z); }
    double operator * (const node &p) const { return x * p.x + y * p.y + z * p.z; }
    node operator ^ (const node &p) const { return node(y*p.z - z * p.y, z*p.x - x * p.z, x*p.y - y * p.x); }
    node operator * (double p) { return node(x*p, y*p, z*p); }
    node operator / (double p) { return node(x / p, y / p, z / p); }
}A1,B1,A2,B2,poa,pob;

double f(const node &a) { return sqrt(a.x*a.x + a.y*a.y + a.z*a.z); }

int main()
{
    int t;
    cin >> t;
    while (t--) {
        cin >> A1.x >> A1.y >> A1.z >> B1.x >> B1.y >> B1.z >> A2.x >> A2.y >> A2.z >> B2.x >> B2.y >> B2.z;
        node e1 = A1 - B1;
        node e2 = A2 - B2;
        node e3 = A1 - A2;
        node p = e1 ^ e2;
        double d = fabs((A1 - A2)*p / f(p));
        double t1 = ((A2 - A1) ^ e2)*(e1^e2);
        double t2 = ((A2 - A1) ^ e1)*(e1^e2);
        double q = f(e1^e2)*f(e1^e2);
        t1 /= q; t2 /= q;
        poa = A1 + (e1*t1);
        pob = A2 + (e2*t2);
        printf("%.6lf\n", d);
        printf("%.6lf %.6lf %.6lf %.6lf %.6lf %.6lf\n", poa.x, poa.y, poa.z, pob.x, pob.y, pob.z);
    }
    return 0;
}
HDU-4741

 

  注意事项:不太明白重载operator的优先级判断,我选择打括号,并且由于严格按照定义的运算对象,所以数乘的时候数和结构体的位置不能互换。

           //4.16.接收到神仙的补充,优先级和普通的优先级一样,所以最后的poa和pob里的括号是可以去掉的。

       算t1和t2的时候A2,A1的位置会影响结果的正负,反正有样例,试一下好了(实际上是这个懒惰的没有手算样例的人并没有搞清楚为什么)

 

比预计的结束时间晚了二十分钟嘤。