再次修订后的版本。。。。。。1.0(发布版,射线求交三角形)
2017-08-07 09:53
405 查看
// 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> #define DotProduct(x,y) ((x)[0] * (y)[0] + (x)[1] * (y)[1] + (x)[2] * (y)[2]); #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]) { //函数所占用的空间量应该动态fenp float D[M][M]; float Dn[M][M]; //根据克莱姆法则,求得D for(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); float dot=DotProduct(flat,dir); if(dot<0) IsFromFront=true; else IsFromFront=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; } void main() { float xishu[M][M+1]; float fangchengjie[M]; for(int i=0;i<M;i++) { for(int j=0;j<M;j++) { if(i!=j)xishu[i][j]=0; else xishu[i][j]=1; } } for(i=0;i<M;i++) xishu[i][M]=1; // jieXianXingFangCheng(xishu,fangchengjie); float org[3]={0,0,0}; float dir[3]={0.5,0.5,0.7}; float xishuA[4]={0,1,0,4}; float jiaodian[3]; //calInsert(org,dir,xishuA,jiaodian); //for(i=0;i<3;i++){ //cout<<jiaodian[i]<<endl; //} float a[3]={1,0,0}; float b[3]={0,1,0}; float c[3]={0,0,1}; float point[3]; bool IsFront; if( !IsIntersectWithTriangle(org,dir,a,b,c,point,IsFront)){ cout<<"不相交"<<endl; }else { cout<<"相交"<<endl; } if( IsFront){ cout<<"前面"<<endl; }else { cout<<"后面"<<endl; } for(i=0;i<3;i++){ cout<<point[i]<<endl; } float v1[3]={1,-1,0}; float v2[3]={1,0,-1}; float temp[3]; CrossProduct(v1,v2,temp); for(i=0;i<3;i++){ cout<<temp[i]<<endl; } cout<<FRAND; // float array[M][M]; // clrscr(); // init(array); // output(array); // printf("\n%d",hanglieshi(array));//输出矩阵行列式的值 }
相关文章推荐
- 使用射线矢量对三角形图元求交 D3DXIntersect()函数说明
- 三角形跟射线求交
- 射线与三角形求交,并判断是否在三角形内的完整代码(带测试)
- 射线与三角形求交的计算
- 探索射线与三角形求交的方法
- 使用射线矢量对三角形图元求交 D3DXIntersect()函数说明
- 射线与三角形求交
- Spring Boot 2.0.0 终于正式发布,重大修订版本
- 3D空间中射线与三角形的交叉检测算法【转】
- 三角形与射线相交
- 2016年第4本:大系统观,修订1.0.1版本
- Spring Boot 2.0.0 终于正式发布,重大修订版本
- WP 删除文章修订版本
- Spring 的 jdk 版本检测在 jdk 8 下的修订:only available on JDK 1.5 and higher 错误
- 第四周项目二 三角形 1初始版本
- wordpress禁用自动保存(autosave)和版本修订(revision)
- Scheme版本修订进展
- WordPress如何禁用并删除文章修订版本记录
- 禁用WordPress文章修订版本Revisions的两种方法(对新版本WP有效)
- POJ 2986 A Triangle and a Circle(三角形和圆形求交)