hdu 4741 Save Labman No.004 计算几何

直接贴模版!!!

求异面直线的距离及坐标!!

代码如下:

 

  1 #include<iostream>
  2 #include<stdio.h>
  3 #include<algorithm>
  4 #include<iomanip>
  5 #include<cmath>
  6 #include<cstring>
  7 #include<vector>
  8 #define I(p) scanf("%lf%lf%lf",&p.x,&p.y,&p.z)
  9 #define eps 1e-20
 10 #define zero(x) (((x)>0?(x):-(x))<eps)
 11 using namespace std;
 12 struct point
 13 {
 14       double x,y,z;
 15       point operator+(point a)
 16       {
 17             point c;
 18             c.x=x+a.x;
 19             c.y=y+a.y;
 20             c.z=z+a.z;
 21             return c;
 22       }
 23 };
 24 struct line{point a,b;}l1,l2;
 25 struct plane
 26 {
 27       point a,b,c;
 28       plane(point _a,point _b,point _c)
 29       {
 30             a=_a;
 31             b=_b;
 32             c=_c;
 33       }
 34 };
 35 point xmult(point u,point v)
 36 {
 37       point ret;
 38       ret.x=u.y*v.z-v.y*u.z;
 39       ret.y=u.z*v.x-u.x*v.z;
 40       ret.z=u.x*v.y-u.y*v.x;
 41       return ret;
 42 }
 43 double dmult(point u,point v)
 44 {
 45       return u.x*v.x+u.y*v.y+u.z*v.z;
 46 }
 47 point subt(point u,point v)
 48 {
 49       point ret;
 50       ret.x=u.x-v.x;
 51       ret.y=u.y-v.y;
 52       ret.z=u.z-v.z;
 53       return ret;
 54 }
 55 //取平面法向量
 56 
 57 point  pvec(plane s)
 58 {
 59 
 60     return  xmult(subt(s.a,s.b),subt(s.b,s.c));
 61 
 62 }
 63 
 64 point  pvec(point  s1,point  s2,point  s3)
 65 {
 66     return  xmult(subt(s1,s2),subt(s2,s3));
 67 
 68 }
 69 
 70 double vlen(point p)
 71 {
 72       return sqrt(p.x*p.x+p.y*p.y+p.z*p.z);
 73 }
 74 double distances(point p1,point p2)
 75 {
 76       return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)+(p1.z-p2.z)*(p1.z-p2.z));
 77 }
 78 
 79 //判两直线平行
 80 
 81 int parallel(line u,line v)
 82 {
 83 
 84     return vlen(xmult(subt(u.a,u.b),subt(v.a,v.b)))<eps;
 85 }
 86 
 87 int parallel(point  u1,point u2,point  v1,point  v2)
 88 {
 89 
 90     return vlen(xmult(subt(u1,u2),subt(v1,v2)))<eps;
 91 
 92 }
 93 
 94 //判两平面平行
 95 
 96 int parallel(plane u,plane v)
 97 {
 98 
 99     return vlen(xmult(pvec(u),pvec(v)))<eps;
100 
101 }
102 
103 int parallel(point  u1,point u2,point  u3,point  v1,point  v2,point  v3)
104 {
105     return vlen(xmult(pvec(u1,u2,u3),pvec(v1,v2,v3)))<eps;
106 
107 }
108 
109 //判直线与平面平行
110 
111 int parallel(line l,plane s)
112 {
113     return zero(dmult(subt(l.a,l.b),pvec(s)));
114 
115 }
116 
117 int parallel(point  l1,point  l2,point  s1,point  s2,point  s3)
118 {
119 
120     return zero(dmult(subt(l1,l2),pvec(s1,s2,s3)));
121 
122 }
123 
124 //判两直线垂直
125 
126 int perpendicular(line u,line v)
127 {
128 
129     return zero(dmult(subt(u.a,u.b),subt(v.a,v.b)));
130 
131 }
132 int perpendicular(point  u1,point u2,point  v1,point  v2)
133 {
134 
135     return zero(dmult(subt(u1,u2),subt(v1,v2)));
136 
137 }
138 
139 //判两平面垂直
140 
141 int perpendicular(plane u,plane v)
142 {
143 
144     return zero(dmult(pvec(u),pvec(v)));
145 
146 }
147 
148 int perpendicular(point  u1,point u2,point  u3,point  v1,point  v2,point  v3)
149 {
150     return zero(dmult(pvec(u1,u2,u3),pvec(v1,v2,v3)));
151 
152 }
153 
154 //判直线与平面平行
155 
156 int perpendicular(line l,plane s)
157 {
158     return vlen(xmult(subt(l.a,l.b),pvec(s)))<eps;
159 
160 }
161 
162 int perpendicular(point  l1,point  l2,point  s1,point  s2,point  s3)
163 {
164 
165     return vlen(xmult(subt(l1,l2),pvec(s1,s2,s3)))<eps;
166 
167 }
168 
169 //计算两直线交点,注意事先判断直线是否共面和平行!
170 //线段交点请另外判线段相交(同时还是要判断是否平行!)
171 point  intersection(point  u1,point u2,point  v1,point  v2)
172 {
173 
174     point  ret=u1;
175 
176     double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))
177 
178              /((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));
179 
180     ret.x+=(u2.x-u1.x)*t;
181     ret.y+=(u2.y-u1.y)*t;
182 
183     ret.z+=(u2.z-u1.z)*t;
184 
185     return ret;
186 
187 }
188 point  intersection(point  l1,point  l2,point  s1,point  s2,point  s3)
189 {
190 
191     point  ret=pvec(s1,s2,s3);
192 
193     double t=(ret.x*(s1.x-l1.x)+ret.y*(s1.y-l1.y)+ret.z*(s1.z-l1.z))/
194              (ret.x*(l2.x-l1.x)+ret.y*(l2.y-l1.y)+ret.z*(l2.z-l1.z));
195 
196     ret.x=l1.x+(l2.x-l1.x)*t;
197 
198     ret.y=l1.y+(l2.y-l1.y)*t;
199 
200     ret.z=l1.z+(l2.z-l1.z)*t;
201 
202     return ret;
203 }
204 //计算两平面交线,注意事先判断是否平行,并保证三点不共线!
205 line intersection(plane u,plane v)
206 {
207 
208     line ret;
209     ret.a=parallel(v.a,v.b,u.a,u.b,u.c)?intersection(v.b,v.c,u.a,u.b,u.c):intersection(v.a,v.b,u.a,u.b,u.c);
210 
211     ret.b=parallel(v.c,v.a,u.a,u.b,u.c)?intersection(v.b,v.c,u.a,u.b,u.c):intersection(v.c,v.a,u.a,u.b,u.c);
212 
213     return ret;
214 }
215 line intersection(point  u1,point  u2,point u3,point  v1,point  v2,point  v3)
216 {
217 
218     line ret;
219 
220     ret.a=parallel(v1,v2,u1,u2,u3)?intersection(v2,v3,u1,u2,u3):intersection(v1,v2,u1,u2,u3);
221 
222     ret.b=parallel(v3,v1,u1,u2,u3)?intersection(v2,v3,u1,u2,u3):intersection(v3,v1,u1,u2,u3);
223     return ret;
224 
225 }
226 //计算两直线交点,注意事先判断直线是否共面和平行!
227 //线段交点请另外判线段相交(同时还是要判断是否平行!)
228 point  intersection(line u,line v)
229 {
230 
231     point  ret=u.a;
232     double x, y;
233     x= ((u.a.x-v.a.x)*(v.a.y-v.b.y)-(u.a.y-v.a.y)*(v.a.x-v.b.x));
234     y= ((u.a.x-u.b.x)*(v.a.y-v.b.y)-(u.a.y-u.b.y)*(v.a.x-v.b.x));
235     double t=((u.a.x-v.a.x)*(v.a.y-v.b.y)-(u.a.y-v.a.y)*(v.a.x-v.b.x))
236 
237              /((u.a.x-u.b.x)*(v.a.y-v.b.y)-(u.a.y-u.b.y)*(v.a.x-v.b.x));
238     if(fabs(x)>eps){
239     ret.x+=(u.b.x-u.a.x)*t;
240 
241     ret.y+=(u.b.y-u.a.y)*t;
242 
243     ret.z+=(u.b.z-u.a.z)*t;
244     }
245     return ret;
246 
247 }
248 int main()
249 {
250       int t;
251       double dis,len1,len2;
252       scanf("%d",&t);
253       while(t--){
254             I(l1.a);
255             I(l1.b);
256             I(l2.a);
257             I(l2.b);
258             point n=xmult(subt(l1.a,l1.b),subt(l2.a,l2.b)),a,b;
259             a=l1.a+n;
260             b=l2.a+n;
261             plane p1(l1.a,l1.b,a),p2(l2.a,l2.b,b);
262             line m=intersection(p1,p2);
263             point ans1=intersection(m,l1);
264             point ans2=intersection(m,l2);
265             printf("%.6lf\n",distances(ans1,ans2));
266             printf("%.6lf %.6lf %.6lf %.6lf %.6lf %.6lf\n",ans1.x,ans1.y,ans1.z,ans2.x,ans2.y,ans2.z);
267       }
268       return 0;
269 }
View Code

 

 

 

posted @ 2013-09-15 20:45  _随心所欲_  阅读(319)  评论(0编辑  收藏  举报