HDU 4741

求异面直线距离及公垂线

公式转自:http://blog.csdn.net/zhengnanlee/article/details/11870595  (求公垂线)

两条直线:

构造方程:

求出公垂线向量:

记公垂线和l1形成的平面为alpha,下面求它:

令:

联立:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>

using namespace std;

struct point {
	double x,y,z;
};
struct line{
	point a,b;
};
point a,b,c,d;
point vectical;
point A,B;
point operator - (const point &x, const point &y){
	point t;
	t.x=x.x-y.x; t.y=x.y-y.y; t.z=x.z-y.z;
	return t;
}

point Xmulti(point u,point v){
	point t;
	t.x=u.y*v.z-v.y*u.z; t.y=u.z*v.x-u.x*v.z; t.z=u.x*v.y-u.y*v.x;
	return t;
}

double dmulti(point &u,point &v){
	return u.x*v.x+u.y*v.y+u.z*v.z;
}
double len(point s){
	return s.x*s.x+s.y*s.y+s.z*s.z;
}

int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		scanf("%lf%lf%lf",&a.x,&a.y,&a.z);
		scanf("%lf%lf%lf",&b.x,&b.y,&b.z);
		scanf("%lf%lf%lf",&c.x,&c.y,&c.z);
		scanf("%lf%lf%lf",&d.x,&d.y,&d.z);
		vectical=Xmulti(b-a,d-c);
		point tt=c-a;
		double ans=fabs(dmulti(tt,vectical)/sqrt(len(vectical)));
        double H = b.x - a.x, I = b.y - a.y, J = b.z - a.z;
        double K = d.x - c.x, L = d.y - c.y, M = d.z - c.z;
        double N = H * I * L - I * I * K - J * J * K + H * J * M;
        double O = H * H * L - H * I * K - I * J * M + J * J * L;
        double P = H * J * K - H * H * M - I * I * M + I *J * L;
        double Q = -a.x * N + a.y * O - a.z * P;
        double k = (O * c.y - N * c.x - P * c.z - Q) / (N * K - O * L + P * M);
        A.x=K * k + c.x; A.y=L * k + c.y; A.z=M * k + c.z;
        swap(a, c);
        swap(b, d);
        H = b.x - a.x, I = b.y - a.y, J = b.z - a.z;
        K = d.x - c.x, L = d.y - c.y, M = d.z - c.z;
        N = H * I * L - I * I * K - J * J * K + H * J * M;
        O = H * H * L - H * I * K - I * J * M + J * J * L;
        P = H * J * K - H * H * M - I * I * M + I *J * L;
        Q = -a.x * N + a.y * O - a.z * P;
        k = (O * c.y - N * c.x - P * c.z - Q) / (N * K - O * L + P * M);
        B.x=K * k + c.x; B.y=L * k + c.y; B.z=M * k + c.z;
		printf("%.6lf\n",ans);
		printf("%.6lf %.6lf %.6lf %.6lf %.6lf %.6lf\n",B.x,B.y,B.z,A.x,A.y,A.z);
	}
	return 0;
}

  

HDU 4741

时间: 2024-11-08 20:10:48

HDU 4741的相关文章

hdu 4741 Save Labman No.004异面直线间的距离既构成最小距离的两个端点

Save Labman No.004 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1473    Accepted Submission(s): 484 Problem Description Due to the preeminent research conducted by Dr. Kyouma, human beings ha

HDU 4741 Save Labman No.004

题意:求空间两线的最短距离和最短线的交点 题解: 线性代数和空间几何,主要是用叉积,点积,几何. 知道两个方向向量s1,s2,求叉积可以得出他们的公共垂直向量,然后公共垂直向量gamma和两线上的点形成的向量做内积, 在除掉gamma的长度就得到投影,即是最短距离. 然后求两个点可以用gamma和s2的叉积和l2上的一个点描述一个平面,再求平面和线的交点, 把(p2-p1)*n 和(p0-p1)*n相除算出比例乘上p2-p1得到交点和p1的差,再加上p1就求出交点了 学习点:计算几何的一些东西

hdu 4741 2013杭州赛区网络赛 dfs ***

起点忘记录了,一直wa 代码写的很整齐,看着很爽 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 #include<map> 8 using namespace std; 9 #define MOD 1000000007 10 con

hdu 1175 连连看(模拟循环队列)

连连看 Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 18149    Accepted Submission(s): 4741 Problem Description "连连看"相信很多人都玩过.没玩过也没关系,下面我给大家介绍一下游戏规则:在一个棋盘中,放了很多的棋子.如果某两个相同的棋子,可以通过一条线连起来(这条

HDU 6203 ping ping ping [LCA,贪心,DFS序,BIT(树状数组)]

题目链接:[http://acm.hdu.edu.cn/showproblem.php?pid=6203] 题意 :给出一棵树,如果(a,b)路径上有坏点,那么(a,b)之间不联通,给出一些不联通的点对,然后判断最少有多少个坏点. 题解 :求每个点对的LCA,然后根据LCA的深度排序.从LCA最深的点对开始,如果a或者b点已经有点被标记了,那么continue,否者标记(a,b)LCA的子树每个顶点加1. #include<Bits/stdc++.h> using namespace std;

HDU 5542 The Battle of Chibi dp+树状数组

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5542 题意:给你n个数,求其中上升子序列长度为m的个数 可以考虑用dp[i][j]表示以a[i]结尾的长度为j的上升子序列有多少 裸的dp是o(n2m) 所以需要优化 我们可以发现dp的第3维是找比它小的数,那么就可以用树状数组来找 这样就可以降低复杂度 #include<iostream> #include<cstdio> #include<cstring> #include

hdu 1207 汉诺塔II (DP+递推)

汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4529    Accepted Submission(s): 2231 Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往

[hdu 2102]bfs+注意INF

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2102 感觉这个题非常水,结果一直WA,最后发现居然是0x3f3f3f3f不够大导致的--把INF改成INF+INF就过了. #include<bits/stdc++.h> using namespace std; bool vis[2][15][15]; char s[2][15][15]; const int INF=0x3f3f3f3f; const int fx[]={0,0,1,-1};

HDU 3555 Bomb (数位DP)

数位dp,主要用来解决统计满足某类特殊关系或有某些特点的区间内的数的个数,它是按位来进行计数统计的,可以保存子状态,速度较快.数位dp做多了后,套路基本上都差不多,关键把要保存的状态给抽象出来,保存下来. 简介: 顾名思义,所谓的数位DP就是按照数字的个,十,百,千--位数进行的DP.数位DP的题目有着非常明显的性质: 询问[l,r]的区间内,有多少的数字满足某个性质 做法根据前缀和的思想,求出[0,l-1]和[0,r]中满足性质的数的个数,然后相减即可. 算法核心: 关于数位DP,貌似写法还是