#include #include #include #include #include #include using namespace std; const double E = 0.0000000001; double dist(double x_1_1, double y_1_1, double z_1_1, double x_1_2, double y_1_2, double z_1_2, double x_3_1, double y_3_1, double z_3_1, double x_3_2, double y_3_2, double z_3_2){ double d_x = x_1_2 - x_1_1; double d_y = y_1_2 - y_1_1; double d_z = z_1_2 - z_1_1; double e_x = x_3_2 - x_3_1; double e_y = y_3_2 - y_3_1; double e_z = z_3_2 - z_3_1; double n_1 = pow(d_x*e_x+d_y*e_y+d_z*e_z, 2.0); double n_2 = (d_x*d_x+d_y*d_y+d_z*d_z)*(e_x*e_x+e_y*e_y+e_z*e_z); if (fabs(n_1-n_2) < E){ double t = (d_x*(x_3_1-x_1_1)+d_y*(y_3_1-y_1_1)+d_z*(z_3_1-z_1_1))/(d_x*d_x+d_y*d_y+d_z*d_z); double result = sqrt(pow(x_1_1+d_x*t-x_3_1,2.0)+pow(y_1_1+d_y*t-y_3_1,2.0)+pow(z_1_1+d_z*t-z_3_1,2.0)); return result; }else{ double t_dash = (d_x*e_x + d_y*e_y + d_z*e_z)/(d_x*d_x + d_y*d_y + d_z*d_z); double a = d_x*(d_x*t_dash-e_x) + d_y*(d_y*t_dash-e_y) + d_z*(d_z*t_dash-e_z); double b = e_x*(d_x*t_dash-e_x) + e_y*(d_y*t_dash-e_y) + e_z*(d_z*t_dash-e_z); double c = (x_3_1-x_1_1)*(d_x*t_dash-e_x) + (y_3_1-y_1_1)*(d_y*t_dash-e_y) + (z_3_1-z_1_1)*(d_z*t_dash-e_z); double s = (c - a*(d_x*(x_3_1-x_1_1)+d_y*(y_3_1-y_1_1)+d_z*(z_3_1-z_1_1))) / (a*t_dash-b); double t = (d_x*(x_3_1+e_x*s-x_1_1)+d_y*(y_3_1+e_y*s-y_1_1)+d_z*(z_3_1+e_z*s-z_1_1)) / (d_x*d_x+d_y*d_y+d_z*d_z); double result = sqrt(pow(x_1_1+d_x*t-x_3_1-e_x*s,2) + pow(y_1_1+d_y*t-y_3_1-e_y*s,2) + pow(z_1_1+d_z*t-z_3_1-e_z*s,2)); return result; } } bool on_the_line(double p_x, double p_y, double p_z, double x_1, double y_1, double z_1, double x_2, double y_2, double z_2){ double d_x = x_2-x_1; double d_y = y_2-y_1; double d_z = z_2-z_1; if ((d_x == 0) && (d_y == 0) && (d_z != 0)){ return ((p_x == x_1) && (p_y == y_1)); }else if (d_x == 0){ double t = (p_y - y_1)/d_y; return ((p_x == x_1) && (fabs(p_z-(z_1+d_z*t)) < E)); }else{ double t = (p_x - x_1)/d_x; return ((fabs(p_y-(y_1+d_y*t)) < E) && (fabs(p_z-(z_1+d_z*t)) < E)); } } class Line{ public: int x_1,y_1,z_1,x_2,y_2,z_2; }; int main(){ int N; while(cin >> N){ if (N == 0) break; double x_s,y_s,z_s,x_t,y_t,z_t; cin >> x_s >> y_s >> z_s >> x_t >> y_t >> z_t; vector v; for (int i = 0; i < N; i++){ Line l; cin >> l.x_1 >> l.y_1 >> l.z_1 >> l.x_2 >> l.y_2 >> l.z_2; v.push_back(l); } double d[N][N]; for (int i = 0; i < N; i++){ for (int j = 0; j < N; j++){ d[i][j] = DBL_MAX; } } for (int i = 0; i < N; i++){ d[i][i] = 0; } for (int i = 0; i < N; i++){ for (int j = (i+1); j < N; j++){ d[i][j] = dist(v[i].x_1,v[i].y_1,v[i].z_1,v[i].x_2,v[i].y_2,v[i].z_2,v[j].x_1,v[j].y_1,v[j].z_1,v[j].x_2,v[j].y_2,v[j].z_2); d[j][i] = d[i][j]; } } int s = 0,t = 0; for (int i = 0; i < N; i++){ if (on_the_line(x_s,y_s,z_s,v[i].x_1,v[i].y_1,v[i].z_1,v[i].x_2,v[i].y_2,v[i].z_2)){ s = i; } if (on_the_line(x_t,y_t,z_t,v[i].x_1,v[i].y_1,v[i].z_1,v[i].x_2,v[i].y_2,v[i].z_2)){ t = i; } } double result[N]; for (int i = 0; i < N; i++){ result[i] = DBL_MAX; } result[s] = 0; set > wl; wl.insert(pair(0,s)); while(!wl.empty()){ double dt = wl.begin()->first; int i = wl.begin()->second; wl.erase(wl.begin()); for (int j = 0; j < N; j++){ if ((d[i][j] < DBL_MAX) && (dt + d[i][j] < result[j])){ wl.erase(pair(result[j],j)); result[j] = dt + d[i][j]; wl.insert(pair(result[j],j)); } } } printf("%.3lf\n",result[t]); } return 0; }