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

 

 

 

你可能感兴趣的:(HDU)