TMZHJW 发表于 2006-11-9 21:42:49

沙发!很好东西!刚学WINDOWS编程,所以还看不太懂!

JAY 发表于 2006-11-9 21:47:34

会LS,和Windows编程关系不是很大=v=

Anson 发表于 2006-11-10 12:29:08

地板!铺个毯子睡午觉=v=

sky11811 发表于 2006-12-14 20:06:38

搂主的分析十分的透彻,对入门着十分的有用

JAY 发表于 2006-12-14 21:02:19

呃...回楼上,这个貌似不怎么适合入门者,这个至少需要读者对立体几何,向量,线性代数以及OpenGL编程有一定的了解。

FantasyDR 发表于 2006-12-15 00:02:46

想起了shooting的图形学作业=v=

cxstm 发表于 2006-12-16 10:11:17

请问:
// 计算x, y坐标
v = (float)x * 2.0 - (float)d;
v = (float)d - (float)y * 2.0;
这是怎么计算球面X,Y坐标得??
本人新手,有些不明白?
如果鼠标点击位置在球面以外得话,怎么计算呢?
说得不对,别笑话!

JAY 发表于 2006-12-16 11:55:48

回楼上
v实际上等于 x - d / 2,不过因为后面有单位化,所以避免有除法就乘以2了。
x 是鼠标坐标, d / 2是中心横坐标。
v是同样的道理,不过OpenGL里面y坐标是向上为正,而鼠标坐标是屏幕坐标,向下为正,所以要反一下。
如果鼠标在范围以外,必然算不出z来,可以用0来代替z或者忽略这种情况。

cxstm 发表于 2006-12-16 16:54:11

如果我把V,V写成
sqrtxy=sqrt((float)x * (float)x + (float)y * (float)y);
v=x*d/sqrtxy;
v=-y*d/sqrtxy;
是否就是超出范围得情况?我发现它很难旋转,呵呵

JAY 发表于 2006-12-16 17:14:57

v、v和x, y就是直接映射关系不需要别的更复杂的运算~
而且这个只是一个粗略的算法,不是很精确的,只是为了方便调试3D图像,可能会有所不便~

kael 发表于 2006-12-21 18:28:12

JAY,你这些天貌似对图形学着迷了。。。。。。

JAY 发表于 2006-11-9 21:33:28

使用鼠标自由旋转三维图形的算法和思路

不算是原创,看着别的程序的示例代码写出来的原理,供大家分享~

考虑鼠标移动在一个半球面而不是普通的平面,如图所示。

鼠标移动时,不是简单从屏幕上的A点移动到B点,而是在球O上沿着弧AB移动到了B点。
也就是说,向量OA沿着圆O旋转到了向量OB。我们便可以将我们的图形也按照同样的方式进行旋转。
因此我们需要知道的是旋转的角度和旋转的法向量。
步骤:
1.计算鼠标在半球面上的坐标
我们可以通过鼠标在屏幕的平面坐标计算鼠标在半球面上的坐标
假设鼠标的屏幕坐标为(Xs, Ys),半球面坐标为(Xh, Yh, Zh)。显然有
Xh = Xs
Yh = Ys
Zh^2 = r^2–Xh^2–Yh^2
其中r为半球半径,一般可以设置为窗口高度的一半。
这样便可以求出向量OA和向量OB的坐标。

2.计算旋转角度
有了向量OA和向量OB的坐标,利用余弦定理我们可以求得角AOB的大小,不过这个计算很复杂,开销很大。
我们可以考虑用A到B的球面距离,即 弧AB的长度 / 圆O的周长 * 360度。
不过弧长也不是那么好算,好在每次鼠标移动的间隔都不大,我们可以简单的使用弦AB的距离来近似弧AB的长度。
因此我们的算法变得很简单。
角AOB = 弦AB的长度 / 圆O的周长 * 360度
弦AB的长度可以用两点间距离公式求得,即 d^2 = (Xa-Xb)^2+(Ya-Yb)^2+(Za-Zb)^2。

3.计算旋转法向量
旋转法向量n是垂直于向量OA和向量OB所决定的平面的,所以只需要求得向量OA与向量OB的外积(也就是叉乘),就可求得旋转法向量n。
即 n = OA×OB。

4.OpenGL的矩阵乘法
有了旋转角度和旋转的法向量就可以使用glRotate函数来旋转图形了,不过这里有一点需要注意的地方:
例如我们旋转一个图形:

glLoadIdentity();
glRotatef(theta, axis, axis, axis);
drawCube();

在这里的glRotate函数实际是产生了一个旋转矩阵,并将其右乘到当前矩阵上,所以当前矩阵的变化为:M = E·R。
如果我们绘制的图形的某一点是P,那么它在绘制时候,将被旋转到点P' = M·P = E·R·P。
当我们第二次旋转的时候,glRotate函数又产生来一新的旋转矩阵R',它再次被右乘到当前矩阵上,所以当前矩阵的变化为:M = E·R·R'。
那么当我们再次绘制图形时,P点将被旋转到P' = M·P = E·R·R'·P。
此时我们发现P点实际上是先按照第二次的旋转矩阵旋转,再按照第一次的旋转,与我们想要的结果刚好相反。
因此我们需要将每一次的旋转矩阵左乘到当前矩阵上,所以我们需要下面的步骤:

glLoadIdentity();
glRotatef(theta, axis, axis, axis);
glMultMatrixf(lastMatrix);
glGetFloatv(GL_MODELVIEW_MATRIX, lastMatrix);

我们用lastMatrix保存当前矩阵,然后将其右乘到新的旋转矩阵上,实际相当于将新的旋转矩阵左乘到当前矩阵上,这样做了之后才能实现我们想要的目的。

下面这个是编译好的示例程序及源代码:点击下载

sdasfjk 发表于 2008-2-24 21:15:48

1111

1111111111111111111111111111111
页: [1]
查看完整版本: 使用鼠标自由旋转三维图形的算法和思路