<style type="text/css">
<!--
@page
{margin:2cm}
pre
{font-family:"DejaVu Sans Mono",monospace}
p.我的格式-western
{font-family:"DejaVu Sans",sans-serif;
font-size:10pt}
p.我的格式-cjk
{font-size:10pt}
p.我的格式-ctl
{font-size:12pt}
p
{margin-bottom:0.21cm}
-->
</style>
模板元编程在立体几何中的妙用
为了更好地理解三维游戏编程,我开始研究了立体几何,注意,是立体解析几何,里面涉及到了很多元组、向量和矩阵的知识。虽然还有一些不懂,可是这唤醒了我在高等数学中学到的知识,我想以后还是有很大的用处的。
当然,数学是工具,是为我们编程服务的。但是出于对性能和简洁性的敏感,在构建数学库的过程中我千方百计减少我们的代码量。在我所学的封装、继承和多态以及模板中进行选择,最后我尝试了一下模板。
我学习了一下模板,发现这是一个非常好的特性。使用模板偏特化的技术,可以让编译器在编译器为我们做一些事情。我们先了解一下,这是在博客园中salomon的一篇介绍模板元编程中的例子,没错,就是求菲波那锲数列的和。
// 主模板
template<int N>
struct Fib
{
enum { Result = Fib<N-1>::Result + Fib<N-2>::Result };
};
// 完全特化版
template <>
struct Fib<1>
{
enum { Result = 1 };
};
// 完全特化版
template <>
struct Fib<0>
{
enum { Result = 0 };
};
int main()
{
int i = Fib<10>::Result;
// std::cout << i << std::endl;
}
从这里可以看出,主模板带的参数是一个整型的数,而不是typename,得益于这一点,C++才有模板元编程,而其它高级语言只有泛型编程。
这里我有一个需求。在3D游戏编程中,常常需要二维、三维、四维的矢量,以便各种各样的数学运算。比方说需要求出两个向量确定平面的法向量,这一点在微软D3D中的d3dx9math.h中有很多体现,此外还需要适配基本的格式,像OpenGL一样,既提供float型的也提供double型的。
怎么实现呢?的确,用模板很好实现:
#ifndef MATH3D_H
#define MATH3D_H
// 以下代码需要高级版本C++编译器支持
template <typename T, int n>
union Tuple
{
T m[n];
};
// 特化
template <typename T>
union Tuple<T, 2>
{
Tuple( void ){ }
Tuple( T _1, T _2 )
{
Set( _1, _2 );
}
void Set( T _1, T _2 )
{
m[0] = _1, m[1] = _2;
}
operator T*( void ) // 重载类型转换函数
{
return m;
}
Tuple operator+( const Tuple& obj ) const// 重载减号
{
Tuple ret;
ret.m[0] = m[0] + obj.m[0];
ret.m[1] = m[1] + obj.m[1];
return ret;
}
Tuple operator-( const Tuple& obj ) const// 重载减号
{
Tuple ret;
ret.m[0] = m[0] - obj.m[0];
ret.m[1] = m[1] - obj.m[1];
return ret;
}
Tuple& operator+=( const Tuple& obj )
{
m[0] += obj.m[0];
m[1] += obj.m[1];
return *this;
}
//-------------------------------------
T m[2];
struct
{
T x, y;
};
struct
{
T w, h;
};
};
template <typename T>
union Tuple<T, 3>
{
Tuple( void ){ }
Tuple( T _1, T _2, T _3 )
{
Set( _1, _2, _3 );
}
void Set( T _1, T _2, T _3 )
{
m[0] = _1, m[1] = _2, m[2] = _3;
}
operator T*( void ) // 重载类型转换函数
{
return m;
}
Tuple operator+( const Tuple& obj ) const// 重载减号
{
Tuple ret;
ret.m[0] = m[0] + obj.m[0];
ret.m[1] = m[1] + obj.m[1];
ret.m[2] = m[2] + obj.m[2];
return ret;
}
Tuple operator-( const Tuple& obj ) const// 重载减号
{
Tuple ret;
ret.m[0] = m[0] - obj.m[0];
ret.m[1] = m[1] - obj.m[1];
ret.m[2] = m[2] - obj.m[2];
return ret;
}
Tuple operator*( const T& obj ) const// 重载减号
{
Tuple ret;
ret.m[0] = m[0] * obj;
ret.m[1] = m[1] * obj;
ret.m[2] = m[2] * obj;
return ret;
}
Tuple operator-( void )
{
return Tuple( -m[0], -m[1], -m[2] );
}
Tuple& operator+=( const Tuple& obj )
{
m[0] += obj.m[0];
m[1] += obj.m[1];
m[2] += obj.m[2];
return *this;
}
//-------------------------------------
T m[3];
struct
{
T x, y, z;
};
struct
{
T r, g, b;
};
};
template <typename T>
union Tuple<T, 4>
{
Tuple( void ){ }
Tuple( T _1, T _2, T _3, T _4 )
{
Set( _1, _2, _3, _4 );
}
void Set( T _1, T _2, T _3, T _4 )
{
m[0] = _1, m[1] = _2, m[2] = _3, m[3] = _4;
}
operator T*( void ) // 重载类型转换函数
{
return m;
}
Tuple operator+( const Tuple& obj ) const// 重载减号
{
Tuple ret;
ret.m[0] = m[0] + obj.m[0];
ret.m[1] = m[1] + obj.m[1];
ret.m[2] = m[2] + obj.m[2];
ret.m[3] = m[3] + obj.m[3];
return ret;
}
Tuple operator-( const Tuple& obj ) const// 重载减号
{
Tuple ret;
ret.m[0] = m[0] - obj.m[0];
ret.m[1] = m[1] - obj.m[1];
ret.m[2] = m[2] - obj.m[2];
ret.m[3] = m[3] - obj.m[3];
return ret;
}
Tuple& operator+=( const Tuple& obj )
{
m[0] += obj.m[0];
m[1] += obj.m[1];
m[2] += obj.m[2];
m[3] += obj.m[3];
return *this;
}
//-------------------------------------
T m[4];
struct
{
T x, y, z, w;
};
struct
{
T r, g, b, a;
};
};
// 定义数据类型
typedef Tuple<float, 2> Vector2F, Point2F, Size2F;
typedef Tuple<float, 3> Vector3F, Color3F, Point3F;
typedef Tuple<float, 4> Vector4F, Color4F;
这里用Tuple表示一个通用的类模板,第一个参数表示类型,如float、double等,第二个参数表示成员的个数。我们通过特化2、3、4个成员个数的类模板来分别定义这些行为。最后定义了Vector2F等一些常见的类型。你们看,是不是比较好地达到了要求?
此外,这里使用到了union联合体的相关用法,在下一次我将向大家介绍union的妙用。
分享到:
相关推荐
描述几何画板如何应用于立体几何的课件,包括如何绘制立体几何图形、动态显示立体几何图形、构建可旋转空间直角坐标系等内容,全面介绍了几何画板在立体几何中的应用。
详细的讲述了空间向量在立体几何中的应用。
《几何学教程(立体几何卷)》J.Hadamard著,中文PDF版,清晰扫描版。该书除详细而严格地论述了立体几何内容外,还包括了常用曲线、测量概念以及有关高等几何等内容,附有大量的习题及解答。
立体几何中的向量方法
高中数学课件模板适合立体几何用,本模板是一个空模板,如需课件另外下载
立体几何高考题及解析,高中数学立体几何题型及解题方法(理科)
ACM计算几何模板大全 线段 圆 凸包 平面 立体几何 最小圆覆盖 多边形 切割 交并
2022届一轮复习人教B版 空间向量在立体几何中的应用 课件(24张).pptx
高中数学立体几何教案.docx
灰色立体几何背景PPT模板
适用于抽象简约及相关类别演示 适用于抽象简约及相关类别演示 适用于抽象简约及相关类别演示 适用于抽象简约及相关类别演示
我个人认为 此课件还不错 因为他囊括可整个高中的立体几何模块的知识 有利于复习
“几何图霸”提供了丰富的画图工具,不仅可绘制平面几何与立体几何图形,也可绘制空间向量、方程曲线、动点轨迹;它具有强大的度量、计算功能,能根据度量结果绘制点、实施变换。这种形与数的转化功能为数学学习和...
向量几何在游戏编程中的使用向量几何在游戏编程中的使用向量几何在游戏编程中的使用
高中数学立体几何PPT课件.pptx
立体几何三角形、几何图形裁图创意封面,几何风过渡页,红灰配色,箭头、楼宇、平行四边形、递进台阶走势箭头、循环步骤、梯子、饼形台阶等精美素材配图,精美实用图文排版,适合企业介绍、商务演讲、工作汇报等场景...
立体几何中一类动点轨迹问题.ppt
高中数学必修2立体几何专题.pdf
立体几何教育教学ppt模板。
高中立体几何知识点及考点,知识点的总结及其经常考法。