- Cross函数判断点是否在直线上
- 勾股定理求斜边长度
- 判断墙是否阻挡两点光线
- Dijsktra计算最短路
// ShellDawn
// POJ1556
// No.10
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<iostream>
#include<cmath>
#define MM(x) memset(x,0,sizeof(x))
#define INF 0x3f3f3f3f
#define NINF 0xc0c0c0c0
#define eps 0.000001
using namespace std;
#define maxn 100
struct Point{
double x;
double y;
void puts(const double& a,const double& b){
x = a;
y = b;
}
};
struct Wall{
Point x;
Point y;
void puts(const double& a,const double& b,const double& c){
x.x = y.x = a;
x.y = b;
y.y = c;
}
};
Point p[maxn];
Wall w[maxn];
int pc;
int wc;
double E[maxn][maxn];
double ans[maxn];
int visited[maxn];
// return > 0 点在直线上面
double Cross(const Point& a, const Point& b,const Point& c){
return (b.x - a.x)*(c.y - a.y) - (c.x - a.x)*(b.y - a.y);
}
// a点和b点是否可以连线
bool judge(const int& a,const int& b){
if(p[a].x - p[b].x < eps && p[b].x - p[a].x < eps) return false;
for(int i=0;i<wc;i++){
if(w[i].x.x > min(p[a].x,p[b].x) && w[i].x.x < max(p[a].x,p[b].x)){
if((Cross(p[a],p[b],w[i].x)>0 && Cross(p[a],p[b],w[i].y)>0)
|| (Cross(p[a],p[b],w[i].x)<0 && Cross(p[a],p[b],w[i].y)<0)){
continue;
}else{
return false;
break;
}
}
}
return true;
}
// a点和b点距离
double PointL(const int& a,const int& b){
return sqrt((p[a].x - p[b].x)*(p[a].x - p[b].x) + (p[a].y - p[b].y)*(p[a].y - p[b].y));
}
void Dijkstra(){
MM(visited);
for(int i=0;i<pc;i++) ans[i] = (int)INF;
ans[0] = 0;
for(int i=0;i<pc;i++){
int loc = 0;
double v = (int)INF;
for(int j=0;j<pc;j++){
if(visited[j] == 0 && ans[j] < v){
v = ans[j];
loc = j;
}
}
visited[loc] = 1;
for(int j=0;j<pc;j++){
ans[j] = min(ans[j],ans[loc] + E[loc][j]);
}
}
}
int main(){
int T;
while(~scanf("%d",&T)&&T!=-1){
pc = wc = 0;
p[pc++].puts(0,5);
p[pc++].puts(10,5);
for(int i=0;i<T;i++){
double a,b[4];
cin>>a;
for(int j=0;j<4;j++){
cin>>b[j];
p[pc++].puts(a,b[j]);
}
w[wc++].puts(a,0,b[0]);
w[wc++].puts(a,b[1],b[2]);
w[wc++].puts(a,b[3],10);
}
for(int i=0;i<pc;i++){
E[i][i] = 0;
for(int j=i+1;j<pc;j++){
if(judge(i,j)){
E[i][j] = E[j][i] = PointL(i,j);
}else{
E[i][j] = E[j][i] = (int)INF;
}
}
}
Dijkstra();
printf("%.2f\n",ans[1]);
}
return 0;
}