zoukankan      html  css  js  c++  java
  • HDU 4741


    获得 新的模板了/// 此模板 有线段和线段的最短距离方法,同时包含线段与线段的最短距离;
    #include<iostream> #include<stdio.h> #include<cstring> #include<algorithm> #include<cmath> #define eps 1e-10 #define inf 0x1f1f1f1f using namespace std; int dcmp( double a ){ if( abs(a) < eps ) return 0; if(a > 0) return 1;return -1;} struct point{ double x,y,z; point(){} point( double x,double y,double z ):x(x),y(y),z(z){} }; typedef point Vector ; point operator + ( point a,point b ){ return point( a.x+b.x , a.y+b.y , a.z+b.z ); } // 确定一个平面;一般式; struct plane{ double a,b,c,d; plane( double a = 0,double b = 0,double c = 0,double d = 0 ):a(a),b(b),c(c),d(d){} }; point operator - ( point a,point b ){ return point( a.x-b.x , a.y-b.y, a.z-b.z ); } point operator * ( point a,double p ){ return point( a.x*p , a.y*p , a.z*p ); } point operator / ( point a,double p ){ return point( a.x/p , a.y/p , a.z/p ); } bool operator == ( point a,point b ){ if( dcmp(a.x-b.x) == 0&& dcmp(a.y-b.y) == 0 && dcmp(a.z-b.z) == 0 )return 1; return 0; } double Dot( point a,point b ){ return a.x*b.x + a.y*b.y + a.z*b.z; } double Length( point a ){ return sqrt(Dot(a,a));} double Angle( point a,point b ){ return acos(Dot(a,b))/Length(a)/Length(b); } // 点到 平面p0 - n 的距离;n 必须为单位向量 n 是平面法向量 double p_po_n( const point &p,const point &po,const point n ){ return abs(Dot( p-po,n )); } // 点在 平面p0 - n 的投影 ; n 必须为单位向量 n 是平面法向量 point p_po_n_jec( const point &p,const point &p0,const point &n ){ return p-n*Dot( p-p0,n ); } // 直线p1 p2 在平面 p0 - n 的交点,假设交点存在;唯一 point p_p_p( point p1,point p2,point p0,point n ){ point v = p2 - p1; double t = ( Dot(n,p0-p1)/Dot(n,p2-p1) ); return p1 + v*t; } point cross( point a,point b ){ return point( a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z,a.x*b.y - a.y*b.x ); } double area( point a,point b,point c ){ return Length(cross(b-a,c-a)); } double dis_to_line( point p, point a,point b ){ point v1 = b-a, v2 = p-a; return Length( cross(v1,v2)/Length(v1) ); } // p 到 ab 线段的距离 double dis_to_segm( point p,point a,point b ){ if( a == b )return Length(p-a); point v1 = b-a, v2 = p-a, v3 = p-b; if( dcmp( Dot(v1,v2) ) < 0 ) return Length(v2); else if( dcmp( Dot(v1,v3) ) > 0 ) return Length(v3); else return Length(cross(v1,v2))/Length(v1); } // 四面体的体积 double dis_l_to_l( point a,point b,point lt,point rt ) { while( abs(rt.x - lt.x) > eps || abs(rt.y - lt.y) > eps || abs( rt.z - lt.z) > eps ) { point temp; temp = lt + ( rt - lt )/3.0; point now; now = lt + ( rt - lt )/3.0*2.0; if( dis_to_segm(temp,a,b) < dis_to_segm(now,a,b) ) rt = now; else lt = temp; } return dis_to_segm( rt,a,b ); } // 获取平面 a*x + b*y + c*z + d; 由;两个向量 和 一个平面一个点确定一个平面 plane get_plane( Vector a,Vector b,point c ) { Vector p = cross( a,b ); // 由平面两个向量 可以确定平面法向量; double d = ( p.x*c.x + p.y*c.y + p.z*c.z)*-1; return plane( p.x,p.y,p.z,d ); } // 获取 直线与平面的交点; point get_point( plane p,point c,point d ) { Vector v = c - d; double t = p.a*c.x+p.b*c.y + p.c*c.z + p.d ; double s = p.a*(d.x - c.x) + p.b*(d.y-c.y) + p.c*(d.z - c.z); double k = t/s; return c + v*k; } point A[5]; int main( ) { int T; scanf("%d",&T); while( T-- ) { for( int i = 1; i <= 4; i++ ) scanf("%lf %lf %lf",&A[i].x,&A[i].y,&A[i].z); Vector v1 = A[2] - A[1]; Vector v2 = A[4] - A[3]; Vector v3 = cross( v1,v2 ); // 获取公垂线; plane a1 = get_plane( v1,v3,A[1] ); // 两个向量 和一个点 确定一个平面; plane a2 = get_plane( v2,v3,A[3] ); point p1 = get_point( a1,A[4],A[3] ); // 获取交点; point p2 = get_point( a2,A[1],A[2] ); printf("%.6lf ",Length(p1-p2)); printf("%.6lf %.6lf %.6lf %.6lf %.6lf %.6lf ",p2.x,p2.y,p2.z,p1.x,p1.y,p1.z); } return 0; }

      

  • 相关阅读:
    最长上升序列,首尾连接
    带权并查集&&并查集
    开发者的小天地-1
    Binary Tree Maximum Path Sum
    Linked List Cycle II
    动归熟手题单
    java 正则表达式-忽略大小写与多行匹配
    KO之tab栏切换
    Vue中通过属性绑定为元素绑定style
    Vue中通过属性绑定为元素设置class
  • 原文地址:https://www.cnblogs.com/wulangzhou/p/3326187.html
Copyright © 2011-2022 走看看