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.
 
 
 

210 lines
4.4 KiB

#include "stdafx.h"
#include "Clip.h"
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<iostream>
#include<fstream>
#include<sstream>
using namespace std;
//分支点数据类型
struct BranchPoint{
P coord; //点坐标
double t; // 分支点相对位置,在0-1之间
double Dis; //卡箍到卡箍之间的距离
bool fixed; //位置是否已经固定
Clip * pc1,*pc2; //存储它相邻的两个卡箍
BranchPoint *pb1,*pb2; //存储它相邻的两个分支点
double l,r; //限制t的范围
vector<int> branchPointsInSameSegment; //同一分段上其他分支点的标号
P ndir; //所在分支的法线方向
double position; //距离参考卡箍的距离
double tempt[2]; //存储分支点在两种情况下的最优位置,0代表异段进同段出
string referClip; //参考卡箍的名字
int id; //分支点标号
int mode; //存储分支点第一次被加入路径属于哪种情况,0代表异段进同段出,1代表同段进异端出
int bundleNodeID; //分支点属于的bundle段id
bool used; //分支点是否被使用
void init(){
l=0;r=1;
pc1=pc2=NULL;
pb1=pb2=NULL;
t=0.5;Dis=0;
fixed=false;
position=0;
id=0;
bundleNodeID=0;
used=0;
}
//初始化
BranchPoint(){
init();
}
//按两个卡箍初始化
BranchPoint(Clip *c1,Clip *c2){
init();
pc1=c1;pc2=c2;
Dis=distan1(c1->coord,c2->coord);
double ratio=MinClipToBranchPointDistance/Dis;
l=max(l,ratio);r=min(r,1-ratio);
t=(l+r)/2;
//cout<<"BranchPoint2: ratio:"<<ratio<<" l:"<<l<<" r:"<<r<<" t:"<<t<<endl;
coord=(c1->coord)*(1-t)+(c2->coord)*t;
}
//按卡箍和范围初始化
BranchPoint(Clip *c1,Clip *c2,double L,double R){
init();
pc1=c1;pc2=c2;
Dis=distan1(c1->coord,c2->coord);
double ratio=MinClipToBranchPointDistance/Dis;
l=max(L,ratio);r=min(R,1-ratio);
t=(l+r)/2;
cout<<"BranchPoint L+R: ratio:"<<ratio<<" l:"<<l<<" r:"<<r<<" t:"<<t<<endl;
coord=(c1->coord)*(1-t)+(c2->coord)*t;
}
//添加左边的分支点
void addL(BranchPoint b){
pb1=&b;
}
//添加右边的分支点
void addR(BranchPoint b){
pb2=&b;
}
//把左边界向右边推d距离
void pushL(double d){
if(d<=0)return;
l+=d/Dis;
}
//把右边界向左边推d距离
void pushR(double d){
if(d<=0)return;
r-=d/Dis;
}
//固定分支点位置
void fix(){
if(fixed==true)return;
fixed=true;
t=tempt[mode];
/*
if(pb1!=NULL){
pb1->pushL(t*Dis+MinBranchPointDistance-r*Dis);
}
if(pb2!=NULL){
pb2->pushR(l*Dis-(t*Dis-MinBranchPointDistance));
}
*/
cout<<"***********";
if(!Equal(t,l)&&!Equal(t,r))cout<<"-------";
cout<<endl;
referClip=pc1->name;
position=t*Dis;
assert(position<=Dis);
}
//通道方向反向,分支点也改变其表示形式
void reverse(){
referClip=pc2->name;
position=Dis-position;
}
//返回分支点在分支上可以连接到的下一个点
//offSet代表分支点坐标的偏差值
inline vector<int> getNext(int offSet){
vector<int> rc=branchPointsInSameSegment;
for(int i=0;i<rc.size();i++)rc[i]+=offSet;
rc.push_back(pc1->id);
rc.push_back(pc2->id);
return rc;
}
/*计算分支点到卡箍点的权值
reverse=0代表从分支点到p
reverse=1代表从p到分支点
*/
inline double computeWeight(P& p,int inOut,bool reverse){
if(l>=r)return 1e9;
if(fixed==false){
double X1=pc1->coord.x,Y1=pc1->coord.y,Z1=pc1->coord.z;
double X2=pc2->coord.x,Y2=pc2->coord.y,Z2=pc2->coord.z;
double X0=p.x,Y0=p.y,Z0=p.z;
double FZ=(X1-X0)*(X1-X2)+(Y1-Y0)*(Y1-Y2)+(Z1-Z0)*(Z1-Z2);
double FM=2*Dis*Dis;
t=FZ/FM; //公式法求t极小值点
t=max(t,l);t=min(t,r);
}
//if(!Equal(t,l)&&!Equal(t,r))cout<<"-------"<<endl;
coord=pc1->coord*(1-t)+pc2->coord*t;
coord.type=1;
if(reverse)return distan(p,coord,inOut,0);
return distan(coord,p,0,inOut);
}
//记录分支点最优位置
void recordPos(int mode){
//if(!Equal(t,l)&&!Equal(t,r))cout<<"-------"<<endl;
//else t=(l+r)/2;
tempt[mode]=t;
}
void check(int i){
//if(!Equal(t,l)&&!Equal(t,r))cout<<"--"<<i<<"--"<<endl;
}
};
//维护所有分支点的集合
struct BranchPointSet{
BranchPoint b[MAXPointNum]; //分支点数组
int branchPointNum; //分支点总数
BranchPointSet(){
branchPointNum=0;
}
//添加一个分支点,并返回指向它的指针
BranchPoint* addBranchPoint(Clip* pc1,Clip* pc2,int bundleNodeID){
branchPointNum++;
b[branchPointNum]=BranchPoint(pc1,pc2);
b[branchPointNum].bundleNodeID=bundleNodeID;
b[branchPointNum].id=branchPointNum;
b[branchPointNum].coord.type=1;
b[branchPointNum].coord.ref=branchPointNum;
return &b[branchPointNum];
}
//获取指向编号为id的分支点的指针
BranchPoint * getBranchPointPointer(int id){
assert(id>=1&&id<=branchPointNum);
return &b[id];
}
}branchPointSet;