|
|
@ -11,7 +11,6 @@ |
|
|
|
#endif |
|
|
|
|
|
|
|
#include "Point.h" |
|
|
|
// #include "Geometry.h"
|
|
|
|
#include "Intersection.h" |
|
|
|
|
|
|
|
#include <cmath> |
|
|
@ -35,14 +34,15 @@ static const double MAXDia = 50; // 卡箍能容纳的最大直径 |
|
|
|
static const int maxCap = 50; // 卡箍能容纳的最大线缆数
|
|
|
|
static const double pi = acos(-1.0); // Π
|
|
|
|
static const double minAngle = pi / 144; // 判断平行和垂直的偏差阈值
|
|
|
|
// static const double minDis=30; //
|
|
|
|
// static const double minDis=30; //*
|
|
|
|
static const double R = 2000; // 飞机横截面的近似半径
|
|
|
|
static const double MARGIN = 1000; // 布线的空间范围,从STL模型向外延申的长度
|
|
|
|
//----------------------mark----------------------
|
|
|
|
static const int MAXBranchPointNumOnSegment = 4; // 分支上的最大分支点数
|
|
|
|
static const int MAXPointNum = N + MAXBranchPointNumOnSegment * N; // 最大分支点数加最大卡箍数
|
|
|
|
static const double segmentLength = 400; // 卡箍到卡箍之间的最长距离
|
|
|
|
static const double MinClipToBranchPointDistance = 1; // 卡箍到分支点的最短距离
|
|
|
|
static const double MinBranchPointDistance = 1; // 分支点到分支点的最短距离
|
|
|
|
static const double segmentLength = 3000; // *卡箍到卡箍之间的最长距离(搜索半径)(目前2000-3000较好)
|
|
|
|
static const double MinClipToBranchPointDistance = 11; // 卡箍到分支点的最短距离
|
|
|
|
static const double MinBranchPointDistance = 11; // 分支点到分支点的最短距离
|
|
|
|
// X,Y,Z的正方向
|
|
|
|
static const P DX = P(1, 0, 0); |
|
|
|
static const P DY = P(0, 1, 0); |
|
|
@ -51,21 +51,23 @@ static const P DZ = P(0, 0, 1); |
|
|
|
CONST_API extern double MAXX, MINX, MAXY, MINY, MAXZ, MINZ; // 卡箍的坐标范围,初值-1e9~1e9
|
|
|
|
CONST_API extern double Ycenter, Zcenter; // 飞机在Y,Z两轴的中心
|
|
|
|
|
|
|
|
extern vector<Vec3f> CONST_API vertices; |
|
|
|
extern vector<Vec3u> CONST_API indices; |
|
|
|
extern Mesh CONST_API mesh; |
|
|
|
extern int CONST_API intersection_model; |
|
|
|
|
|
|
|
inline bool inmid(double x, double y, double z, double margin = MARGIN) |
|
|
|
// static const double intersection_distance = 100;
|
|
|
|
static int intersection_model = 0; //是否判断求交
|
|
|
|
|
|
|
|
// 判断y是否在[x-margin,z+margin]的范围内
|
|
|
|
inline bool inmid(const double x, const double y, const double z, const double margin = MARGIN) |
|
|
|
{ |
|
|
|
return y >= x - margin && y <= z + margin; |
|
|
|
} |
|
|
|
inline bool inbox(P &p) |
|
|
|
|
|
|
|
inline bool inbox(const P &p) |
|
|
|
{ |
|
|
|
return inmid(MINX, p.x, MAXX) && inmid(MINY, p.y, MAXY) && inmid(MINZ, p.z, MAXZ); |
|
|
|
} |
|
|
|
|
|
|
|
inline int dcmp(double d) |
|
|
|
// 将d与0比较,返回正负
|
|
|
|
inline int dcmp(const double d) |
|
|
|
{ |
|
|
|
if (d < -eps) |
|
|
|
return -1; |
|
|
@ -74,17 +76,36 @@ inline int dcmp(double d) |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
inline double distan1(P &p1, P &p2) |
|
|
|
// 空间两点距离
|
|
|
|
inline double distan1(const P &p1, const P &p2) |
|
|
|
{ |
|
|
|
double x = p1.x - p2.x, y = p1.y - p2.y, z = p1.z - p2.z; |
|
|
|
return sqrt(x * x + y * y + z * z); |
|
|
|
} |
|
|
|
/*
|
|
|
|
inline double distan2(P &p1,P &p2){ |
|
|
|
static double penalty_par=1; |
|
|
|
if(intersection_model==1) |
|
|
|
{ |
|
|
|
LineSegment lineSegment(Vec3f(p1.x, p1.y, p1.z),Vec3f(p2.x, p2.y, p2.z)); |
|
|
|
static BVH_intersection bvh(mesh); |
|
|
|
bool hit = bvh.intersectWithLineSegment(lineSegment); |
|
|
|
if(hit==0) |
|
|
|
penalty_par=1; |
|
|
|
else |
|
|
|
penalty_par=100; |
|
|
|
} |
|
|
|
double x=p1.x-p2.x,y=p1.y-p2.y,z=p1.z-p2.z; |
|
|
|
return sqrt(x*x+y*y+z*z)*penalty_par; |
|
|
|
} |
|
|
|
*/ |
|
|
|
|
|
|
|
inline double Dot(const Vector3 &A, const Vector3 &B) { return A.x * B.x + A.y * B.y + A.z * B.z; } |
|
|
|
inline double Length(const Vector3 &A) { return sqrt(Dot(A, A)); } |
|
|
|
inline double Angle(const Vector3 &A, const Vector3 &B) { return acos(Dot(A, B) / Length(A) / Length(B)); } |
|
|
|
inline double DistanceToPlane(const Point3 &p, const Point3 &p0, const Vector3 &n) { return fabs(Dot(p - p0, n)); } // 如果不取绝对值,得到的是有向距离
|
|
|
|
|
|
|
|
inline int ParallelorVertical(P &p1, P &p2) |
|
|
|
inline int ParallelorVertical(const P &p1, const P &p2) |
|
|
|
{ |
|
|
|
double angel = Angle(p1, p2); |
|
|
|
if (angel <= minAngle || angel >= pi - minAngle) |
|
|
@ -93,53 +114,62 @@ inline int ParallelorVertical(P &p1, P &p2) |
|
|
|
return 2; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
inline Point3 GetPlaneProjection(Point3 &p, Point3 &p0, Vector3 &n) |
|
|
|
|
|
|
|
inline Point3 GetPlaneProjection(const Point3 &p, const Point3 &p0, const Vector3 &n) |
|
|
|
{ |
|
|
|
return p - n * Dot(p - p0, n); |
|
|
|
} |
|
|
|
inline Point3 LinePlaneIntersection(Point3 &p1, Point3 &p2, Point3 &p0, Vector3 &n) |
|
|
|
|
|
|
|
inline Point3 LinePlaneIntersection(const Point3 &p1, const Point3 &p2, const Point3 &p0, const Vector3 &n) |
|
|
|
{ |
|
|
|
Vector3 v = p2 - p1; |
|
|
|
double t = (Dot(n, p0 - p1) / Dot(n, p2 - p1)); |
|
|
|
return p1 + v * t; |
|
|
|
double t = (Dot(n, p0 - p1) / Dot(n, p2 - p1)); // 判断分母是否为 0
|
|
|
|
return p1 + v * t; // 如果是线段,判断 t 是不是在 0 和 1 之间
|
|
|
|
} |
|
|
|
inline Vector3 Cross(Vector3 A, Vector3 B) |
|
|
|
|
|
|
|
inline Vector3 Cross(const Vector3 A, const Vector3 B) |
|
|
|
{ |
|
|
|
return Vector3(A.y * B.z - A.z * B.y, A.z * B.x - A.x * B.z, A.x * B.y - A.y * B.x); |
|
|
|
} |
|
|
|
inline double Area2(Point3 &A, Point3 &B, Point3 &C) |
|
|
|
{ |
|
|
|
return Length(Cross(B - A, C - A)); |
|
|
|
} |
|
|
|
|
|
|
|
inline double get_penalty_par_distance(double len) |
|
|
|
inline double Area2(const Point3 &A, const Point3 &B, const Point3 &C) { return Length(Cross(B - A, C - A)); } |
|
|
|
|
|
|
|
inline double get_penalty_par_distance(const double len) |
|
|
|
{ |
|
|
|
static const double intersection_distance = 60; |
|
|
|
static const double intersection_distance = 180; |
|
|
|
if (len <= intersection_distance) |
|
|
|
return 1; |
|
|
|
else if (len <= intersection_distance * 1.5) |
|
|
|
return 3; |
|
|
|
return 1.4; |
|
|
|
else if (len <= intersection_distance * 3) |
|
|
|
return 10; |
|
|
|
return 2.6; |
|
|
|
else if (len <= intersection_distance * 5) |
|
|
|
return 20; |
|
|
|
return 6; |
|
|
|
else if (len <= intersection_distance * 10) |
|
|
|
return 50; |
|
|
|
return 15; |
|
|
|
else if (len <= intersection_distance * 25) |
|
|
|
return 200; |
|
|
|
return 30; |
|
|
|
else |
|
|
|
return 40; |
|
|
|
} |
|
|
|
|
|
|
|
/*考虑了连线方向,卡箍方向,连线长度的综合权值函数
|
|
|
|
A或者B type!=0时代表它们不是卡箍,对应的inOut没有意义 |
|
|
|
inOut1=0代表沿着A的dir,inOut1=1代表逆着A的dir |
|
|
|
inOut2=0代表沿着B的dir,inOut2=1代表逆着B的dir |
|
|
|
*/ |
|
|
|
inline double distan(P A, P B, int inOut1, int inOut2) |
|
|
|
{ |
|
|
|
static double penalty_par_intersection = 1; |
|
|
|
static double penalty_par_distance = 1; |
|
|
|
|
|
|
|
double angel = Angle(A - B, DX); |
|
|
|
if (angel > pi / 2) |
|
|
|
angel = pi - angel; |
|
|
|
angel = min(angel, pi / 2 - angel); |
|
|
|
double len = distan1(A, B); |
|
|
|
|
|
|
|
// 求交判断并赋值惩罚参数
|
|
|
|
if (intersection_model == 1) |
|
|
|
{ |
|
|
|
|
|
|
@ -149,9 +179,11 @@ inline double distan(P A, P B, int inOut1, int inOut2) |
|
|
|
if (hit == 0) |
|
|
|
penalty_par_intersection = 1; |
|
|
|
else |
|
|
|
penalty_par_intersection = 100; |
|
|
|
penalty_par_distance = get_penalty_par_distance(len); |
|
|
|
penalty_par_intersection = 100; //*原400
|
|
|
|
// cout << "out: len:" << len << " intersection_distance" << intersection_distance << endl;
|
|
|
|
} |
|
|
|
penalty_par_distance = get_penalty_par_distance(len); |
|
|
|
|
|
|
|
double len1 = sqrt((A.y - Ycenter) * (A.y - Ycenter) + (A.z - Zcenter) * (A.z - Zcenter)); |
|
|
|
double len2 = sqrt((B.y - Ycenter) * (B.y - Ycenter) + (B.z - Zcenter) * (B.z - Zcenter)); |
|
|
|
if (len1 < R || len2 < R) |
|
|
@ -167,27 +199,37 @@ inline double distan(P A, P B, int inOut1, int inOut2) |
|
|
|
angel3 = pi - angel3; |
|
|
|
angel = min(angel1, min(angel2, angel3)); |
|
|
|
} |
|
|
|
|
|
|
|
P C; |
|
|
|
if (inOut1) |
|
|
|
A.reverse(); |
|
|
|
C.x = A.dx; |
|
|
|
C.y = A.dy; |
|
|
|
C.z = A.dz; |
|
|
|
|
|
|
|
double angel2 = Angle(B - A, C); |
|
|
|
if (A.isend == 1 || A.type != 0) |
|
|
|
angel2 = 0; |
|
|
|
|
|
|
|
if (inOut2) |
|
|
|
B.reverse(); |
|
|
|
C.x = B.dx; |
|
|
|
C.y = B.dy; |
|
|
|
C.z = B.dz; |
|
|
|
|
|
|
|
double angel3 = Angle(B - A, C); |
|
|
|
if (B.isend == 1 || B.type != 0) |
|
|
|
angel3 = 0; |
|
|
|
|
|
|
|
double orign_distance = len * (angel * 4 + 1) + 300 * 600 * (angel2 + angel3) / len; |
|
|
|
return orign_distance * penalty_par_intersection * penalty_par_distance; |
|
|
|
} |
|
|
|
|
|
|
|
/*考虑了连线方向,卡箍方向,连线长度的综合权值函数
|
|
|
|
A和B自动选择最合适的dir |
|
|
|
*/ |
|
|
|
//----------------------mark----------------------
|
|
|
|
// 多线缆bug:距离太短可能无法生成分离点导致
|
|
|
|
inline double distan(P A, P B) |
|
|
|
{ |
|
|
|
static double penalty_par_intersection = 1; |
|
|
@ -205,9 +247,11 @@ inline double distan(P A, P B) |
|
|
|
if (hit == 0) |
|
|
|
penalty_par_intersection = 1; |
|
|
|
else |
|
|
|
penalty_par_intersection = 100; |
|
|
|
penalty_par_distance = get_penalty_par_distance(len); |
|
|
|
penalty_par_intersection = 100; //*原400
|
|
|
|
// cout << "no_out: len:" << len << " intersection_distance" << intersection_distance << endl;
|
|
|
|
} |
|
|
|
penalty_par_distance = get_penalty_par_distance(len); |
|
|
|
|
|
|
|
double len1 = sqrt((A.y - Ycenter) * (A.y - Ycenter) + (A.z - Zcenter) * (A.z - Zcenter)); |
|
|
|
double len2 = sqrt((B.y - Ycenter) * (B.y - Ycenter) + (B.z - Zcenter) * (B.z - Zcenter)); |
|
|
|
if (len1 < R || len2 < R) |
|
|
@ -239,10 +283,12 @@ inline double distan(P A, P B) |
|
|
|
angel3 = min(angel3, pi - angel3); |
|
|
|
if (B.isend == 1 || B.type != 0) |
|
|
|
angel3 = 0; |
|
|
|
|
|
|
|
double orign_distance = len * (angel * 4 + 1) + 300 * 600 * (angel2 + angel3) / len; |
|
|
|
return orign_distance * penalty_par_intersection * penalty_par_distance; |
|
|
|
} |
|
|
|
|
|
|
|
// 打印路径信息
|
|
|
|
inline void printPath(vector<P> vecp) |
|
|
|
{ |
|
|
|
for (int j = 0; j < vecp.size(); j++) |
|
|
|