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( ...
随机推荐
- js③
while(true){ console.log('hello'); }/每次执行完语句块之后,又会跳回去检查小括号里面的布尔值,如果为true,那么又会执行语句块一次. //while循环//var ...
- 几种通过JDBC操作数据库的方法,以及返回数据的处理
1.SQL TO String :只返回一个查询结果 例如查询某条记录的总数 rs = stmt.executeQuery(replacedCommand); if (rs ! ...
- Java Base64 类
package org.yp.ypfinancing.core.service.payV2.domain.service.Sdp.utils; public final class Base64 { ...
- 通过声明Attribute属性改变不同类的输出效果
ConsoleApplication--控制台应用程序 首先创建基类: using System; using System.Collections.Generic; using System.Lin ...
- iOS 3D Touch 适配开发
3D Touch的主要应用 文档给出的应用介绍主要有两块: 1.A user can now press your Home screen icon to immediately access fun ...
- GeoHash原理解析
GeoHash 核心原理解析 引子 一提到索引,大家脑子里马上浮现出B树索引,因为大量的数据库(如MySQL.oracle.PostgreSQL等)都在使用B树.B树索引本质上是对索引字段 ...
- iOS学习之cocoaPods
Cocoapods Cocoapods作用:iOS开发时,项目中会引用许多第三方库,CocoaPods可以用来方便的统一管理这些第三方库. 第一步安装: 下载安装CocoaPods需要Ruby环境 M ...
- 使用Mybatis-Generator自动生成Dao、Model、Mapping代码
1.所需jar包 mybatis-generator-core-1.3.2.jar mybatis-generator-core-1.3.2.jar 可以去http://mvnrepository.c ...
- NOIP 赛前模拟记录
8.11 T1 给定一个序列M,求出能过构造出的序列使得(Si+Si+1)/2=Mi成立的序列个数.保证M,S递增. T2 平面点集中最大的四边形面积 T3 不太懂得一道国家队选拔的加强版. 90+2 ...
- 一个简单的app自动登录Python脚本案例