将立方体转换到openGL中的球体表面 [英] Transform cube on to surface of sphere in openGL

查看:173
本文介绍了将立方体转换到openGL中的球体表面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在制作一个渲染纹理球体(代表地球)和立方体代表球员模型的游戏(稍后将实施)。 用户点击球体上的一个点,立方体从原点(0,0,0)(也是球体的中心)转换到球体表面上的点。



问题是我希望立方体旋转,以便将它的底部平放在球体表面上(而不仅仅是转换立方体)。

最好的方法是计算每个轴的旋转矩阵以获得这种效果? 与您制作lookat矩阵的计算方法相同。

在这种形式中,您可以将球体上的归一化点作为一个轴用作'Z'轴),然后将其他两个作为垂直向量。通常要做到这一点,您需要选择一些任意的向上轴,它不需要平行于第一轴,然后使用两个交叉产品。首先你穿过'Z'和'向上'做一个'X'轴,然后穿过'X'和'Z'轴做一个'Y'轴。

X,Y和Z轴(标准化)形成一个旋转矩阵,将立方体定向到球体的法线面。然后把它翻译成表面点。



GL的基本思想是:

  float x_axis [3]; 
float y_axis [3];
float z_axis [3]; //这是球体上的点,标准化

x_axis = cross(z_axis,up);
正常化(x_axis);
y_axis = cross(z_axis,x_axis);

DrawSphere();

float mat [16] = {
x_axis [0],x_axis [1],x_axis [2],0,
y_axis [0],y_axis [1], y_axis [2],0,
z_axis [0],z_axis [1],z_axis [2],0,
(sphereRad + cubeSize)* z_axis [0],(sphereRad + cubeSize)* z_axis [1],(sphereRad + cubeSize)* z_axis [2],1};

glMultMatrixf(mat);

DrawCube();

其中 z_axis [] 是归一化点在该球体上, x_axis [] 是该向量与任意'向上'向量的归一化叉积,并且 y_axis [] 是另外两个轴的归一化叉积。 sphereRad cubeSize 是球体和立方体的大小 - 我假定两个形状都以其局部坐标为中心原产地。


I'm currently working on a game which renders a textured sphere (representing Earth) and cubes representing player models (which will be implemented later).

When a user clicks a point on the sphere, the cube is translated from the origin (0,0,0) (which is also the center of the sphere) to the point on the surface of the sphere.

The problem is that I want the cube to rotate so as to sit with it's base flat on the sphere's surface (as opposed to just translating the cube).

What the best way is to calculate the rotation matrices about each axis in order to achieve this effect?

解决方案

This is the same calculation as you'd perform to make a "lookat" matrix.

In this form, you would use the normalised point on the sphere as one axis (often used as the 'Z' axis), and then make the other two as perpendicular vectors to that. Typically to do that you choose some arbitrary 'up' axis, which needs to not be parallel to your first axis, and then use two cross-products. First you cross 'Z' and 'Up' to make an 'X' axis, and then you cross the 'X' and 'Z' axes to make a 'Y' axis.

The X, Y, and Z axes (normalised) form a rotation matrix which will orient the cube to the surface normal of the sphere. Then just translate it to the surface point.

The basic idea in GL is this:

float x_axis[3];
float y_axis[3];
float z_axis[3]; // This is the point on sphere, normalised

x_axis = cross(z_axis, up);
normalise(x_axis);
y_axis = cross(z_axis, x_axis);

DrawSphere();

float mat[16] = {
    x_axis[0],x_axis[1],x_axis[2],0,
    y_axis[0],y_axis[1],y_axis[2],0,
    z_axis[0],z_axis[1],z_axis[2],0,
    (sphereRad + cubeSize) * z_axis[0], (sphereRad + cubeSize) * z_axis[1], (sphereRad + cubeSize) * z_axis[2], 1 };

glMultMatrixf(mat);

DrawCube();

Where z_axis[] is the normalised point on the sphere, x_axis[] is the normalised cross-product of that vector with the arbitrary 'up' vector, and y_axis[] is the normalised cross-product of the other two axes. sphereRad and cubeSize are the sizes of the sphere and cube - I'm assuming both shapes are centred on their local coordinate origin.

这篇关于将立方体转换到openGL中的球体表面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