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.
 
 
 

234 lines
5.3 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;