一个可复用的C++ 3阶实方阵类和4阶实方阵类(兼容与扩展了DX中的4阶实方阵类);四元数(quaternion)模板类的使用

2024-05-13 18:48

本文主要是介绍一个可复用的C++ 3阶实方阵类和4阶实方阵类(兼容与扩展了DX中的4阶实方阵类);四元数(quaternion)模板类的使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


一个可复用的C++ 3阶实方阵类和4阶实方阵类(兼容与扩展了DX中的4阶实方阵类)
部分DX矩阵函数的实现
namespace Han
{
 FLOAT WINAPI D3DXMatrixDeterminant(CONST D3DXMATRIX *pM)
{
     D3DXMATRIX mtx=*pM;
     FLOAT ret=Bsdet(&mtx(0,0),4);//第一个参数是输入输出参数
     return ret;
}
D3DXMATRIX* D3DXMatrixIdentity(D3DXMATRIX *pOut)
{
//identity matrix
memset(pOut,0,sizeof(D3DXMATRIX));
pOut->m[0][0]=1;
pOut->m[1][1]=1;
pOut->m[2][2]=1;
pOut->m[3][3]=1;
return pOut;
}
//Build a matrix which scales by (sx,sy,sz)
D3DXMATRIX* D3DXMatrixScaling(D3DXMATRIX *pOut,FLOAT sx,FLOAT sy,FLOAT sz)
{
//创建一个沿着X,Y和Z轴方向缩放矩阵
memset(pOut,0,sizeof(D3DXMATRIX));
pOut->m[0][0]=sx;
pOut->m[1][1]=sy;
pOut->m[2][2]=sz;
pOut->m[3][3]=1;
return pOut;
}
//Build a matrix which translates by (x,y,z)
D3DXMATRIX* D3DXMatrixTranslation(D3DXMATRIX *pOut,FLOAT x,FLOAT y,FLOAT z)
{
//创建一个沿着X,Y和Z轴方向平移矩阵
memset(pOut,0,sizeof(D3DXMATRIX));
pOut->m[0][0]=1;
pOut->m[1][1]=1;
pOut->m[2][2]=1;
pOut->m[3][3]=1;
pOut->m[3][0]=x;
pOut->m[3][1]=y;
pOut->m[3][2]=z;
return pOut;
}
//Build a matrix which rotates around the X axis
D3DXMATRIX* D3DXMatrixRotationX(D3DXMATRIX *pOut,FLOAT Angle)
{
//创建一个绕X轴旋转Angle弧度的旋转矩阵
memset(pOut,0,sizeof(D3DXMATRIX));
pOut->m[0][0]=1;
pOut->m[1][1]=cos(Angle);
pOut->m[2][2]=cos(Angle);
pOut->m[3][3]=1;
pOut->m[1][2]=sin(Angle);
pOut->m[2][1]=-sin(Angle);
return pOut;
}
//Build a matrix which rotates around the Y axis
D3DXMATRIX* D3DXMatrixRotationY(D3DXMATRIX *pOut,FLOAT Angle)
{
//创建一个绕Y轴旋转Angle弧度的旋转矩阵
memset(pOut,0,sizeof(D3DXMATRIX));
pOut->m[0][0]=cos(Angle);
pOut->m[1][1]=1;
pOut->m[2][2]=cos(Angle);
pOut->m[3][3]=1;
pOut->m[0][2]=-sin(Angle);
pOut->m[2][0]=sin(Angle);
return pOut;
}
//Build a matrix which rotates around the Z axis
D3DXMATRIX* D3DXMatrixRotationZ(D3DXMATRIX *pOut,FLOAT Angle)
{
//创建一个绕Z轴旋转Angle弧度的旋转矩阵
memset(pOut,0,sizeof(D3DXMATRIX));
pOut->m[0][0]=cos(Angle);
pOut->m[1][1]=cos(Angle);
pOut->m[2][2]=1;
pOut->m[3][3]=1;
pOut->m[0][1]=sin(Angle);
pOut->m[1][0]=-sin(Angle);
return pOut;
}
//Transform (x,y,z,1) by matrix
D3DXVECTOR4* D3DXVec3Transform(D3DXVECTOR4 *pOut,CONST D3DXVECTOR4 *pV,CONST D3DXMATRIX *pM)
{
#if 1
//MV
D3DXVECTOR4 v(pV->x,pV->y,pV->z,1);
pOut->x=(*pM)(0,0)*v.x+(*pM)(0,1)*v.y+(*pM)(0,2)*v.z+(*pM)(0,3)*v.w;
pOut->y=(*pM)(1,0)*v.x+(*pM)(1,1)*v.y+(*pM)(1,2)*v.z+(*pM)(1,3)*v.w;
pOut->z=(*pM)(2,0)*v.x+(*pM)(2,1)*v.y+(*pM)(2,2)*v.z+(*pM)(2,3)*v.w;
pOut->w=(*pM)(3,0)*v.x+(*pM)(3,1)*v.y+(*pM)(3,2)*v.z+(*pM)(3,3)*v.w;
return pOut;
#else
//VM
D3DXVECTOR4 v(pV->x,pV->y,pV->z,1);
pOut->x=(*pM)(0,0)*v.x+(*pM)(1,0)*v.y+(*pM)(2,0)*v.z+(*pM)(3,0)*v.w;
pOut->y=(*pM)(0,1)*v.x+(*pM)(1,1)*v.y+(*pM)(2,1)*v.z+(*pM)(3,1)*v.w;
pOut->z=(*pM)(0,2)*v.x+(*pM)(1,2)*v.y+(*pM)(2,2)*v.z+(*pM)(3,2)*v.w;
pOut->w=(*pM)(0,3)*v.x+(*pM)(1,3)*v.y+(*pM)(2,3)*v.z+(*pM)(3,3)*v.w;
return pOut;
#endif
return NULL;
}
};
----实矩阵乘法----
-3,1,-1,
-7,5,-1,
-6,6,-2,
-3,1,-1,
-7,5,-1,
-6,6,-2,
8,-4,4,
-8,12,4,
-12,12,4,
----实矩阵求逆----
-0.25,-0.25,0.25,
-0.5,3.47694e-008,0.25,
-0.75,0.75,-0.5,
-3,1,-1,
-7,5,-1,
-6,6,-2,
----实矩阵求行列式的值----
16
16
// 矩阵标准API(实矩阵相乘,Bsdet求实方阵的行列式值,求实方阵的逆)的C++封装,一个可复用的C++ 3阶方阵类
//
#include"stdafx.h"
#include<cmath>
#include<iostream>
using namespace std;
template<class T>
void __stdcall Brmul(T *a,T *b,int m,int n,int k,T *c)
{
 int i,j,l,u;
 for (i=0; i<=m-1; i++)
  for (j=0; j<=k-1; j++)
  {
   u=i*k+j;
   c[u]=0.0;
   for(l=0; l<=n-1; l++)
    c[u]=c[u]+a[i*n+l]*b[l*k+j];
  }
  return;
}
template<class T>
//第一个参数是输入输出参数
T __stdcall Bsdet(T *a,int n)
{
 int i,j,k,is,js,l,u,v;
 T f,det,q,d;
 f=1.0; det=1.0;
 for (k=0; k<=n-2; k++)
 {
  q=0.0;
  for (i=k; i<=n-1; i++)
   for (j=k; j<=n-1; j++)
   {
    l=i*n+j;
    d=fabs(a[l]);
    if (d>q)
    {
     q=d;
     is=i;
     js=j;
    }
   }
   if(q+1.0==1.0)
   {
    det=0.0;
    return(det);
   }
   if(is!=k)
   {
    f=-f;
    for (j=k; j<=n-1; j++)
    {
     u=k*n+j;
     v=is*n+j;
     d=a[u];
     a[u]=a[v];
     a[v]=d;
    }
   }
   if(js!=k)
   {
    f=-f;
    for (i=k; i<=n-1; i++)
    {
     u=i*n+js;
     v=i*n+k;
     d=a[u];
     a[u]=a[v];
     a[v]=d;
    }
   }
   l=k*n+k;
   det=det*a[l];
   for (i=k+1; i<=n-1; i++)
   {
    d=a[i*n+k]/a[l];
    for (j=k+1; j<=n-1; j++)
    {
     u=i*n+j;
     a[u]=a[u]-d*a[k*n+j];
    }
   }
 }
 det=f*det*a[n*n-1];
 return(det);
}
template<class T>
int __stdcall Brinv(T *a,int n)
{
 int *is,*js,i,j,k,l,u,v;
 T d,p;
 is=(int*)malloc(n*sizeof(int));
 js=(int*)malloc(n*sizeof(int));
 for (k=0; k<=n-1; k++)
 {
  d=0.0;
  for (i=k; i<=n-1; i++)
   for (j=k; j<=n-1; j++)
   {
    l=i*n+j;
    p=fabs(a[l]);
    if (p>d)
    {
     d=p;
     is[k]=i;
     js[k]=j;
    }
   }
   if (d+1.0==1.0)
   {
    free(is);
    free(js);
    printf("err**not inv\n");
    return(0);
   }
   if (is[k]!=k)
    for (j=0; j<=n-1; j++)
    {
     u=k*n+j;
     v=is[k]*n+j;
     p=a[u];
     a[u]=a[v];
     a[v]=p;
    }
    if (js[k]!=k)
     for (i=0; i<=n-1; i++)
     {
      u=i*n+k;
      v=i*n+js[k];
      p=a[u];
      a[u]=a[v];
      a[v]=p;
     }
     l=k*n+k;
     a[l]=1.0/a[l];
     for (j=0; j<=n-1; j++)
      if (j!=k)
      {
       u=k*n+j;
       a[u]=a[u]*a[l];
      }
      for (i=0; i<=n-1; i++)
       if (i!=k)
        for (j=0; j<=n-1; j++)
         if (j!=k)
         {
          u=i*n+j;
          a[u]=a[u]-a[i*n+k]*a[k*n+j];
         }
         for (i=0; i<=n-1; i++)
          if (i!=k)
          {
           u=i*n+k;
           a[u]=-a[u]*a[l];
          }
 }
 for(k=n-1; k>=0; k--)
 {
  if (js[k]!=k)
   for (j=0; j<=n-1; j++)
   {
    u=k*n+j;
    v=js[k]*n+j;
    p=a[u];
    a[u]=a[v];
    a[v]=p;
   }
   if (is[k]!=k)
    for (i=0; i<=n-1; i++)
    {
     u=i*n+k;
     v=i*n+is[k];
     p=a[u];
     a[u]=a[v];
     a[v]=p;
    }
 }
 free(is);
 free(js);
 return(1);
}
 
