228 lines
5.0 KiB
C
228 lines
5.0 KiB
C
#ifndef _DATASTRUCT_H
|
|
#define _DATASTRUCT_H
|
|
#include "sysDefine.h"
|
|
//直角坐标系下的一个点
|
|
struct cpoint
|
|
{
|
|
double x,y,z;
|
|
cpoint(){x = y = z = MAX_DBL;}
|
|
};
|
|
typedef vector<cpoint> cpointArray;
|
|
|
|
//直角坐标点的一些数学运算
|
|
cpoint operator -(cpoint a, cpoint b)
|
|
{
|
|
cpoint m;
|
|
m.x=a.x-b.x;
|
|
m.y=a.y-b.y;
|
|
m.z=a.z-b.z;
|
|
return m;
|
|
}
|
|
|
|
cpoint operator +(cpoint a, cpoint b) //矢量加法
|
|
{
|
|
cpoint m;
|
|
m.x=a.x+b.x;
|
|
m.y=a.y+b.y;
|
|
m.z=a.z+b.z;
|
|
return m;
|
|
}
|
|
|
|
cpoint operator *(double sign,cpoint b) //矢量乘法
|
|
{
|
|
cpoint m;
|
|
m.x=sign*b.x;
|
|
m.y=sign*b.y;
|
|
m.z=sign*b.z;
|
|
return m;
|
|
}
|
|
|
|
//重载逻辑等操作符作用于矢量,判断两个直角点是否相等
|
|
bool operator ==(cpoint a, cpoint b)
|
|
{
|
|
if(fabs(a.x-b.x)<ZERO&&fabs(a.y-b.y)<ZERO&&fabs(a.z-b.z)<ZERO)
|
|
{
|
|
return 1;
|
|
}
|
|
else return 0;
|
|
}
|
|
|
|
double dot(cpoint a, cpoint b) //矢量点乘
|
|
{
|
|
return a.x*b.x+a.y*b.y+a.z*b.z;
|
|
}
|
|
|
|
cpoint cross(cpoint a,cpoint b) //矢量叉乘
|
|
{
|
|
cpoint v;
|
|
v.x = a.y*b.z-a.z*b.y;
|
|
v.y = a.z*b.x-a.x*b.z;
|
|
v.z = a.x*b.y-a.y*b.x;
|
|
return v;
|
|
}
|
|
|
|
//返回两个直角坐标点的中点位置
|
|
cpoint middleCpoint(cpoint a,cpoint b)
|
|
{
|
|
cpoint c;
|
|
c.x = 0.5*(a.x + b.x);
|
|
c.y = 0.5*(a.y + b.y);
|
|
c.z = 0.5*(a.z + b.z);
|
|
return c;
|
|
}
|
|
|
|
//返回两点之间的一个点 以第一个点为参考点 第三个参数为相对于原线段的比例
|
|
cpoint scaleCpoint(cpoint a,cpoint b,double scale)
|
|
{
|
|
cpoint c;
|
|
c.x = a.x + (b.x - a.x)*scale;
|
|
c.y = a.y + (b.y - a.y)*scale;
|
|
c.z = a.z + (b.z - a.z)*scale;
|
|
return c;
|
|
}
|
|
|
|
cpoint rescaleCpoint(cpoint a,double refr)
|
|
{
|
|
cpoint c;
|
|
double m = sqrt(a.x*a.x+a.y*a.y+a.z*a.z);
|
|
c.x = a.x*refr/m;
|
|
c.y = a.y*refr/m;
|
|
c.z = a.z*refr/m;
|
|
return c;
|
|
}
|
|
|
|
double module(cpoint a)
|
|
{
|
|
return sqrt(a.x*a.x+a.y*a.y+a.z*a.z);
|
|
}
|
|
|
|
double distanceCpoint(cpoint a, cpoint b)
|
|
{
|
|
cpoint m;
|
|
double d;
|
|
m.x=a.x-b.x;
|
|
m.y=a.y-b.y;
|
|
m.z=a.z-b.z;
|
|
d = sqrt(m.x*m.x + m.y*m.y + m.z*m.z);
|
|
return d;
|
|
}
|
|
|
|
double sphAngle(cpoint a,cpoint b) //两个矢量的球心角 注意返回值为弧度
|
|
{
|
|
double m1,m2;
|
|
m1 = sqrt(a.x*a.x+a.y*a.y+a.z*a.z);
|
|
m2 = sqrt(b.x*b.x+b.y*b.y+b.z*b.z);
|
|
return acos((a.x*b.x+a.y*b.y+a.z*b.z)/(m1*m2));
|
|
}
|
|
|
|
//球坐标系下的一个点
|
|
struct spoint
|
|
{
|
|
double lon,lat,rad;
|
|
spoint(){lon = lat = rad = MAX_DBL;}
|
|
};
|
|
typedef vector<spoint> spointArray;
|
|
|
|
/*直角坐标与球坐标相互转换函数 注意这里使用的球坐标是地理坐标范围 即经度为-180~180 纬度为-90~90*/
|
|
cpoint s2c(spoint s)
|
|
{
|
|
cpoint c;
|
|
c.x = s.rad*sin((0.5 - s.lat/180.0)*pi)*cos((2.0 + s.lon/180.0)*pi);
|
|
c.y = s.rad*sin((0.5 - s.lat/180.0)*pi)*sin((2.0 + s.lon/180.0)*pi);
|
|
c.z = s.rad*cos((0.5 - s.lat/180.0)*pi);
|
|
return c;
|
|
}
|
|
|
|
spoint c2s(cpoint c)
|
|
{
|
|
spoint s;
|
|
s.rad = sqrt(pow(c.x,2)+pow(c.y,2)+pow(c.z,2));
|
|
if (fabs(s.rad)<ZERO) //点距离原点极近 将点置于原点
|
|
{
|
|
s.lat = s.lon = s.rad = 0.0;
|
|
}
|
|
else
|
|
{
|
|
s.lat = 90.0 - acos(c.z/s.rad)*180.0/pi;
|
|
s.lon = atan2(c.y,c.x)*180.0/pi;
|
|
}
|
|
return s;
|
|
}
|
|
|
|
//顶点
|
|
struct vertex
|
|
{
|
|
int id; //索引
|
|
cpoint posic; //直角坐标系位置
|
|
spoint posis; //球坐标系位置
|
|
vertex()
|
|
{
|
|
id = -1; //初始化顶点索引值为-1 这里不需要初始化坐标位置 因为已经由相应的初始化函数完成了初始化
|
|
}
|
|
void set(int i) //设置索引值
|
|
{
|
|
id = i;
|
|
}
|
|
void set(cpoint c) //从直角坐标位置初始化
|
|
{
|
|
posic.x = c.x; posic.y = c.y; posic.z = c.z;
|
|
posis = c2s(posic);
|
|
}
|
|
void set(spoint s) //从球坐标位置初始化
|
|
{
|
|
posis.lon = s.lon; posis.lat = s.lat; posis.rad = s.rad;
|
|
posic = s2c(posis);
|
|
}
|
|
void info() //显示顶点信息
|
|
{
|
|
cout << id << " " << setprecision(16) << posic.x << " " << posic.y << " " << posic.z << " " << posis.lon << " " << posis.lat << " " << posis.rad << endl;
|
|
}
|
|
};
|
|
typedef vector<vertex> vertexArray;
|
|
typedef map<int,vertex> idMap; //顶点索引值映射 用于通过索引值寻找相应顶点
|
|
typedef map<string,vertex> strMap; //顶点位置映射 用于通过顶点位置寻找相应顶点
|
|
typedef map<int,int> outIdMap; //输出msh文件时重新索引三角形顶点集
|
|
|
|
//三角形信息结构体,包含三角形的三个顶点索引,逆时针排序
|
|
struct triangle
|
|
{
|
|
int id;
|
|
int vec[3];//三角形顶点
|
|
int phys; //三角形的物理属性组
|
|
triangle() //初始化顶点索引
|
|
{
|
|
phys = 0; //默认的物理属性组为0
|
|
vec[0] = vec[1] = vec[2] = -1;
|
|
}
|
|
};
|
|
typedef vector<triangle> triangleArray;
|
|
|
|
//矢量与平面的交点
|
|
cpoint lineOnPlane(cpoint c,cpoint normal,cpoint p)
|
|
{
|
|
cpoint m;
|
|
m.x = 0; m.y = 0; m.z = 0;
|
|
double t;
|
|
if (dot(normal,p) != 0) //平面与矢量平行
|
|
{
|
|
t = dot(normal,c)/dot(normal,p);
|
|
m.x += p.x*t;
|
|
m.y += p.y*t;
|
|
m.z += p.z*t;
|
|
}
|
|
return m;
|
|
}
|
|
|
|
//细分三角形面积比形式的三角形内插值函数
|
|
double triInterp_area(cpoint p,cpoint p1,cpoint p2,cpoint p3,double d1,double d2,double d3)
|
|
{
|
|
cpoint pp1 = p1 - p;
|
|
cpoint pp2 = p2 - p;
|
|
cpoint pp3 = p3 - p;
|
|
//三角形的面积等于叉乘的1/2 这里只计算比值 所以不需要乘以1/2
|
|
double a1 = module(cross(pp2,pp3));
|
|
double a2 = module(cross(pp3,pp1));
|
|
double a3 = module(cross(pp1,pp2));
|
|
return (d1*a1+d2*a2+d3*a3)/(a1+a2+a3);;
|
|
}
|
|
#endif |