CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
山寨机中的战斗机! 程序优化工程师到底对IT界有没有贡献
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  专题开发/技术/项目 >  图形图像/机器视觉

三维模型的取点问题。

楼主czmissyou(海中石)2004-11-02 21:24:35 在 专题开发/技术/项目 / 图形图像/机器视觉 提问

要做的是把鼠标所在点映射到模型上去,取出所在点的坐标显示出来。  
   
  我用了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

相关问题

  • OpenGL 三维 人体 模型
  • 关于三维软件中的事物模型
  • 谁知道什么技术可以把3ds做的模型转换诚DirectX或openGL格式的三维模型
  • YCbCr模型中CbCr的取值范围
  • 通过一些特征点的标识,获取人脸一些特征点的三维数据,然后对这些数据进行拟合,生成一个人脸的的模型,请问有哪些方法可以实现这一建模
  • 有没有网站上可以得到飞机模型或人体的三维图形的数据
  • 瀑布模型
  • i/o 模型
  • 模型驱动
  • 想用基于图像的建模方法对建立脸部三维模型,不知哪位朋友做过类似工作给点建议

关键词

  • .net
  • 坐标
  • 误差
  • 屏幕
  • 物体
  • 鼠标
  • 邮箱
  • csdn
  • xml
  • 模型

得分解答快速导航

  • 帖主:czmissyou

相关链接

  • CSDN Blog
  • 技术文档
  • 代码下载
  • 第二书店
  • 读书频道

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo