OpenGL观察轴
旋转矩阵可以通过观察向量构造,观察向量可以是3D空间的两个或三个点。如果一个处于P1点的对象面向P2点,则观察向量就是P2-P1,如下图:
首先,前轴向量通过归一化的观察向量简单计算而来。
其次,左轴通过指定向上方向向量与前轴的差乘计算而来。向上方向向量用于确定对象的roll角度。并且她不必与前轴垂直。如果我们不考虑对象的roll旋转,我们可以使用(0,1,0)。这就是说对象始终向上站立着。
实际上,与前轴与左轴都正交的上轴向量可以动过另外前轴与左轴向量的差乘计算出来。为了拥有单位长度的向量,左轴与上轴在差乘之后需要归一化。
下面是从观察向量计算左轴、上轴与前轴的C++代码。第一段代码块是Vector3结构体变量的最简便实现。第二代码块从两点(位置与目标向量)计算3个轴。最后一个代码块从3点(位置、目标向量与向上向量)计算3轴。
// Vector3结构体的最简化实现
struct Vector3
{
float x;
float y;
float z; Vector3() : x(0), y(0), z(0) {}; // 构造函数
Vector3(float x, float y, float z) : x(x), y(y), z(z) {}; // 函数
Vector3& normalize(); //
Vector3 operator-(const Vector3& rhs) const; // 减法
Vector3 operator*(const Vector3& rhs) const; // 差乘
Vector3& operator*=(const float scale); // 缩放与更新
}; Vector3& Vector3::normalize() {
float invLength = 1 / sqrtf(x*x + y*y + z*z);
x *= invLength;
y *= invLength;
z *= invLength;
return *this;
} Vector3 Vector3::operator-(const Vector3& rhs) const {
return Vector3(x-rhs.x, y-rhs.y, z-rhs.z);
} Vector3 Vector3::cross(const Vector3& rhs) const {
return Vector3(y*rhs.z - z*rhs.y, z*rhs.x - x*rhs.z, x*rhs.y - y*rhs.x);
}
///////////////////////////////////////////////////////////////////////////////
// 从对象的位置与目标点计算变换轴
///////////////////////////////////////////////////////////////////////////////
void lookAtToAxes(const Vector3& position, const Vector3& target,
Vector3& left, Vector3& up, Vector3& forward)
{
// 计算前向量
forward = target - position;
forward.normalize(); // 基于前向量计算临时上向量
// 注意向上/下观察角度为90°的情况
// 例如:前向量在Y轴上
if(fabs(forward.x) < EPSILON && fabs(forward.z) < EPSILON)
{
// 前向量指向+Y轴
if(forward.y > 0)
up = Vector3(0, 0, -1);
// 前向量指向-Y轴
else
up = Vector3(0, 0, 1);
}
// 通常情况上向量为直立的
else
{
up = Vector3(0, 1, 0);
} // 计算左向量
left = up.cross(forward); // cross product
left.normalize(); // 重新计算正交化的上向量
up = forward.cross(left); // 差乘
up.normalize();
}
///////////////////////////////////////////////////////////////////////////////
// 从位置、目标与向上方向计算变换轴
///////////////////////////////////////////////////////////////////////////////
void lookAtToAxes(const Vector3& pos, const Vector3& target, const Vector3& upDir,
Vector3& left, Vector3& up, Vector3& forward)
{
// 计算前向量
forward = target - pos;
forward.normalize(); // 计算左向量
left = upDir.cross(forward); // 差乘
left.normalize(); // 计算正交化的上向量
up = forward.cross(left); // 差乘
up.normalize();
}
英文原文:http://www.songho.ca/opengl/gl_lookattoaxes.html
OpenGL观察轴的更多相关文章
- OpenGL角轴
概述 轴旋转 角轴 概述 OpenGL旋转矩阵 旋转角度直接影响OpenGL GL_MODELVIEW矩阵的前三列,准确地说是向左.向上与向前三轴元素.例如,如果一沿X轴的单位向量(1,0,0)与任一 ...
- OpenGL变换
概述 OpenGL变换矩阵 实例:GL_MODELVIEW矩阵 实例:GL_PROJECTION矩阵 概述 OpenGL管线中,在光栅化操作之前,包括顶点位置与法线向量的几何数据经顶点操作与图元装配操 ...
- OpenGL变换【转】
http://www.cnblogs.com/hefee/p/3811099.html OpenGL变换 概述 OpenGL变换矩阵 实例:GL_MODELVIEW矩阵 实例:GL_PROJECTIO ...
- 《Real Time Rendering》第四章 图形变换
图形变换是一个将例如点.向量或者颜色等实体进行某种转换的操作.对于计算机图形学的先驱者,掌握图形变换是极为重要的.有了他们,你就可以对象.光源以及摄像机进行定位,变形以及动画添加.你也可以确认所有的计 ...
- cocos2d-x CCNode类
文章引用自http://blog.csdn.net/qiurisuixiang/article/details/8763260 1 CCNode是cocos2d-x中一个非常重要的类.CCNode是场 ...
- [cocos2d-x] --- CCNode类详解
Email : awodefeng@163.com 1 CCNode是cocos2d-x中一个很重要的类,CCNode是场景.层.菜单.精灵等的父类.而我们在使用cocos2d-x时,接触最多的就是场 ...
- TETeLasr Cutting System 开机回零问题
TETeLasr Cutting System 开机回零问题 :打开 "轴信息" :打开 加工参数-->机器参数-->脉冲当量: X轴==4000 Y轴== ...
- cocos2d CCNode类(节点属性大全)
1 CCNode是cocos2d-x中一个很重要的类,CCNode是场景.层.菜单.精灵等的父类.而我们在使用cocos2d-x时,接触最多的就是场景.层.菜单.精灵等.所以有必要先弄懂CCNode类 ...
- OpenGL的几何变换4之内观察全景图
上一次写了OpenGL的几何变换3之内观察全景图 上次采用的是图片分割化方式,这次采用数据分割化方式. 先说下思路,数据分割化方式呢,是只读取一张图片imgData,然后通过glTexCoord2f( ...
随机推荐
- Delphi编译的程序如何获取管理员权限
1.制作manifest文件 <?xml version="1.0" encoding="UTF-8" standalone="yes" ...
- Multivariance Linear Regression练习
%% 方法一:梯度下降法 x = load('E:\workstation\data\ex3x.dat'); y = load('E:\workstation\data\ex3y.dat'); x = ...
- 探索javascript----拖拽
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 网络电视精灵~分析~~~~~~简单工厂模式,继承和多态,解析XML文档,视频项目
小总结: 所用技术: 01.C/S架构,数据存储在XML文件中 02.简单工厂模式 03.继承和多态 04.解析XML文档技术 05.深入剖析内存中数据的走向 06.TreeView控件的使用 核心: ...
- Linux 下安装Source Insight
第一步: 安装Wine 下面跟大家分享一下如何在Ubuntu 12.04上安装Wine 1).添加PPA -- PPA:表示 Personal Package Archives,也就是个人软件包集. ...
- 码农带你区分String类型的"=="和equals()
大家玩csdn也可以关注我的博客额http://blog.csdn.net/wujiandong25253344 情形一: String s1= new String("hello" ...
- 单例模式(Java)
//单例模式 public class Singleton { private static Singleton s; private Singleton(){ } public static Sin ...
- soj1001算法分析
题目简单描述: 给定一个长数串,输出可能的字母串解个数.(A对应1,Z对应26) 样例输入:25114 样例输出:6 样例解释:可能的字母串解:YJD.YAAD.YAN.BEJD.BEAAD.BEAN ...
- win系统登录密码重置
[1]制作PE启动盘,参考 http://jingyan.baidu.com/article/72ee561aadfb1fe16138dfab.html [2]拿PE启动盘启动电脑,重置密码,参考 h ...
- BZOJ 1040 树形DP+环套树
就是有n个点n条边,那么有且只有一个环那么用Dfs把在环上的两个点找到.然后拆开,从这条个点分别作树形Dp即可. #include <cstdio> #include <cstrin ...