65.9K
CodeProject 正在变化。 阅读更多。
Home

第一部分:欧几里得几何代数和四元数

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.87/5 (11投票s)

2005年3月4日

CPOL

8分钟阅读

viewsIcon

96530

downloadIcon

2277

几何代数在 OpenGL 中的应用。

Sample Image - ega.jpg

引言

这将是关于几何代数(GA)及其在图形学中应用的第一个系列文章,我将使用Gaigen。我将随着我朝着图形应用的共形模型努力来演进这段代码。我从三维几何代数模型开始,因为我认为它更容易理解。本文包含三个部分:GAGL类、Gaigen以及欧几里得几何代数简介。

GAGL 类

我将只介绍OpenGL类,因为它自成一体。对于那些没有使用过OpenGL的人来说,这可能是一个轻松入门的好方法。在OnDarw中一行代码就可以在屏幕上显示一个可以通过鼠标操作的对象。目前,您在实现它时仍需要包含Gaigen的头文件,但我会在未来尝试隐藏这些头文件。到目前为止,此类已处理OpenGL初始化、屏幕绘制和鼠标移动。构建它,您会注意到鼠标移动非常直观,仿佛使用了四元数。如果您在堆上创建它,您就不必在应用程序中到处散布头文件。此类可用于WINDOWS应用程序、WTL或MFC中的窗口和视图。我已将必要的接口保持在最低限度。生成的Gaigen文件已包含在项目下载中,您无需Gaigen生成器即可使用示例项目或GAGL类。您不必了解任何几何代数或Gaigen的知识,因为这些都已隐藏。

要在MFC视图中使用它,请在CMyView声明中添加一个指针
    GAGL* pGWL;

OnCreate中初始化它

    pGLW= new GAGL( *this );

在视图的OnSize成员函数中

    pGLW->OnSize( cx, cy );

一个最小化的鼠标实现是通过在x和y轴上滚动屏幕。像这样传递鼠标移动

void CMyView::OnLButtonDown( UINT /*nFlags*/, CPoint point )
{
    SetCapture( );
    bMouseActive= true;
    pGLW->InitMouse( point.x, point.y );
}

void CMyView::OnLButtonUp( UINT /*nFlags*/, CPoint /*point*/ )
{
    ReleaseCapture( );
    bMouseActive= false;
}

void CMyView::OnMouseMove( UINT /*nFlags*/, CPoint point )
{
    if( bMouseActive )
        pGLW->MoveMouse( point.x, point.y );
}

OnDraw中,您将

void CMyView::OnDraw( CDC* /*pDC*/ )
{
    pGLW->PrepareDraw( );
    // Do your drawing here.
    pGLW->RenderDraw( );
}

最后,完成

void CMyView::OnDestroy( )
{
    delete pGLW;
    CView::OnDestroy( );
}

请注意,编译Gaigen文件时会收到警告。忽略它们,它们是无害的。如果Gaigen发布了修复此问题的版本,我将提交新的下载。

Gaigen

这是可选的。项目中包含了用于欧几里得几何的Gaigen生成文件。

The Gaigen Generator

Gaigen 是一个 C++ 文件生成器。它在开发方面快速且方便。您可以在开发 Gaigen 类时一直保持其打开状态。生成后,当您通过 Alt+Tab 切换回 Visual Studio 时,只需让 VS 加载更改的文件并进行编译即可。您可以在 SourceForge 下载 Gaigen。

以下是针对 VS.NET 解决方案的内容。

您将需要 fltk 库。在 gaigenui 项目中,执行以下操作。将“附加包含目录”设置为包含 /FL 目录的目录。从项目中删除 gaigenui.rc。它丢失了,但您不需要它。将链接器的“附加库目录”设置为 fltk 的 lib 目录。在“忽略特定库”中,添加 LIBCD.lib。将所有项目的输出设置为一个公共目录。可执行文件需要放在一起。我将它们放在一个像这样的库中

Sample Gaigen directories

gaigenui.exe 是您想要启动的可执行文件。现在它应该可以运行了,但如果您尝试生成文件,它会崩溃。这里是安装手册的链接我认为您可以使用 src 目录中的 'gaigen_local_install.cpp'(我尚未尝试过)。我已经将环境变量 'GAIGEN_CONFIG' 设置为指向 gaigen.config 文件,该文件似乎也在此版本中丢失。这里是一个副本设置您的代数和可执行文件的目录。但等等!还有更多!在其中一个项目中打开 'enviroment.cpp'。将 #else 之后的初始化器设置为类似这样
char *g_dataDir = "C:\\cpp\\gaigen\\ui_4\\algebras";
char *g_includeDir = "C:\\cpp\\gaigen\\ui_4\\algebras";
char *g_binDir = 
  "C:\\cpp\\gaigen\\ui_4\\lib"; //this must be set to your executables
char *g_algebrasDir = 
  "C:\\cpp\\gaigen\\ui_4\\temp"; //This doesn't seem to have effect

这里我将 src/gaspectemplates.txt 复制到了 algebras/目录。在生成文件之前,转到“generate”选项卡,并设置您希望使用这些文件的项目的目录。如果您遇到任何问题,请立即转到输出窗口查看出了什么问题。这应该能告诉您,您不必进行调试。我在我的项目下载中包含了 'e3ga.gas' 文件。这是我在示例中使用的 GA。如果您认真要使用 Gaigen,您还需要这两本手册

再说一点。Gaigen 似乎有内存泄漏,不是我的问题。我稍微看了一下,但还没找到。生成器的源代码在 gaspectemplates.txt 中。

四元数及其他

几何代数不仅仅用于图形处理。事实上,据我所知,Gaigen 生成器最初是用于科学建模的。但在本文中,我将只关注图形。

在欧几里得空间中,点是“一次项”(grade one blades),也就是来自原点的向量。所以,就像您会做的那样,平移空间并绘制点。在这个例子中,我还绘制了从原点到点的线。这让它看起来像一个真正的装置。

线或向量同样是向量。但它们是无坐标的。将它们置于空间中需要第二个向量。要求基向量垂直于线可能更优雅,但仔细考虑后,并非如此。能够指定任何任意点让线通过要强大得多。我选择绘制向量而不是线。但正如您将在项目中看到的,它们可以同样被当作线来处理。在CGLView::DrawVector成员函数中,我展示了一个将向量转换为旋转器的示例。这样,我就可以将模型矩阵对齐到向量上,然后使用gluCylinder绘制线。

平面是二重向量,或者说“二次项”(grade two blades)。一个二重向量实际上包含比平面所需更多的信息。它包含一个有向幅度。如果您要绘制一个有限的平面,例如一个圆盘,这个幅度就会被使用。对于无限平面,我们关心的是二重向量的有向性。为了进行简单的glVertex3f调用,我将模型矩阵调整到从原点指向法线

旋转器也是二重向量,其作用与四元数相同。美妙之处在于您实际上可以可视化其工作原理。虽然四元数似乎是一些神秘的“四维”函数,但请想想它们实际上做了什么。您有一个明确定义的平面,想要在该平面上旋转一定量。旋转实际上是三维空间中的一个二维子空间!使用旋转器非常简单,并且可以将其应用于任何 GA 对象。您会在项目中找到几个示例。它们通常看起来像这样

e3ga rotatedObject= rotor * origanalObject * !rotor;

看看 wingl.cpp 中的 gaRotateMatrix,其中有一个旋转 OpenGL 矩阵的示例。我包含了您可以打开的跟踪功能来查看其工作过程。因为您可以直接旋转 GA 对象,所以您不需要像使用 glu 和 aux 对象那样旋转模型矩阵来绘制它们。这里有两个 PDF 文件,列出了不同几何图形中的不同对象和操作

绘制平面之前的代码显示了线与平面的交点。绘制反射只需要几行代码,使用旋转器即可完成。交点代码直接来自光线追踪 PDF。Gaigen 丰富地重载了运算符,因此您可以发现实现看起来与公式非常相似。只花了几个小时使用 Gaigen 手册就编写了反射。(这都是在投入一些时间理解 GA 和 Gaigen 之后!)在这里,我将向量当作线来处理。当您运行动画时,您会看到向量从平面反射,就好像它是无限的一样。

您会注意到 GA 对象与 OpenGL 接口是独立存在的。线段的作用(还可以查看 CGLView::OnTimer 中线的动画旋转)仅仅是 GA 数学。OpenGL 仅在渲染时才被考虑。Gaigen 代码中有图形成员,但没有任何实现。这可能永远不会发生,因为保持分离可能不如集成那么灵活。

如果您深入研究,需要注意一点。在 Gaigen 中被称为“法线”(normal)的东西,引用他们的话来说,“是所有坐标平方的总和”。它不是一个正交归一化的对象,而是一个标量。对于常规的法线,您将使用“对偶”(dual)。您将在项目中看到“norm”和“dual”的用法。您会发现对偶与乘以空间的伪标量是相同的。请参见示例中的 DrawVector

本文只打算介绍几何代数,作为四元数和 Plucker 坐标的替代方案。网上关于 GA 的信息很多。这里有两个不错的链接

我曾经有一篇论文,很久以前打印过,但在网上找不到,而且 PDF 也在一个不再使用的驱动器上。这两个网站上都有很多好论文。所以,我不会推荐“一篇”论文,因为每个读者的背景都不同,品味也不同。有些论文在我刚开始时不喜欢,现在看起来却很好。这些可能会适合您

几何代数:几何应用的计算框架

如果您下载光线追踪项目,则不需要 Gaigen。他们已经包含了所有生成的文件。它工作正常,但有一个例外。在 wood.rtm 文件中,有两行留有绝对文件引用。将这两行更改为

diffuse_texture "../files/wood.png"
bumpmap "../files/wood2.png"

谢谢,Dan。

© . All rights reserved.