我自己写的3D图形数学库。。。有点乱!

来源:互联网 发布:美国救护车 费用 知乎 编辑:程序博客网 时间:2024/05/29 12:28
// Det.cpp : Defines the entry point for the console application.//#include "stdafx.h"#define M 3//矩阵大小#include <stdio.h>#include <iostream.h>#include <stdlib.h>#include <math.h>#include <conio.h>#include "ArrayInterTriangle.h"#define FRAND   (((float)rand()-(float)rand())/RAND_MAX)float  hanglieshi(float array[M][M]){//计算行列式   float temp[M][2*M];   int i,j,c,c1;   float result=0,t=1;   for(i=0;i<M;i++)   {//构造临时矩阵,用来计算行列式      for(j=0;j<2*M;j++)      {          temp[i][j]=array[i][j%M];      }   }   for(c1=0;c1<M;c1++)   {//计算正值      i=0;      j=c1;      t=1;      for(c=0;c<M;c++)      {         t*=temp[i][j];         i++;         j++;      }      result+=t;   }   for(c1=0;c1<M;c1++)   {//计算负值      i=M-1;      j=c1;      t=1;      for(c=0;c<M;c++)      {          t*=temp[i][j];          i--;          j++;      }      result-=t;   }   return result;}void init(float array[M][M]){//初始化矩阵,用随机值填充矩阵   int i,j;   float m=3.0;   //randomize();   for(i=0;i<M;i++)      for(j=0;j<M;j++)         array[i][j]=rand()%20000;}void output(float array[M][M]){//输出矩阵   int i,j;   for(i=0;i<M;i++)   {      printf("\n\n");      for(j=0;j<M;j++)          printf("%4f",array[i][j]);   }}//非齐次方程bool jieXianXingFangCheng(float xishu[M][M+1],float fangChengjie[M]){//函数所占用的空间量应该动态fenpfloat D[M][M];float Dn[M][M];//根据克莱姆法则,求得Dfor(int i=0;i<M;i++)for(int j=0;j<M;j++){D[i][j]=xishu[i][j];    Dn[i][j]=xishu[i][j];}if(hanglieshi(D)==0)return false;    float tempVect[M];//下面求解:    for(int m=0;m<M;m++){//替换第m列的值for(i=0;i<M;i++){            tempVect[i]=Dn[i][m];    Dn[i][m]=xishu[i][M];}fangChengjie[m]=hanglieshi(Dn)/hanglieshi(D);for(i=0;i<M;i++){            Dn[i][m]=tempVect[i];}//cout<<fangChengjie[m]<<endl;}return true;}//定义屏幕拾取要用的变量。//计算射线与平面交点的函数bool calInsert(float org[3],float dir[3],float flat[4],float intersection[3]){float xishu[3][4];//定义三个数来表示是否该设为标准参考int cankao[3];bool flag=false;for(int i=0,j=1;i<3;i++){   if(dir[i]!=0&&!flag)      {   cankao[0]=i;     flag=true;   }   else   {   cankao[j]=i;j++;   }}if(!flag)return flag;for(i=0;i<2;i++){///int x=i+1;//1,2为非参考降//系数为cankao[0],cankao[i+1],cankao[3-i];xishu[i][cankao[2-i]]=0;xishu[i][cankao[0]]=-dir[cankao[i+1]]/dir[cankao[0]];xishu[i][cankao[i+1]]=1;xishu[i][3]=org[cankao[i+1]]-dir[cankao[i+1]]*org[cankao[0]]/dir[cankao[0]];}/*for(i=0;i<3;i++){cout<<endl;for(j=0;j<4;j++){    cout<<xishu[i][j]<<"  ";}}*///第一行//x=nearPoint.x+n_vector.x*(y-nearPoint.y)/(farPoint.y-nearPoint.y);//z=nearPoint.z+n_vector.z*(y-nearPoint.y)/(farPoint.y-nearPoint.y);//xishu[cankao[1]][cankao[1]]=1;//xishu[cankao[1]][1]=-dir[cankao[1]]/dir[cankao[0]];//xishu[cankao[1]][cankao[0]]=0;//xishu[cankao[1]][3]=org[cankao[1]]-dir[cankao[1]]*org[cankao[0]]/dir[cankao[]];//第二行//第三行是一个平面方程。。//    //假设系数为a,b,c,常量为d////float a ,b ,c, d;    xishu[2][0]=flat[0];    xishu[2][1]=flat[1];xishu[2][2]=flat[2];xishu[2][3]=flat[3];    return jieXianXingFangCheng(xishu,intersection);}//下面的代码判断,平面上,一个点是否在三角形内。//思路是求面积。面积之和是否与三角形相等。//要用到求叉积  void _CrossProduct(float Vector1[3], float Vector2[3], float Cross[3]){Cross[0]= Vector1[1] * Vector2[2] - Vector1[2] * Vector2[1];Cross[1]= Vector1[2] * Vector2[0] - Vector1[0] * Vector2[2];Cross[2]= Vector1[0] * Vector2[1] - Vector1[1] * Vector2[0];}void VectBinus(float a[3],float b[3],float c[3]){     c[0]=a[0]-b[0]; c[1]=a[1]-b[1]; c[2]=a[2]-b[2];}//计算模double calMole(float a[3]){return sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]);}bool IsInTriangle(float a[3],float b[3],float c[3],float point[3]){    float  tempcross[4][3];float v1[3];float v2[3];    VectBinus(a,point,v1);    VectBinus(a,b,v2);_CrossProduct(v1,v2,tempcross[0]);    VectBinus(b,point,v1);    VectBinus(b,c,v2);_CrossProduct(v1,v2,tempcross[1]);VectBinus(c,point,v1);    VectBinus(c,a,v2);_CrossProduct(v1,v2,tempcross[2]);VectBinus(c,b,v1);    VectBinus(c,a,v2);_CrossProduct(v1,v2,tempcross[3]);//计算面积是否相等    if(fabs(calMole(tempcross[0])+calMole(tempcross[1])+calMole(tempcross[2])-calMole(tempcross[3]))<0.00001  )return true;return false;}//前面两个 表示一条射线,成功则返回point[3],true.bool IsIntersectWithTriangle(float org[3],float dir[3],float a[3],float b[3],float c[3],float point[3],bool &IsFromFront){  float v1[3],v2[3]; float flat_4[4]; float flat[3]; VectBinus(a,b,v1);     VectBinus(b,c,v2); _CrossProduct(v1,v2,flat); cout<<endl; cout<<"方向为:"; for(int i=0;i<3;i++) { cout<<dir[i]<<" "; } cout<<"法线为:"; for(i=0;i<3;i++) { cout<<flat[i]<<" "; } cout<<endl; float dot=DotProduct(flat,dir); cout<<"点积为:"<<endl;      cout<<dot<<endl; if(dot<0) IsFromFront=true; else IsFromFront=false; if(dot==0) { return false; } if(flat[0]==0&&flat[1]==0&&flat[2]==0) { return false; } //根据法线与平面上的线的垂直关系,写出平面方程 flat_4[3]=a[0]*flat[0]+a[1]*flat[1]+a[2]*flat[2];     flat_4[0]=flat[0]; flat_4[1]=flat[1]; flat_4[2]=flat[2]; if(calInsert(org,dir,flat_4,point)) { if(IsInTriangle(a,b,c,point)==true)return true; else return false; }else return false;}//求平面法线void qiuFaXiangLiang(float a[3],float b[3],float c[3],float faXiangLiang[3]){float v1[3],v2[3]; //float flat[3]; VectBinus(a,b,v1);     VectBinus(b,c,v2); _CrossProduct(v1,v2,faXiangLiang);}//求平面方程系数bool qiuPingMianFangCheng(float a[3],float b[3],float c[3],float flat_4[4]){ float v1[3],v2[3]; //float flat_4[4]; float flat[3]; VectBinus(a,b,v1);     VectBinus(b,c,v2); _CrossProduct(v1,v2,flat); if(flat[0]==0&&flat[1]==0&&flat[2]==0) { return false; } flat_4[3]=a[0]*flat[0]+a[1]*flat[1]+a[2]*flat[2];     flat_4[0]=flat[0]; flat_4[1]=flat[1]; flat_4[2]=flat[2]; return true;}bool IsTriangle(float a[3],float b[3],float c[3]){   float v1[3],v2[3];   float flat[3];   VectBinus(a,b,v1);   VectBinus(a,c,v2);   _CrossProduct(v1,v2,flat);       if(calMole(flat)<0.000001)return false;   else return true;}

 

#ifndef __ArrayInterTriangle_H__#define __ArrayInterTriangle_H__#define DotProduct(x,y) ((x)[0] * (y)[0] + (x)[1] * (y)[1] + (x)[2] * (y)[2]);bool IsIntersectWithTriangle(float org[3],float dir[3],float a[3],float b[3],float c[3],float point[3],bool &IsFromFront);void VectBinus(float a[3],float b[3],float c[3]);bool qiuPingMianFangCheng(float a[3],float b[3],float c[3],float flat_4[4]);void qiuFaXiangLiang(float a[3],float b[3],float c[3],float faXiangLiang[3]);bool calInsert(float org[3],float dir[3],float flat[4],float intersection[3]);bool IsTriangle(float a[3],float b[3],float c[3]);#endif