#pragma once #ifdef _WIN32 #ifdef WIREROUTINGDLL_EXPORTS // VisualStudio DLL 项目模板会将 _EXPORTS 添加到定义预处理器宏。 #define CONST_API __declspec(dllexport) // _WIN32 #else #define CONST_API __declspec(dllimport) #endif #else #define CONST_API #endif #include "Point.h" #include "Intersection.h" #include #include #include #include #include #include #include using namespace std; // 该文件定义一些基本常量和通用函数 typedef P Point3; typedef P Vector3; static const int M = 10010; // 连接器数量 static const int N = 8010; // 卡箍数量 static const int MaxSTL = 210000; // STL文件最大面片数 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 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; // *卡箍到卡箍之间的最长距离(搜索半径)(不求交2000-3000较好) static const double MinClipToBranchPointDistance = 1; // 卡箍到分支点的最短距离(不求交11) static const double MinBranchPointDistance = 1; // 分支点到分支点的最短距离(不求交11) // X,Y,Z的正方向 static const P DX = P(1, 0, 0); static const P DY = P(0, 1, 0); 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两轴的中心 // static const double intersection_distance = 100; CONST_API extern int intersection_model; //是否判断求交 // 判断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(const P &p) { return inmid(MINX, p.x, MAXX) && inmid(MINY, p.y, MAXY) && inmid(MINZ, p.z, MAXZ); } // 将d与0比较,返回正负 inline int dcmp(const double d) { if (d < -eps) return -1; else if (d > eps) return 1; return 0; } // 空间两点距离 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(const P &p1, const P &p2) { double angel = Angle(p1, p2); if (angel <= minAngle || angel >= pi - minAngle) return 1; else if (angel >= pi / 2 - minAngle && angel <= pi / 2 + minAngle) return 2; return 0; } inline Point3 GetPlaneProjection(const Point3 &p, const Point3 &p0, const Vector3 &n) { return p - n * Dot(p - p0, 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)); // 判断分母是否为 0 return p1 + v * t; // 如果是线段,判断 t 是不是在 0 和 1 之间 } 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(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 = 180; if (len <= intersection_distance) return 1; else if (len <= intersection_distance * 1.5) return 1.4; else if (len <= intersection_distance * 3) return 2.6; else if (len <= intersection_distance * 5) return 6; else if (len <= intersection_distance * 10) return 15; else if (len <= intersection_distance * 25) 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) { LineSegment lineSegment(Vec3f(A.x, A.y, A.z), Vec3f(B.x, B.y, B.z)); static BVH_intersection bvh(mesh); bool hit = bvh.intersectWithLineSegment(lineSegment); if (hit == 0) penalty_par_intersection = 1; else 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) { double angel1 = Angle(A - B, DX); if (angel1 > pi / 2) angel1 = pi - angel1; double angel2 = Angle(A - B, DY); if (angel2 > pi / 2) angel2 = pi - angel2; double angel3 = Angle(A - B, DZ); if (angel3 > pi / 2) 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; 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) { LineSegment lineSegment(Vec3f(A.x, A.y, A.z), Vec3f(B.x, B.y, B.z)); static BVH_intersection bvh(mesh); bool hit = bvh.intersectWithLineSegment(lineSegment); if (hit == 0) penalty_par_intersection = 1; else 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) { double angel1 = Angle(A - B, DX); if (angel1 > pi / 2) angel1 = pi - angel1; double angel2 = Angle(A - B, DY); if (angel2 > pi / 2) angel2 = pi - angel2; double angel3 = Angle(A - B, DZ); if (angel3 > pi / 2) angel3 = pi - angel3; angel = min(angel1, min(angel2, angel3)); } P C; C.x = A.dx; C.y = A.dy; C.z = A.dz; double angel2 = Angle(B - A, C); angel2 = min(angel2, pi - angel2); if (A.isend == 1 || A.type != 0) angel2 = 0; C.x = B.dx; C.y = B.dy; C.z = B.dz; double angel3 = Angle(B - A, C); 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

vecp) { for (int j = 0; j < vecp.size(); j++) { P pp = vecp[j]; cout << setprecision(10) << "(" << pp.x << "," << pp.y << "," << pp.z << ")"; if (j != vecp.size() - 1) cout << "->"; } cout << endl; return; }