// From gamasutra. This file may follow different licence features.
// A floating point number
//
typedef float SCALAR;
//
// A 3D vector
//
class VECTOR
{
public:
 SCALAR x,y,z; //x,y,z coordinates
public:
 VECTOR() : x(0), y(0), z(0) {}
 VECTOR( const SCALAR& a, const SCALAR& b, const SCALAR& c ) : x(a), y(b), z(c) {}
 //index a component
 //NOTE: returning a reference allows
 //you to assign the indexed element
 SCALAR& operator [] ( const long i )
 {
  return *((&x) + i);
 }
//compare

这篇关于一个可复用的C++ 3阶实方阵类和4阶实方阵类(兼容与扩展了DX中的4阶实方阵类);四元数(quaternion)模板类的使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/986525

相关文章

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

C++中unordered_set哈希集合的实现

《C++中unordered_set哈希集合的实现》std::unordered_set是C++标准库中的无序关联容器,基于哈希表实现,具有元素唯一性和无序性特点,本文就来详细的介绍一下unorder... 目录一、概述二、头文件与命名空间三、常用方法与示例1. 构造与析构2. 迭代器与遍历3. 容量相关4

Linux join命令的使用及说明

《Linuxjoin命令的使用及说明》`join`命令用于在Linux中按字段将两个文件进行连接,类似于SQL的JOIN,它需要两个文件按用于匹配的字段排序,并且第一个文件的换行符必须是LF,`jo... 目录一. 基本语法二. 数据准备三. 指定文件的连接key四.-a输出指定文件的所有行五.-o指定输出

Linux jq命令的使用解读

《Linuxjq命令的使用解读》jq是一个强大的命令行工具,用于处理JSON数据,它可以用来查看、过滤、修改、格式化JSON数据,通过使用各种选项和过滤器,可以实现复杂的JSON处理任务... 目录一. 简介二. 选项2.1.2.2-c2.3-r2.4-R三. 字段提取3.1 普通字段3.2 数组字段四.

C++中悬垂引用(Dangling Reference) 的实现

《C++中悬垂引用(DanglingReference)的实现》C++中的悬垂引用指引用绑定的对象被销毁后引用仍存在的情况,会导致访问无效内存,下面就来详细的介绍一下产生的原因以及如何避免,感兴趣... 目录悬垂引用的产生原因1. 引用绑定到局部变量,变量超出作用域后销毁2. 引用绑定到动态分配的对象,对象

Linux kill正在执行的后台任务 kill进程组使用详解

《Linuxkill正在执行的后台任务kill进程组使用详解》文章介绍了两个脚本的功能和区别,以及执行这些脚本时遇到的进程管理问题,通过查看进程树、使用`kill`命令和`lsof`命令,分析了子... 目录零. 用到的命令一. 待执行的脚本二. 执行含子进程的脚本,并kill2.1 进程查看2.2 遇到的

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三

k8s按需创建PV和使用PVC详解

《k8s按需创建PV和使用PVC详解》Kubernetes中,PV和PVC用于管理持久存储,StorageClass实现动态PV分配,PVC声明存储需求并绑定PV,通过kubectl验证状态,注意回收... 目录1.按需创建 PV(使用 StorageClass)创建 StorageClass2.创建 PV

Redis 基本数据类型和使用详解

《Redis基本数据类型和使用详解》String是Redis最基本的数据类型,一个键对应一个值,它的功能十分强大,可以存储字符串、整数、浮点数等多种数据格式,本文给大家介绍Redis基本数据类型和... 目录一、Redis 入门介绍二、Redis 的五大基本数据类型2.1 String 类型2.2 Hash