You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
319 lines
8.5 KiB
319 lines
8.5 KiB
#include "stdafx.h"
|
|
#include "BasicChannel.h"
|
|
#include<cmath>
|
|
#include<vector>
|
|
#include<queue>
|
|
#include<map>
|
|
#include<iostream>
|
|
#include<fstream>
|
|
#include<sstream>
|
|
using namespace std;
|
|
|
|
//存储卡箍与卡箍之间,卡箍与分支点之间,分支点与分支点之间的边关系
|
|
struct BasicEdge{
|
|
vector<pair<int,int> > clip[MAXPointNum][2],branchPoint[N][2];
|
|
//0,1代表两种模式,0代表同分支段的卡箍与分支点,1则相反
|
|
|
|
private: vector<pair<int,int> >edge[N][2]; //卡箍到卡箍的连线
|
|
|
|
//预处理分支点和卡箍之间的连线关系
|
|
public: void buildEdgeBetweenClipAndBranchPoint(){
|
|
for(int i=1;i<=3000;i++){
|
|
for(int j=0;j<=1;j++){
|
|
assert(edge[i][j].size()==0);
|
|
}
|
|
}
|
|
|
|
for(int i=1;i<=basicChannel.bundleNum;i++){
|
|
|
|
BundleNode* pbn=basicChannel.bundles[i].head;
|
|
BundleNode* pre=NULL;
|
|
while(pbn!=NULL){
|
|
if(pre!=NULL){
|
|
int cid1=pre->pc->id;
|
|
int cid2=pbn->pc->id;
|
|
int inOut1=pre->inOut;
|
|
int inOut2=pbn->inOut;
|
|
assert(cid1!=cid2);
|
|
pair<int,int> pr=make_pair(cid2,inOut2);
|
|
assert(pr.first==cid2);
|
|
|
|
if(inOut1!=0&&inOut1!=1){
|
|
cout<<"clip "<<cid1<<" inOut="<<inOut1<<endl;
|
|
}
|
|
if(inOut2!=0&&inOut2!=1){
|
|
cout<<"clip "<<cid2<<" inOut="<<inOut2<<endl;
|
|
}
|
|
assert(inOut1==0||inOut1==1);
|
|
assert(inOut2==0||inOut2==1);
|
|
edge[cid1][inOut1].push_back(pr);
|
|
|
|
|
|
|
|
pr=make_pair(cid1,inOut1^1);
|
|
assert(pr.first==cid1);
|
|
edge[cid2][inOut2^1].push_back(pr);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
pre=pbn;
|
|
pbn=pbn->next;
|
|
}
|
|
//cout<<i<<" "<<edge[94][1].size()<<endl;
|
|
}
|
|
for(int i=1;i<=3000;i++){
|
|
for(int j=0;j<=1;j++){
|
|
for(int k=0;k<edge[i][j].size();k++){
|
|
if(edge[i][j][k].first==i)cout<<i<<" "<<j<<" "<<k<<endl;
|
|
assert(edge[i][j][k].first!=i);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
for(int i=1;i<=branchPointSet.branchPointNum;i++){
|
|
BranchPoint* pb=&branchPointSet.b[i];
|
|
int cid1=pb->pc1->id;
|
|
int inOut1=basicChannel.getClipInOut(cid1)^1;
|
|
int cid2=pb->pc2->id;
|
|
int inOut2=basicChannel.getClipInOut(cid2);
|
|
int inOut3=basicChannel.isClipConnectedToClip(cid1,cid2);
|
|
assert(inOut3==inOut2);
|
|
clip[i][0].push_back(make_pair(cid1,inOut1));
|
|
clip[i][0].push_back(make_pair(cid2,inOut2));
|
|
branchPoint[cid1][inOut1^1].push_back(make_pair(i,1));
|
|
branchPoint[cid2][inOut2^1].push_back(make_pair(i,1));
|
|
vector<int> vec=kdtree.search_by_dis(branchPointSet.b[i].coord,600);
|
|
for(int j=0;j<vec.size();j++){
|
|
int cid=vec[j];
|
|
if(!bvh.iscollect(clipSet.c[cid].coord,branchPointSet.b[i].coord)){
|
|
clip[i][1].push_back(make_pair(cid,0)); //这里相当于只存储卡箍,不存储进出信息,因为会变
|
|
int clipType=basicChannel.clipType(cid);
|
|
if(clipType==0){
|
|
|
|
branchPoint[cid][0].push_back(make_pair(i,0));
|
|
branchPoint[cid][1].push_back(make_pair(i,0));
|
|
}
|
|
else if(clipType==1){
|
|
int inDir=basicChannel.getEXTClipInDir(cid);
|
|
branchPoint[cid][inDir^1].push_back(make_pair(i,0));
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//返回卡箍能连接到的卡箍,如果没有能连接到的,返回只含有0的数组
|
|
vector< pair<int,int> > getClipConnectedToClip(int cid,int inOut){
|
|
if(edge[cid][inOut].size()!=0){
|
|
if(edge[cid][inOut][0].first==0)return edge[cid][inOut];
|
|
vector<pair<int,int> > res;
|
|
for(int i=0;i<edge[cid][inOut].size();i++){
|
|
int v=edge[cid][inOut][i].first;
|
|
assert(v!=cid);
|
|
int inOut2=edge[cid][inOut][i].second;
|
|
int clipType=basicChannel.clipType(v);
|
|
if(clipType==2){
|
|
int dir=basicChannel.isClipConnectedToClip(cid,v);
|
|
if(dir!=inOut2)continue;
|
|
//去除中间卡箍
|
|
}
|
|
res.push_back(make_pair(v,inOut2));
|
|
}
|
|
|
|
return res;
|
|
}
|
|
//只有不在通道里的卡箍方向需要被处理,通道内卡箍应该提前处理好
|
|
|
|
vector<int> vec1=kdtree.search_by_dis(clipSet.c[cid].coord,600);
|
|
for(int i=0;i<vec1.size();i++){
|
|
int v=vec1[i];
|
|
if(v==cid)continue;
|
|
int clipType=basicChannel.clipType(v);
|
|
if(clipType!=2&&
|
|
!bvh.iscollect(clipSet.c[cid].coord,clipSet.c[v].coord)){
|
|
|
|
if(clipType==0){
|
|
edge[cid][inOut].push_back(make_pair(v,0));
|
|
edge[cid][inOut].push_back(make_pair(v,1));
|
|
}
|
|
else{
|
|
int inDir=basicChannel.getEXTClipInDir(v);
|
|
edge[cid][inOut].push_back(make_pair(v,inDir));
|
|
|
|
}
|
|
}
|
|
}
|
|
if(edge[cid][inOut].size()==0)edge[cid][inOut].push_back(make_pair(0,0));
|
|
return edge[cid][inOut];
|
|
}
|
|
|
|
/*根据分支点返回卡箍
|
|
mode=0为模式A,否则为模式B
|
|
其中模式B需要过滤掉通道中的卡箍
|
|
*/
|
|
vector<pair<int,int> > getClipConnectedToBranchPoint(int bid,int mode){
|
|
if(mode==0)return clip[bid][0];
|
|
else {
|
|
vector<pair<int,int> > v;
|
|
for(int i=0;i<clip[bid][1].size();i++){
|
|
int cid=clip[bid][1][i].first;
|
|
int clipType=basicChannel.clipType(cid);
|
|
if(clipType==0){
|
|
v.push_back(make_pair(cid,0));
|
|
v.push_back(make_pair(cid,1));
|
|
}
|
|
else if(clipType==1){
|
|
v.push_back(make_pair(cid,basicChannel.getEXTClipInDir(cid)));
|
|
}
|
|
else if(clipType==2){
|
|
int dir=basicChannel.isBranchPointConnectedToClip(bid,cid);
|
|
if(dir!=-1)v.push_back(make_pair(cid,dir));
|
|
}
|
|
|
|
|
|
}
|
|
return v;
|
|
}
|
|
}
|
|
|
|
/*根据卡箍返回分支点,卡箍与分支点在同一个Bundle上
|
|
卡箍分为3种,断头/通道中的点/孤立点
|
|
其中通道中的点只能采用模式A
|
|
孤立点只能采用模式B
|
|
断头可以根据inOut来判断采用哪种模式
|
|
offset代表偏移量,用来将分支点标号对应到Astar中点的标号
|
|
*/
|
|
vector<pair<int,int> > getBranchPointConnectedToClip(int cid,int inOut,int offset=0){
|
|
vector<pair<int,int> > v;
|
|
for(int i=0;i<branchPoint[cid][inOut].size();i++){
|
|
int bid=branchPoint[cid][inOut][i].first;
|
|
int mode=branchPoint[cid][inOut][i].second;
|
|
v.push_back(make_pair(bid+offset,mode));
|
|
}
|
|
return v;
|
|
}
|
|
|
|
//返回Astar中编号为id的点能建立边的下个点
|
|
public: vector<pair<int,int> > getNextPoint(int id,int mode,int offset){
|
|
int cid,bid;
|
|
vector<pair<int,int> >v1,v2;
|
|
if(id<=offset){
|
|
cid=id;
|
|
v1=this->getBranchPointConnectedToClip(cid,mode,offset);
|
|
v2=this->getClipConnectedToClip(cid,mode);
|
|
if(v2.size()&&v2[0].first!=0)
|
|
v1.insert(v1.begin(),v2.begin(),v2.end());
|
|
return v1;
|
|
}
|
|
else {
|
|
bid=id-offset;
|
|
v1=this->getClipConnectedToBranchPoint(bid,mode);
|
|
return v1;
|
|
}
|
|
}
|
|
|
|
/*返回端点可以连接到的点
|
|
p是端点坐标
|
|
offSet是分支点坐标的偏移量
|
|
isEnd=1表示这个端点是路径终点,否则是路径起点
|
|
*/
|
|
public: vector<pair<int,int> > getEXTNextPoint(P p,int offSet,int isEnd){
|
|
vector<pair<int,int> >res;
|
|
vector<int> vec1=kdtree.search_by_dis(p,600);
|
|
vec1=basicChannel.getBranchPointAndClip(vec1,offSet);
|
|
for(int i=0;i<vec1.size();i++){
|
|
int v=vec1[i];
|
|
if(v<=offSet){
|
|
int clipType=basicChannel.clipType(v);
|
|
if(clipType==0){
|
|
res.push_back(make_pair(v,0));
|
|
res.push_back(make_pair(v,1));
|
|
}
|
|
if(clipType==1){
|
|
int inDir=basicChannel.getEXTClipInDir(v);
|
|
res.push_back(make_pair(v,inDir^isEnd));
|
|
}
|
|
|
|
}
|
|
else {
|
|
if(isEnd)res.push_back(make_pair(v,1));
|
|
else res.push_back(make_pair(v,0));
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
//根据新的路径更新边信息
|
|
public: void addPath(Path path){
|
|
for(int i=0;i<path.size();i++){
|
|
P& p=path.points[i];
|
|
BundleNode* pbn; //当前通道节点
|
|
if(p.type==0){ //卡箍
|
|
int cid=p.ref;
|
|
pbn=basicChannel.getClipBundleNodePointer(cid);
|
|
int clipType=basicChannel.clipType(cid);
|
|
assert(clipType==2);
|
|
int inOut=basicChannel.getClipInOut(cid);
|
|
|
|
//更新edge卡箍到卡箍的边
|
|
edge[cid][inOut].clear();
|
|
if(pbn->next->type==0){
|
|
int cid2=pbn->next->pc->id;
|
|
int inOut2=basicChannel.getClipInOut(cid2);
|
|
edge[cid][inOut].push_back(make_pair(cid2,inOut2));
|
|
}
|
|
else edge[cid][inOut].push_back(make_pair(0,0));
|
|
|
|
edge[cid][inOut^1].clear();
|
|
if(pbn->pre->type==0){
|
|
int cid2=pbn->pre->pc->id;
|
|
int inOut2=basicChannel.getClipInOut(cid2);
|
|
edge[cid][inOut^1].push_back(make_pair(cid2,inOut2^1));
|
|
}
|
|
else edge[cid][inOut^1].push_back(make_pair(0,0));
|
|
|
|
//更新branch卡箍到分支点的边
|
|
if(branchPoint[cid][0].size()!=0
|
|
&&branchPoint[cid][0][0].second==0){ //原本不在通道里
|
|
int vv=0;
|
|
for(int i=0;i<branchPoint[cid][0].size();i++){
|
|
int v=branchPoint[cid][0][i].first;
|
|
if(basicChannel.isBranchPointConnectedToClip(v,cid)==1){
|
|
vv=v;
|
|
break;
|
|
|
|
}
|
|
}
|
|
branchPoint[cid][0].clear();
|
|
if(vv!=0)branchPoint[cid][0].push_back(make_pair(vv,0));
|
|
}
|
|
if(branchPoint[cid][1].size()!=0
|
|
&&branchPoint[cid][1][0].second==0){
|
|
int vv=0;
|
|
for(int i=0;i<branchPoint[cid][1].size();i++){
|
|
int v=branchPoint[cid][1][i].first;
|
|
if(basicChannel.isBranchPointConnectedToClip(v,cid)==0){
|
|
vv=v;
|
|
break;
|
|
}
|
|
}
|
|
branchPoint[cid][1].clear();
|
|
if(vv!=0)branchPoint[cid][1].push_back(make_pair(vv,0));
|
|
}
|
|
//排除异分支模式
|
|
}
|
|
//分支点不需要更新
|
|
|
|
}
|
|
return;
|
|
}
|
|
|
|
|
|
}basicEdge;
|