您的位置:首页 > 编程语言

射线与三角形求交,并判断是否在三角形内的完整代码(带测试)

2017-08-07 09:53 477 查看
// 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>
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;
}
}
//定义屏幕拾取要用的变量。
//计算射线与平面交点的函数
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];
}
//计算模
float calMole(float a[3])
{
return 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(
(
calMole(tempcross[0])
+calMole(tempcross[1])
+calMole(tempcross[2])
)==calMole(tempcross[3])
)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])
{
float v1[3],v2[3];
float flat_4[4];
float flat[3];
VectBinus(a,b,v1);
VectBinus(b,c,v2);
CrossProduct(v1,v2,flat);
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))
return IsInTriangle(a,b,c,point);
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,1,0};
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]={0,0,1};
float b[3]={1,0,0};
float c[3]={0,1,0};
float point[3];
if( IsIntersectWithTriangle(org,dir,a,b,c,point)){
cout<<"false!"<<endl;
}
for(i=0;i<3;i++){
cout<<point[i]<<endl;
}
// float array[M][M];
//  clrscr();
// init(array);
// output(array);
// printf("\n%d",hanglieshi(array));//输出矩阵行列式的值
}

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: