一点小疑问

简介:
记得我第一次看Nehe教程里第9课的时候,就被他下面这段代码弄晕了:
glRotatef(tilt,1.0f,0.0f,0.0f);                    // Tilt The View (Using The Value In 'tilt')
        glRotatef(star[loop].angle,0.0f,1.0f,0.0f);        // Rotate To The Current Stars Angle
        glTranslatef(star[loop].dist,0.0f,0.0f);        // Move Forward On The X Plane
        glRotatef(-star[loop].angle,0.0f,1.0f,0.0f);    // Cancel The Current Stars Angle
        glRotatef(-tilt,1.0f,0.0f,0.0f);                // Cancel The Screen Tilt

他给出的解释更是让我摸不着头脑:
现在我们来移动星星。星星开始时位于屏幕的中心。我们要做的第一件事是把场景沿Y轴旋转。如果我们旋转90度的话,X轴不再是自左至右的了,他将由里向外穿出屏幕。为了让大家更清楚些,举个例子。假想您站在房子中间。再设想您左侧的墙上写着-x,前面的墙上写着-z,右面墙上就是+x咯,您身后的墙上则是+ z。加入整个房子向右转90度,但您没有动,那么前面的墙上将是-x而不再是-z了。所有其他的墙也都跟着移动。-z出现在右侧,+z出现在左侧,+x出现在您背后。神经错乱了吧?通过旋转场景,我们改变了x和z平面的方向。
第二行代码沿x轴移动一个正值。通常x轴上的正值代表移向了屏幕的右侧(也就是通常的x轴的正向),但这里由于我们绕y轴旋转了坐标系,x轴的正向可以是任意方向。如果我们转180度的话,屏幕的左右侧就镜像反向了。因此,当我们沿 x轴正向移动时,可能向左,向右,向前或向后。
接着的代码带点小技巧。星星实际上是一个平面的纹理。现在您在屏幕中心画了个平面的四边形然后贴上纹理,这看起来很不错。一切都如您所想的那样。但是当您当您沿着y轴转上个90度的话,纹理在屏幕上就只剩右侧和左侧的两条边朝着您。看起来就是一条细线。这不是我们所想要的。我们希望星星永远正面朝着我们,而不管屏幕如何旋转或倾斜。
我们通过在绘制星星之前,抵消对星星所作的任何旋转来实现这个愿望。您可以采用逆序来抵消旋转。当我们倾斜屏幕时,我们实际上以当前角度旋转了星星。通过逆序,我们又以当前角度"反旋转"星星。也就是以当前角度的负值来旋转星星。就是说,如果我们将星星旋转了10度的话,又将其旋转-10度来使星星在那个轴上重新面对屏幕。下面的第一行抵消了沿y轴的旋转。然后,我们还需要抵消掉沿x轴的屏幕倾斜。要做到这一点,我们只需要将屏幕再旋转-tilt倾角。在抵消掉x和y轴的旋转后,星星又完全面对着我们了。
 
今天又复习到这一课了,还是理解不了他干嘛要旋转坐标轴,接着又逆向旋转回去,就和susu讨论了下:
phinecos 15:53:12
我感觉他是多余了,我修改了下代码
phinecos 15:53:22
效果也差不多呀
susu 15:53:31
是不是仅在距离上有点变化
phinecos 15:53:38
        //glRotatef(tilt,1.0f,0.0f,0.0f);                    // Tilt The View (Using The Value In 'tilt')
        glRotatef(star[loop].angle,0.0f,0.0f,1.0f);        // Rotate To The Current Stars Angle

        glTranslatef(star[loop].dist,0.0f,0.0f);        // Move Forward On The X Plane

    //    glRotatef(-star[loop].angle,0.0f,1.0f,0.0f);    // Cancel The Current Stars Angle
    //    glRotatef(-tilt,1.0f,0.0f,0.0f);                // Cancel The Screen Tilt
susu 15:53:49
我看他唯一没有抵消的快乐能是dist了
phinecos 15:54:17
没必要抵消嘛,他把坐标轴转了个90度,我认为没必要
susu 15:54:31
是啊,转来转去的
phinecos 15:54:41
glRotatef(star[loop].angle,0.0f,0.0f,1.0f);    
glTranslatef(star[loop].dist,0.0f,0.0f);        
phinecos 15:55:05
我就这两句,让星星围着z轴转个角度,再平移个距离
susu 15:55:32
那又没有那个四边形没有正对着照相机?
phinecos 15:56:05
好像没有呀
phinecos 15:56:21
我再比对下效果看看
susu 15:56:27
对,前面坐标轴没有动
phinecos 15:56:44
哪个坐标轴没动呢?
susu 15:57:01
//glRotatef(tilt,1.0f,0.0f,0.0f);
phinecos 15:57:38
这个坐标轴转个90度到底有啥用处吗?让四边形对着视点?
phinecos 15:58:02
它这是绕x轴转90度,我想不通
susu 15:58:11
对阿
phinecos 15:59:10
绕x轴转90度,那y,z轴就互换了,对吗?
susu 15:59:26
phinecos 15:59:34
这里转90度,是坐标轴转,还是物体转呢?
phinecos 15:59:42
我认为是坐标轴呢
susu 15:59:46
坐标轴吧
phinecos 16:00:31
那y,z轴既然已经换了,那这句:glRotatef(star[loop].angle,0.0f,1.0f,0.0f);    // 旋转至当前所画星星的角度;到底是围着哪条轴转的?
phinecos 16:01:02
本来应该是绕y轴,可现在z轴在它的位置上,不是变绕z了?
susu 16:01:09
应该是
phinecos 16:02:06
glTranslatef(star[loop].dist,0.0f,0.0f);    // 沿X轴正向移动,这里又绕x轴平移,本来x轴就没动过,所以前面做的坐标轴变换不是白搭了。。。
phinecos 16:02:37
我试下两种代码的效果区别先
susu 16:02:45
是啊
phinecos 16:05:42
汗,我是看不出效果的区别。。。
susu 16:06:00
呵呵
susu 16:06:14
glTranslatef(star[loop].dist,0.0f,0.0f);是不是只做了一遍
phinecos 16:06:28
恩,是的
susu 16:06:43
它应该是使星星分散开的
susu 16:06:58
想明白就可以了,呵呵
phinecos 16:07:08
哦,那下面还有的:        star[loop].dist-=0.01f;
        if (star[loop].dist<0.0f)
        {
            star[loop].dist+=5.0f;
            star[loop].r=rand()%256;
            star[loop].g=rand()%256;
            star[loop].b=rand()%256;
        }
phinecos 16:07:23
先让它归中,然后抛出去
susu 16:07:34
形成动画
phinecos 16:08:01
恩,我修改后的代码和Nehe的效果没什么区别,但没有刚才那么难理解了
phinecos 16:08:15
刚才它旋转来,又旋转回去,晕掉了
susu 16:08:16
呵呵,他可能当时有点晕了

我觉得他先把坐标轴绕X轴转了个90度,这不就让y,z轴互换了吗?再让四边形绕y轴(我理解这里应该是旋转后的z轴了)转自己的角度,最后平移自己到中心的距离,可最终他又反向旋转回去,真是让人晕,那这样旋转坐标轴到底有什么用处呢?不转还不是一样,我下面就修改了他的代码,根本不去转那个该死的坐标轴,好像最终效果也差不多呀:
    glRotatef(star[loop].angle,0.0f,0.0f,1.0f);        // Rotate To The Current Stars Angle
        glTranslatef(star[loop].dist,0.0f,0.0f);        // Move Forward On The X Plane

我就让星星绕Z轴转自己的角度,再绕X轴平移自己距中心的距离,这样有什么问题呢?至少我是想不通。。。


