`
daojin
  • 浏览: 675581 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

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

阅读更多
// 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])
{
	//函数所占用的空间量应该动态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);
	 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

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics