// Calculate the length of the vector length = (float)sqrt((vector[0]*vector[0]) + (vector[1]*vector[1]) + (vector[2]*vector[2])); // Keep the program from blowing up by providing an exceptable // value for vectors that may calculated too close to zero. if(length == 0.0f) length = 1.0f; // Dividing each element by the length will result in a // unit normal vector. vector[0] /= length; vector[1] /= length; vector[2] /= length; } void CTins::calcNormal(float v[3][3], float out[3])
{ float v1[3],v2[3]; static const int x = 0; static const int y = 1; static const int z = 2; // Calculate two vectors from the three points v1[x] = v[0][x] - v[1][x]; v1[y] = v[0][y] - v[1][y]; v1[z] = v[0][z] - v[1][z]; v2[x] = v[1][x] - v[2][x]; v2[y] = v[1][y] - v[2][y]; v2[z] = v[1][z] - v[2][z]; // Take the cross product of the two vectors to get // the normal vector which will be stored in out out[x] = v1[y]*v2[z] - v1[z]*v2[y]; out[y] = v1[z]*v2[x] - v1[x]*v2[z]; out[z] = v1[x]*v2[y] - v1[y]*v2[x]; // Normalize the vector (shorten length to one) ReduceToUnit(out); } bool CTins::IsPositive(int Point_1,int Point_2,int Point) //判断点是否在线段的正方向 { double a,b,f; a=(Points[Point_2].y-Points[Point_1].y)/(Points[Point_2].x-Points[Point_1].x); b=(Points[Point_1].y*Points[Point_2].x-Points[Point_2].y*Points[Point_1].x)/(Points[Point_2].x-Points[Point_1].x); f=Points[Point].y-a*Points[Point].x-b; if(f>=0) return true; else return false; }double CTins::Dis(float x1,float y1,float x2,float y2) { return abs(x1-x2)+abs(y1-y2); } //------------------------------------------------------------------------- double CTins::cosc(int NodeA,int NodeB,int NodeC) { double aa,bb,cc; aa=(Points[NodeB].x-Points[NodeC].x)*(Points[NodeB].x-Points[NodeC].x)+(Points[NodeB].y-Points[NodeC].y)*(Points[NodeB].y-Points[NodeC].y); bb=(Points[NodeA].x-Points[NodeC].x)*(Points[NodeA].x-Points[NodeC].x)+(Points[NodeA].y-Points[NodeC].y)*(Points[NodeA].y-Points[NodeC].y); cc=(Points[NodeB].x-Points[NodeA].x)*(Points[NodeB].x-Points[NodeA].x)+(Points[NodeB].y-Points[NodeA].y)*(Points[NodeB].y-Points[NodeA].y); return (aa+bb-cc)/(2*sqrt(aa)*sqrt(bb));}void CTins::Draw(struct TriangleNet TNet) { float normal[3]; float v[3][3]= {{Points[TNet.NodeA].x,Points[TNet.NodeA].y,Points[TNet.NodeA].z}, {Points[TNet.NodeB].x,Points[TNet.NodeB].y,Points[TNet.NodeB].z}, {Points[TNet.NodeC].x,Points[TNet.NodeC].y,Points[TNet.NodeC].z}}; calcNormal(v,normal); glColor3f(0.0f,0.5f,0.f); glBegin(GL_TRIANGLE_STRIP); glNormal3fv(normal); glVertex3fv(v[0]); glVertex3fv(v[1]); glVertex3fv(v[2]); glFinish(); glEnd();
//
.......
const int nPoints=4;
const int nLayers=6; //定义int Edges[nPoints][nPoints];//用来定义二维数组
........
// Tins.cpp : implementation file
//#include "stdafx.h"
#include "Test1.h"
#include "Tins.h"#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif/////////////////////////////////////////////////////////////////////////////
// CTinsCTins::CTins()
{
noftin=0;
max_x=0.0;
max_y=0.0;
min_x=10000.0;
min_y=10000.0;
csh=false;
bOutline=false;
addn=0;
ClipL[0].x=0;
ClipL[0].y=0;
ClipL[0].index=0;
ClipL[1].x=130;
ClipL[1].y=70;
ClipL[1].index=1;
}CTins::~CTins()
{
}
BEGIN_MESSAGE_MAP(CTins, CWnd)
//{{AFX_MSG_MAP(CTins)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CTins message handlers
int CTins::Tin() //生成三角网数据
{
double tem=1.E+30,tem1;
int L=0,K=0,i;
TriangleNet[L].index=0;
for(i=0;i<nPoints;i++) //找到第一个点
{
tem1=Dis(Points[i].x,Points[i].y,center_x,center_y);
if(tem1<tem)
{
TriangleNet[L].NodeA=i;
tem=tem1;
}
}
tem=1.E+30;
for(i=0;i<nPoints;i++) //找到第二个点
{
if(i!=TriangleNet[L].NodeA)
{
tem1=Dis(Points[TriangleNet[L].NodeA].x,Points[TriangleNet[L].NodeA].y,Points[i].x,Points[i].y);
if(tem1<tem)
{
TriangleNet[L].NodeB=i;
tem=tem1;
}
}
}
tem=1.0E+30;
for(i=0;i<nPoints;i++) //找第三个点
{
if(i!=TriangleNet[L].NodeA&&i!=TriangleNet[L].NodeB)
{
tem1=cosc(TriangleNet[L].NodeA,TriangleNet[L].NodeB,i);
if(tem1>0&&tem1<tem)
{
tem=tem1;
TriangleNet[L].NodeC=i;
}
}
}
K++;
Edges[TriangleNet[L].NodeA][TriangleNet[L].NodeB]++;
Edges[TriangleNet[L].NodeB][TriangleNet[L].NodeC]++;
Edges[TriangleNet[L].NodeC][TriangleNet[L].NodeA]++;
int NagB_Point;
while(K!=L||L==0)
{
if(Edges[TriangleNet[L].NodeA][TriangleNet[L].NodeB]+Edges[TriangleNet[L].NodeB][TriangleNet[L].NodeA]!=2)
{
NagB_Point=NagBPoint(TriangleNet[L].NodeA,TriangleNet[L].NodeB,TriangleNet[L].NodeC);
if(NagB_Point!=-1)
{
TriangleNet[K].NodeA=TriangleNet[L].NodeA;
TriangleNet[K].NodeB=TriangleNet[L].NodeB;
TriangleNet[K].NodeC=NagB_Point;
TriangleNet[K].index=K;
TriangleNet[K].AdjTriangleC=L;
TriangleNet[L].AdjTriangleC=K;
Edges[TriangleNet[K].NodeA][TriangleNet[K].NodeB]++;
Edges[TriangleNet[K].NodeB][TriangleNet[K].NodeC]++;
Edges[TriangleNet[K].NodeC][TriangleNet[K].NodeA]++;
K++;
}
else
TriangleNet[L].AdjTriangleC=-1;
}
if(Edges[TriangleNet[L].NodeB][TriangleNet[L].NodeC]+Edges[TriangleNet[L].NodeC][TriangleNet[L].NodeB]!=2)
{
NagB_Point=NagBPoint(TriangleNet[L].NodeB,TriangleNet[L].NodeC,TriangleNet[L].NodeA);
if(NagB_Point!=-1)
{
TriangleNet[K].NodeA=TriangleNet[L].NodeB;
TriangleNet[K].NodeB=TriangleNet[L].NodeC;
TriangleNet[K].NodeC=NagB_Point;
TriangleNet[K].index=K;
TriangleNet[K].AdjTriangleC=L;
TriangleNet[L].AdjTriangleA=K;
Edges[TriangleNet[K].NodeA][TriangleNet[K].NodeB]++;
Edges[TriangleNet[K].NodeB][TriangleNet[K].NodeC]++;
Edges[TriangleNet[K].NodeC][TriangleNet[K].NodeA]++;
K++;
}
else
TriangleNet[L].AdjTriangleA=-1;
}
if(Edges[TriangleNet[L].NodeC][TriangleNet[L].NodeA]+Edges[TriangleNet[L].NodeA][TriangleNet[L].NodeC]!=2)
{
NagB_Point=NagBPoint(TriangleNet[L].NodeC,TriangleNet[L].NodeA,TriangleNet[L].NodeB);
if(NagB_Point!=-1)
{
TriangleNet[K].NodeA=TriangleNet[L].NodeC;
TriangleNet[K].NodeB=TriangleNet[L].NodeA;
TriangleNet[K].NodeC=NagB_Point;
TriangleNet[K].index=K;
TriangleNet[K].AdjTriangleC=L;
TriangleNet[L].AdjTriangleB=K;
Edges[TriangleNet[K].NodeA][TriangleNet[K].NodeB]++;
Edges[TriangleNet[K].NodeB][TriangleNet[K].NodeC]++;
Edges[TriangleNet[K].NodeC][TriangleNet[K].NodeA]++;
K++;
}
else
TriangleNet[L].AdjTriangleB=-1;
}
L++;
}
return L;
}
void CTins::DrawTin(int n) //画出三角网
{
int i,j;
for(i=0;i<nPoints+addn;i++)
for(j=0;j<nPoints+addn;j++)
{
Edges[i][j]=0;
}
for(i=0;i<n;i++)
{
Draw(TriangleNet[i]);
//Edges[TriangleNet[i].NodeA][TriangleNet[i].NodeB]++;
//Edges[TriangleNet[i].NodeB][TriangleNet[i].NodeC]++;
//Edges[TriangleNet[i].NodeC][TriangleNet[i].NodeA]++;
}
}
{
//求出与点Point_3在线段Point_1Point_2一侧相反的点中与线段形成的夹角最大的点号
bool flag=IsPositive(Point_1,Point_2,Point_3);
bool flag1;
double tem=10E+30,tem1;
int n=-1;
for(int i=0;i<nPoints+addn;i++)
{
if(i!=Point_1&&i!=Point_2&&Point_3)
{
flag1=IsPositive(Point_1,Point_2,i);
if(flag1!=flag)
{
tem1=cosc(Point_1,Point_2,i);
if(tem1<=tem)
{
tem=tem1;
n=i;
}
}
}
}
return n;
}void CTins::ReduceToUnit(float vector[3])
{
float length;
// Calculate the length of the vector
length = (float)sqrt((vector[0]*vector[0]) +
(vector[1]*vector[1]) +
(vector[2]*vector[2])); // Keep the program from blowing up by providing an exceptable
// value for vectors that may calculated too close to zero.
if(length == 0.0f)
length = 1.0f; // Dividing each element by the length will result in a
// unit normal vector.
vector[0] /= length;
vector[1] /= length;
vector[2] /= length;
}
void CTins::calcNormal(float v[3][3], float out[3])
{
float v1[3],v2[3];
static const int x = 0;
static const int y = 1;
static const int z = 2; // Calculate two vectors from the three points
v1[x] = v[0][x] - v[1][x];
v1[y] = v[0][y] - v[1][y];
v1[z] = v[0][z] - v[1][z]; v2[x] = v[1][x] - v[2][x];
v2[y] = v[1][y] - v[2][y];
v2[z] = v[1][z] - v[2][z]; // Take the cross product of the two vectors to get
// the normal vector which will be stored in out
out[x] = v1[y]*v2[z] - v1[z]*v2[y];
out[y] = v1[z]*v2[x] - v1[x]*v2[z];
out[z] = v1[x]*v2[y] - v1[y]*v2[x]; // Normalize the vector (shorten length to one)
ReduceToUnit(out);
}
bool CTins::IsPositive(int Point_1,int Point_2,int Point) //判断点是否在线段的正方向
{
double a,b,f;
a=(Points[Point_2].y-Points[Point_1].y)/(Points[Point_2].x-Points[Point_1].x);
b=(Points[Point_1].y*Points[Point_2].x-Points[Point_2].y*Points[Point_1].x)/(Points[Point_2].x-Points[Point_1].x);
f=Points[Point].y-a*Points[Point].x-b;
if(f>=0)
return true;
else
return false;
}double CTins::Dis(float x1,float y1,float x2,float y2)
{
return abs(x1-x2)+abs(y1-y2);
}
//-------------------------------------------------------------------------
double CTins::cosc(int NodeA,int NodeB,int NodeC)
{
double aa,bb,cc;
aa=(Points[NodeB].x-Points[NodeC].x)*(Points[NodeB].x-Points[NodeC].x)+(Points[NodeB].y-Points[NodeC].y)*(Points[NodeB].y-Points[NodeC].y);
bb=(Points[NodeA].x-Points[NodeC].x)*(Points[NodeA].x-Points[NodeC].x)+(Points[NodeA].y-Points[NodeC].y)*(Points[NodeA].y-Points[NodeC].y);
cc=(Points[NodeB].x-Points[NodeA].x)*(Points[NodeB].x-Points[NodeA].x)+(Points[NodeB].y-Points[NodeA].y)*(Points[NodeB].y-Points[NodeA].y);
return (aa+bb-cc)/(2*sqrt(aa)*sqrt(bb));}void CTins::Draw(struct TriangleNet TNet)
{
float normal[3]; float v[3][3]= {{Points[TNet.NodeA].x,Points[TNet.NodeA].y,Points[TNet.NodeA].z},
{Points[TNet.NodeB].x,Points[TNet.NodeB].y,Points[TNet.NodeB].z},
{Points[TNet.NodeC].x,Points[TNet.NodeC].y,Points[TNet.NodeC].z}}; calcNormal(v,normal); glColor3f(0.0f,0.5f,0.f);
glBegin(GL_TRIANGLE_STRIP);
glNormal3fv(normal);
glVertex3fv(v[0]);
glVertex3fv(v[1]);
glVertex3fv(v[2]);
glFinish();
glEnd();
}
//DEL void CTins::DrawLine()
//DEL {
//DEL
//DEL }
bool CTins::IfCross(float x1, float y1, float x2, float y2,float x3, float y3,float x4, float y4)
{
double a,b,c,d;
a=x2-x1;
b=x4-x3;
c=y2-y1;
d=y4-y3;
if(a*d-b*c==0)
return false;
else
return true;
}bool CTins::IfOnLine(float x, float y, float x1, float y1,float x2, float y2)
{
if((x-x1)*(x-x2)<0)
{
return true;
}
else if((x-x1)*(x-x2)==0)
{
if((y-y1)*(y-y2)<=0)
return true;
else
return false;
}
else
{
return false;
}
}void CTins::CalCross(float x1, float y1, float x2, float y2,float x3, float y3,float x4, float y4)
{
float a,b,c,d;
a=x2-x1;
b=x4-x3;
c=y2-y1;
d=y4-y3;
cy=(c*d*(x3-x1)+a*d*y1-b*c*y3)/(a*d-b*c);
cx=x1+a*(cy-y1)/c;
}
void CTins::CalZ(float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3)
{
float d1,d2;
d1=Dis(x1, y1, x3, y3);
d2=Dis(x2, y2, x3, y3);
cz=z1+(d1/(d1+d2))*(z2-z1);
//补充点到数组的代码
//
}