本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2007/08/07/846476.html,如需转载请自行联系原作者
目录
相关文章
|
6天前
|
存储 关系型数据库 分布式数据库
PostgreSQL 18 发布,快来 PolarDB 尝鲜!
PostgreSQL 18 发布,PolarDB for PostgreSQL 全面兼容。新版本支持异步I/O、UUIDv7、虚拟生成列、逻辑复制增强及OAuth认证,显著提升性能与安全。PolarDB-PG 18 支持存算分离架构,融合海量弹性存储与极致计算性能,搭配丰富插件生态,为企业提供高效、稳定、灵活的云数据库解决方案,助力企业数字化转型如虎添翼!
|
17天前
|
弹性计算 关系型数据库 微服务
基于 Docker 与 Kubernetes(K3s)的微服务:阿里云生产环境扩容实践
在微服务架构中,如何实现“稳定扩容”与“成本可控”是企业面临的核心挑战。本文结合 Python FastAPI 微服务实战,详解如何基于阿里云基础设施,利用 Docker 封装服务、K3s 实现容器编排,构建生产级微服务架构。内容涵盖容器构建、集群部署、自动扩缩容、可观测性等关键环节,适配阿里云资源特性与服务生态,助力企业打造低成本、高可靠、易扩展的微服务解决方案。
1327 7
|
5天前
|
存储 人工智能 Java
AI 超级智能体全栈项目阶段二:Prompt 优化技巧与学术分析 AI 应用开发实现上下文联系多轮对话
本文讲解 Prompt 基本概念与 10 个优化技巧,结合学术分析 AI 应用的需求分析、设计方案,介绍 Spring AI 中 ChatClient 及 Advisors 的使用。
300 129
AI 超级智能体全栈项目阶段二:Prompt 优化技巧与学术分析 AI 应用开发实现上下文联系多轮对话
|
4天前
|
监控 JavaScript Java
基于大模型技术的反欺诈知识问答系统
随着互联网与金融科技发展,网络欺诈频发,构建高效反欺诈平台成为迫切需求。本文基于Java、Vue.js、Spring Boot与MySQL技术,设计实现集欺诈识别、宣传教育、用户互动于一体的反欺诈系统,提升公众防范意识,助力企业合规与用户权益保护。
|
16天前
|
机器学习/深度学习 人工智能 前端开发
通义DeepResearch全面开源!同步分享可落地的高阶Agent构建方法论
通义研究团队开源发布通义 DeepResearch —— 首个在性能上可与 OpenAI DeepResearch 相媲美、并在多项权威基准测试中取得领先表现的全开源 Web Agent。
1396 87
|
4天前
|
JavaScript Java 大数据
基于JavaWeb的销售管理系统设计系统
本系统基于Java、MySQL、Spring Boot与Vue.js技术,构建高效、可扩展的销售管理平台,实现客户、订单、数据可视化等全流程自动化管理,提升企业运营效率与决策能力。
|
5天前
|
人工智能 Java API
AI 超级智能体全栈项目阶段一:AI大模型概述、选型、项目初始化以及基于阿里云灵积模型 Qwen-Plus实现模型接入四种方式(SDK/HTTP/SpringAI/langchain4j)
本文介绍AI大模型的核心概念、分类及开发者学习路径,重点讲解如何选择与接入大模型。项目基于Spring Boot,使用阿里云灵积模型(Qwen-Plus),对比SDK、HTTP、Spring AI和LangChain4j四种接入方式,助力开发者高效构建AI应用。
298 122
AI 超级智能体全栈项目阶段一:AI大模型概述、选型、项目初始化以及基于阿里云灵积模型 Qwen-Plus实现模型接入四种方式(SDK/HTTP/SpringAI/langchain4j)
|
5天前
|
弹性计算 安全 数据安全/隐私保护
2025年阿里云域名备案流程(新手图文详细流程)
本文图文详解阿里云账号注册、服务器租赁、域名购买及备案全流程,涵盖企业实名认证、信息模板创建、域名备案提交与管局审核等关键步骤,助您快速完成网站上线前的准备工作。
232 82
2025年阿里云域名备案流程(新手图文详细流程)