三维模型的取点问题。
要做的是把鼠标所在点映射到模型上去,取出所在点的坐标显示出来。
我用了syy64(太平洋)兄提供的代码。使用gluUnProject()函数取物体坐标。
这些都没有问题。
但是我取出来的坐标值差得太多了。 x、y的值总在正负几十之间变化,但是我的模型是0到13000(x坐标)。还有,如果我把模型转动的话,同一个点(模型上)的x、y、z的值应该是不变的,但是这些值是相对屏幕固定的,就是说,左边的总是负值,右边的总是正值。它根本就没有跟着模型转。
搞不定了,请高手帮忙。
问题点数:0、回复次数:32Top
1 楼zzwu(未名)回复于 2004-11-03 08:26:24 得分 0
你的误差我认为完全合理,正常的,无法再减小。
因为,这是由于你的模型分辨率大大高于屏幕本身分辨率引起的.
你要减少误差,除非把你的模型的大小设置成和屏幕上看到的模型的像素级大小一样才行.
因屏幕本身大小(分辨率)可能是800*600,而你的模型在屏幕上只占了一部分,算它640*480,
如果你能把模型的大小设置成640*480,而不是不是13000*XXXX,则误差就可以缩小为正负1了。
而你现在实际模型,单从x方向看,就已超过640*480的20倍,所以误差也至少要扩大20倍,变成正
负20以上,是完全合理的.
Top
2 楼syy64(太平洋)回复于 2004-11-03 10:48:00 得分 0
在放大状态才能精度高;
http://community.csdn.net/Expert/topic/3498/3498322.xml?temp=.8563959
http://community.csdn.net/Expert/topic/3468/3468693.xml?temp=.8914606
http://community.csdn.net/Expert/topic/3367/3367641.xml?temp=.1536676
Top
3 楼czmissyou(海中石)回复于 2004-11-03 20:47:07 得分 0
为了不麻烦大家,
我先研究一下太平洋兄给的那几个连接。Top
4 楼czmissyou(海中石)回复于 2004-11-08 20:25:14 得分 0
不行啊,还是没有搞正确。
就算数值的偏差是由于误差原因。但是坐标不跟着模型转就不对了。
我的意思是:物体上的同一个点不论你怎么旋转,平移模型,他的物体坐标是不能变的。但是,我把模型旋转180度,就是从左边转到右边,坐标就由正值变成了负值。这显然是错误的。Top
5 楼syy64(太平洋)回复于 2004-11-08 22:13:12 得分 0
应该是错的,你更kiang和pan7861交流一下,他们作过。Top
6 楼czmissyou(海中石)回复于 2004-11-09 20:10:24 得分 0
怎么和他们联系啊?Top
7 楼syy64(太平洋)回复于 2004-11-10 08:45:40 得分 0
给他们发短消息,你提我他们就知道了。Top
8 楼czmissyou(海中石)回复于 2004-11-10 16:52:04 得分 0
郁闷啊,我给他们俩都发了短消息,但是没有一个人回我。Top
9 楼kiang(菜鸟)回复于 2004-11-10 22:01:59 得分 0
^_^ :)不好意思 今天才看到消息.
你能不能把你 旋转座标轴,
跟提取座标的流程写一下阿.
是不会是你提取得 就是旋转之后的座标.Top
10 楼syy64(太平洋)回复于 2004-11-11 16:23:49 得分 0
我出差了,在广州Top
11 楼czmissyou(海中石)回复于 2004-11-11 21:14:17 得分 0
具体说起来的话,一下子说不明白。我把我的程序源代码放到一个邮箱里,麻烦kiang 和 太平洋看看好吗?看看我的问题出在哪里?
其他人如果有兴趣当然可以一起研究一下,很欢迎的。
邮箱:sunpursuer@126.com
密码:sunpursuer
邮箱里有一个Mesh文件夹,(先点左边的那个文件夹链接)
我还写了一些说明,如果还有什么不清楚的可以问我。Top
12 楼kiang(菜鸟)回复于 2004-11-12 09:05:40 得分 0
太平洋 老大, 怎么以前还是红星闪闪呢 , 现在绿了,信誉也低了。
CSDN 真不是玩意, 你是我碰到的 最热心的一个 大侠 :)
就算帮忙顶帖吧:)Top
13 楼happy__888([顾问团]寻开心 www.e-jjj.com)回复于 2004-11-12 10:10:10 得分 0
坐标不对,应该是没有考虑到world变换矩阵
unproject只是把屏幕空间的点,变换为world空间下的向量
如果你对模型施加了移动,旋转或者是缩放变换,就需要再次利用这个变换的逆矩阵,把world空间下的向量变换到模型的local空间当中去计算
从描述上感觉,你对物体施加了变换,但是没有对从屏幕空间到world空间的向量做逆变换
因为模型是旋转的,所以你不使用这个变换依然可以做求交计算,但是结果就是错误的了.
Top
14 楼pan7861()回复于 2004-11-12 10:47:46 得分 0
是这样的,绘制图元的使用首先要装载名称,比如
glloadname(linename);
glBegin(gl_lines);
glvertex3f(x,y,z);
glvertex3f(x1,x2,x3);
glEnd();
至于鼠标捕获图元位置坐标的转换如下
//这个函数是处理鼠标捕获位置的地方,与书上代码一样
void CMy3DMoveView::ProcessSelection(int xPos,int yPos)
{
GLfloat nRange=10.0f;
VECTORLINE::iterator linePos;
GLuint selectBuff[BUFFER_LENGTH];
GLint hits,viewport[4];
glSelectBuffer(BUFFER_LENGTH,selectBuff);
glGetIntegerv(GL_VIEWPORT,viewport);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glRenderMode(GL_SELECT);
glLoadIdentity();
gluPickMatrix(xPos,viewport[3] - yPos,2,2,viewport);
// gluPerspective(45.0f,fAspect,1.0,425.0);
if(m_icx<=m_icy)
glOrtho(-nRange,nRange,-nRange*m_icy/m_icx,nRange*m_icy/m_icx,-30.0f,30.0f);
else
glOrtho(-nRange*m_icx/m_icy,nRange*m_icx/m_icy,-nRange,nRange,-30.0f,30.0f);
LookOneView();//书上代码是RenderScene()函数
hits = glRenderMode(GL_RENDER);
if(hits == 1)
{
// ProcessPlanet(selectBuff);//该处是显示捕获节点信息,直接把点序号显示就可以了,没详细写.
}
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
}
Top
15 楼czmissyou(海中石)回复于 2004-11-13 10:24:26 得分 0
对的,整个模型随时都会有变换的,旋转,平移,缩放都用鼠标控制。
如果我对模型已经做了:
glTranslated(m_xTranslation,m_yTranslation,m_zTranslation);
glRotatef(m_xRotation, 1.0, 0.0, 0.0);
glRotatef(m_yRotation, 0.0, 1.0, 0.0);
glRotatef(m_zRotation, 0.0, 0.0, 1.0);
glScalef(m_xScaling,m_yScaling,m_zScaling);
我用gluUnProject函数取出来的坐标是p(p 是一数据结构,p.x,p.y,p.z分别为x,y,z坐标)
那我下面怎么样做变换?Top
16 楼happy__888([顾问团]寻开心 www.e-jjj.com)回复于 2004-11-15 12:12:51 得分 0
把gluUnproject变换出来的坐标,用你的变换矩阵的逆矩阵处理一下,才可以得到模型上的点坐标的Top
17 楼czmissyou(海中石)回复于 2004-11-15 20:03:05 得分 0
这样得出来的结果是准确的吗?
这个东西需要很高的精度,不知道有谁做过这方面的东西,给我说一说你们是怎么做的?
是不是还得自己用逆矩阵去乘?没有相关的函数吧?Top
18 楼happy__888([顾问团]寻开心 www.e-jjj.com)回复于 2004-11-16 10:16:54 得分 0
结果肯定是准确的
你不必自己去求逆矩阵的,直接利用gluUnProject函数
gluUnProject里面的 modelMatrix参数设置成你对物体进行变换后的矩阵就可以了
gluUnProject函数不是需要投影矩阵, 视矩阵和模型矩阵三个矩阵作为参数的嘛
你把显示物体所使用的这三个矩阵都赋给它就可以了
常规的情况下,也就是模型没有做移动,旋转和缩放等变换时候的,modelmatrix是单位矩阵,但是做了这些变换后就不是了.
gluUnProject会利用这个矩阵自己计算出来模型局部坐标系下的坐标的Top
19 楼syy64(太平洋)回复于 2004-11-16 16:36:00 得分 0
出差刚回来;
to kiang:不是CSDN错了,是在两个大类中,这是专题开发。Top
20 楼czmissyou(海中石)回复于 2004-11-16 20:45:43 得分 0
按照你这个说法,那我应该是取了模型矩阵:
glGetIntegerv(GL_VIEWPORT, iViewPort);
glPushMatrix();
glGetDoublev(GL_MODELVIEW_MATRIX, dModelMatrix);
glGetDoublev(GL_PROJECTION_MATRIX, dProjMatrix);
glReadPixels(point.x, iViewPort[3]-point.y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &fdepth);
gluUnProject((GLdouble)point.x,
(GLdouble)(iViewPort[3]-point.y),
(GLdouble)fdepth,
dModelMatrix,
dProjMatrix,
iViewPort,
&ObjectX,
&ObjectY,
&ObjectZ);
微软真是无聊,对OpenGL的函数说得真TM简单。happy__888,我这个取出来之后,就应该是模型的局部坐标了吧,但是取出来的坐标就会出现上面的问题。
太平洋兄,出差辛苦吧?Top
21 楼syy64(太平洋)回复于 2004-11-17 08:40:13 得分 0
还行吧,同学集会,你的邮箱在哪个网站?Top
22 楼czmissyou(海中石)回复于 2004-11-17 19:54:00 得分 0
对不起,忘了告诉大家了。
是mail.126.com
username 和 password 都是:sunpursuerTop
23 楼syy64(太平洋)回复于 2004-11-18 09:49:50 得分 0
程序我看了,取坐标的地方我看没错,而是你在画模型的时候用了比例缩放函数glScale函数,你应该通过平移函数和视点和模型点的变化来设置场景,不要用缩放函数来放大和缩小场景。Top
24 楼czmissyou(海中石)回复于 2004-11-18 20:58:30 得分 0
是这样的啊,我试试。Top
25 楼czmissyou(海中石)回复于 2004-11-18 21:45:57 得分 0
郁闷啊。
m_xRotation = 90.0f;
m_yRotation = 180.0f;
m_zRotation = 0.0f;
m_xTranslation = 0.0f;
m_yTranslation = 0.0f;
m_zTranslation = -1400.0f;
m_xScaling = 1.0f;
m_yScaling = 1.0f;
m_zScaling = 1.0f;
m_SpeedRotation = 1.0f / 3.0f;
m_SpeedTranslation = 10.0f;
这是我的初始化,把m_zTranslation放到-300的时候才能看到三角片,而一直到-1400也只是看到大的三角片,-1500的时候竟然看不到了,这是怎么回事?Top
26 楼czmissyou(海中石)回复于 2004-11-18 22:09:35 得分 0
我原来用的确实是缩放,现在我改了一下代码,可是,平移好象解决不了问题,拉远1500M后,竟然黑屏了。太平洋兄,帮我看看怎么回事好吗?邮箱的代码我更新了一下。Top
27 楼syy64(太平洋)回复于 2004-11-19 09:41:11 得分 0
黑屏问题在你这儿是因为场景在屏幕外面造成的,解决方法是这样的:应该根据你的数据的坐标值大小来设置平移参数、视点和模型点的位置、调整好视点和模型点的距离。Top
28 楼syy64(太平洋)回复于 2004-11-19 10:20:01 得分 0
程序我看了,也比较乱,分步调试也进行不下去,坐标也没法看,你里面场景漫游函数:gluLookat也没见用上,所以视点和模型点也无法设置,你再看看红宝书,把这些概念弄清楚。Top
29 楼czmissyou(海中石)回复于 2004-11-21 18:35:35 得分 0
gluLookat函数在初始化的时候就可以用吗?
原来我用缩放函数的时候不用设置视点也能看到模型,后来就一直没有加上。Top
30 楼syy64(太平洋)回复于 2004-11-22 09:04:49 得分 0
可以呀,在OnPaint函数里面也得用。Top
31 楼czmissyou(海中石)回复于 2004-11-22 21:48:44 得分 0
大哥,在我的想法里,gluLookat函数是设置视点的,OpenGL的默认视点在原点,把视点往前拉与把模型往后拉的效果是一样的。
今晚的试了一下,果然不错,在Onpaint函数里把视点设在1000附近时才能看到一个大的三角片。
gluLookAt(0.0,0.0,1000.0,0.0,0.0,0.0,0,1,0);
与原来用glTranslated的效果是一样的。说模型在屏幕外也是不可能的,因为OpenGL的原点设在了模型的中心,而模型x坐标的范围是(-50000.0,50000.0),y坐标的范围是(-36500,36500).俯看的模式,模型不可能在屏幕外的。
因为这个,所以非常奇怪,近了看不到,远了也看不到。郁闷。
调试应该没有问题,在我机子上,我一步一步调过,没有发现毛病啊。Top
32 楼syy64(太平洋)回复于 2004-11-22 21:59:52 得分 0
不对,gluLookAt函数不光设置视点,还有放大和缩小的功能Top




