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.

221 lines
6.6 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 "Geometry.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; //�ж�ƽ�кʹ�ֱ��ƫ����ֵ
//static const double minDis=30; //
static const double R=2000; //�ɻ��������Ľ��ư뾶
static const double MARGIN=1000; //���ߵĿռ䷶Χ����STLģ�����������ij���
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; //��֧�㵽��֧�������̾���
//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����������
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){
return y>=x-margin&&y<=z+margin;
}
inline bool inbox(P& p){
return
inmid(MINX,p.x,MAXX)
&&inmid(MINY,p.y,MAXY)
&&inmid(MINZ,p.z,MAXZ);
}
inline int dcmp(double d){
if(d<-eps)return -1;
else if(d>eps)return 1;
return 0;}
inline double distan1(P &p1,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 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){
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(Point3 &p,Point3 &p0,Vector3 &n)
{
return p - n * Dot(p - p0, n);
}
inline Point3 LinePlaneIntersection(Point3 &p1,Point3 &p2,Point3 &p0,Vector3 &n)
{
Vector3 v=p2-p1;
double t=(Dot(n,p0-p1)/Dot(n,p2-p1));
return p1+v*t;
}
inline Vector3 Cross(Vector3 A,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)
{
static const double intersection_distance=60;
if(len<=intersection_distance)
return 1;
else if(len<=intersection_distance*1.5)
return 3;
else if(len<=intersection_distance*3)
return 10;
else if(len<=intersection_distance*5)
return 20;
else if(len<=intersection_distance*10)
return 50;
else if(len<=intersection_distance*25)
return 200;
else return 40;
}
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;
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;
}
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;
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<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;
}