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.
 
 
 

266 lines
7.0 KiB

#include "stdafx.h"
#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;
//该文件定义一些基本常量和通用函数
const int M=10010; //连接器数量
const int N=5010; //卡箍数量
const int MaxSTL=210000; //STL文件最大面片数
const double MAXDia=50; //卡箍能容纳的最大直径
const int maxCap=50; //卡箍能容纳的最大线缆数
const double pi=acos(-1.0); //Π
const double minAngle=pi/144; //判断平行和垂直的偏差阈值
const double minDis=30; //
const double R=2000; //飞机横截面的近似半径
const double MARGIN=1000; //布线的空间范围,从STL模型向外延申的长度
//----------------------mark----------------------
const int MAXBranchPointNumOnSegment=2; //分支上的最大分支点数
const int MAXPointNum=N+MAXBranchPointNumOnSegment*N; //最大分支点数加最大卡箍数
double segmentLength=0.8; //卡箍到卡箍之间的最长距离
const double MinClipToBranchPointDistance=55; //卡箍到分支点的最短距离
const double MinBranchPointDistance=55; //分支点到分支点的最短距离
P DX=P(1,0,0);
P DY=P(0,1,0);
P DZ=P(0,0,1);
//X,Y,Z的正方向
double Ycenter,Zcenter; //飞机在Y,Z两轴的中心
double MAXX=-1e9,MINX=1e9,MAXY=-1e9,MINY=1e9,MAXZ=-1e9,MINZ=1e9; //卡箍的坐标范围
vector<Vec3f> vertices;//VS2008
vector<Vec3u> indices;//VS2008
Mesh mesh;
const double intersection_distance=1;
int intersection_model =0;
typedef P Point3;
typedef P Vector3;
//判断y是否在[x-margin,z+margin]的范围内
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);
}
//将d与0比较,返回正负
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 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(Vector3 &A,Vector3 &B){return A.x*B.x+A.y*B.y+A.z*B.z;}
inline double Length(Vector3 &A){return sqrt(Dot(A,A));}
inline double Angle(Vector3 &A,Vector3 &B){return acos(Dot(A,B)/Length(A)/Length(B));}
inline double DistanceToPlane(Point3 &p,Point3 &p0,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));//判断分母是否为 0
return p1+v*t;//如果是线段,判断 t 是不是在 0 和 1 之间
}
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));}
/*考虑了连线方向,卡箍方向,连线长度的综合权值函数
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 int out1;
//cout<<"out:"<<out1++<<endl;
static double penalty_par_intersection=1;
static double penalty_par_distance=1;
//cout<<"out1"<<endl;
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=400;
if(len>intersection_distance)
penalty_par_distance=8;
else
penalty_par_distance=1;
}
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;
//return pow(len,angel*3+1);
double orign_distance=len*(angel*4+1)+300*600*(angel2+angel3)/len;
//cout<<"dir:"<<orign_distance<<" "<<"patch_par"<<patch_par<<endl;
//return len*(angel*4+1)+300*600*(angel2+angel3)/len;
return orign_distance*penalty_par_intersection*penalty_par_distance;
}
/*考虑了连线方向,卡箍方向,连线长度的综合权值函数
A和B自动选择最合适的dir
*/
//----------------------mark----------------------
inline double distan(P A,P B){
//static int without1;
//cout<<"without:"<<without1++<<endl;
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=400;
if(len>intersection_distance)
penalty_par_distance=8;
else
penalty_par_distance=1;
}
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;
//return pow(len,angel*3+1);
double orign_distance=len*(angel*4+1)+300*600*(angel2+angel3)/len;
return orign_distance*penalty_par_intersection;
}
//打印路径信息
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;
}