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.

302 lines
9.2 KiB

#pragma once
#ifdef _WIN32
#ifdef WIREROUTINGDLL_EXPORTS // VisualStudio DLL 项目模板会将 <PROJECTNAME>_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 <cmath>
#include <vector>
#include <queue>
#include <map>
#include <iostream>
#include <fstream>
#include <sstream>
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; // 判断平行和垂直的偏差阈值
9 months ago
// static const double minDis=30; //*
static const double R = 2000; // 飞机横截面的近似半径
static const double MARGIN = 1000; // 布线的空间范围,从STL模型向外延申的长度
9 months ago
//----------------------mark----------------------
static const int MAXBranchPointNumOnSegment = 4; // 分支上的最大分支点数
static const int MAXPointNum = N + MAXBranchPointNumOnSegment * N; // 最大分支点数加最大卡箍数
9 months ago
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两轴的中心
9 months ago
// static const double intersection_distance = 100;
CONST_API extern int intersection_model; //是否判断求交
9 months ago
// 判断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;
}
9 months ago
inline bool inbox(const P &p)
{
return inmid(MINX, p.x, MAXX) && inmid(MINY, p.y, MAXY) && inmid(MINZ, p.z, MAXZ);
}
9 months ago
// 将d与0比较,返回正负
inline int dcmp(const double d)
{
if (d < -eps)
return -1;
else if (d > eps)
return 1;
return 0;
}
9 months ago
// 空间两点距离
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);
}
9 months ago
/*
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)); } // 如果不取绝对值,得到的是有向距离
9 months ago
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;
}
9 months ago
inline Point3 GetPlaneProjection(const Point3 &p, const Point3 &p0, const Vector3 &n)
{
return p - n * Dot(p - p0, n);
}
9 months ago
inline Point3 LinePlaneIntersection(const Point3 &p1, const Point3 &p2, const Point3 &p0, const Vector3 &n)
{
Vector3 v = p2 - p1;
9 months ago
double t = (Dot(n, p0 - p1) / Dot(n, p2 - p1)); // 判断分母是否为 0
return p1 + v * t; // 如果是线段,判断 t 是不是在 0 和 1 之间
}
9 months ago
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);
}
9 months ago
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)
{
9 months ago
static const double intersection_distance = 180;
if (len <= intersection_distance)
return 1;
else if (len <= intersection_distance * 1.5)
9 months ago
return 1.4;
else if (len <= intersection_distance * 3)
9 months ago
return 2.6;
else if (len <= intersection_distance * 5)
9 months ago
return 6;
else if (len <= intersection_distance * 10)
9 months ago
return 15;
else if (len <= intersection_distance * 25)
9 months ago
return 30;
else
return 40;
}
9 months ago
/*考虑了连线方向,卡箍方向,连线长度的综合权值函数
A或者B type!=0inOut没有意义
inOut1=0沿A的dirinOut1=1A的dir
inOut2=0沿B的dirinOut2=1B的dir
*/
inline double distan(P A, P B, int inOut1, int inOut2)
{
static double penalty_par_intersection = 1;
static double penalty_par_distance = 1;
9 months ago
double angel = Angle(A - B, DX);
if (angel > pi / 2)
angel = pi - angel;
angel = min(angel, pi / 2 - angel);
double len = distan1(A, B);
9 months ago
// 求交判断并赋值惩罚参数
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
9 months ago
penalty_par_intersection = 100; //*原400
// cout << "out: len:" << len << " intersection_distance" << intersection_distance << endl;
}
9 months ago
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));
}
9 months ago
P C;
if (inOut1)
A.reverse();
C.x = A.dx;
C.y = A.dy;
C.z = A.dz;
9 months ago
double angel2 = Angle(B - A, C);
if (A.isend == 1 || A.type != 0)
angel2 = 0;
9 months ago
if (inOut2)
B.reverse();
C.x = B.dx;
C.y = B.dy;
C.z = B.dz;
9 months ago
double angel3 = Angle(B - A, C);
if (B.isend == 1 || B.type != 0)
angel3 = 0;
9 months ago
double orign_distance = len * (angel * 4 + 1) + 300 * 600 * (angel2 + angel3) / len;
return orign_distance * penalty_par_intersection * penalty_par_distance;
}
9 months ago
/*考虑了连线方向,卡箍方向,连线长度的综合权值函数
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
9 months ago
penalty_par_intersection = 100; //*原400
// cout << "no_out: len:" << len << " intersection_distance" << intersection_distance << endl;
}
9 months ago
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;
9 months ago
double orign_distance = len * (angel * 4 + 1) + 300 * 600 * (angel2 + angel3) / len;
return orign_distance * penalty_par_intersection * penalty_par_distance;
}
9 months ago
// 打印路径信息
inline void printPath(vector<P> 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;
}