查看: 2298|回复: 5

相交测试

[复制链接]

该用户从未签到

发表于 2012-11-19 22:21:26 | 显示全部楼层 |阅读模式
做相交测试的时候,做了同样的碰撞检测,模型对称的,为什么一个是红色,一个是绿色呢?(条件:有交点显示红色三角形,没有交点为绿色)图上都应该没有交点,应该都是红色的。各位大师指点
111.jpg

该用户从未签到

发表于 2012-11-20 13:41:38 | 显示全部楼层
这个问题最好的解决方式就是跟代码

该用户从未签到

 楼主| 发表于 2012-11-21 14:34:10 | 显示全部楼层
gis_wudi 发表于 2012-11-20 13:41
这个问题最好的解决方式就是跟代码

  1. void getIntersections( osg::Vec3dArray *buttomPointList,osg::Group* sphereGroup, osg::Node* model, osg::Vec3d p_start,osg::Vec3d p_end)
  2. {
  3. osg::ref_ptr< osgUtil::LineSegmentIntersector > _lineSegmentIntersector = new osgUtil::LineSegmentIntersector(p_start,p_end);
  4. osgUtil::IntersectionVisitor _iv(_lineSegmentIntersector.get());
  5. model->accept(_iv);

  6. osgUtil::LineSegmentIntersector::Intersections _intersections = _lineSegmentIntersector->getIntersections();
  7. int _intersectionNumber=_intersections.size();
  8. osgUtil::LineSegmentIntersector::Intersections::iterator hitr = _intersections.begin();
  9. for (; hitr != _intersections.end();hitr++)
  10. {
  11. buttomPointList->push_back(hitr->getWorldIntersectPoint());
  12. }
  13. for (int i=0;i<buttomPointList->size();i++)
  14. {
  15. osg::Geode* geode=new osg::Geode;
  16. osg::ShapeDrawable *viewPoint=new osg::ShapeDrawable(new osg::Sphere(buttomPointList->at(i),0.01f));
  17. viewPoint->setColor(osg::Vec4(0.0f,0.0f,1.0f,1.0f));
  18. geode->addDrawable(viewPoint);
  19. sphereGroup->addChild(geode);
  20. }
  21. }
  22. osg::ref_ptr<osg::Group>getVisiableRange(osg::Vec3d eyePoint,osg::Vec3dArray* buttomList,osg::Node *model,float gre,float yel,float red)
  23. {
  24. osg::ref_ptr<osg::Group>visiableRange=new osg::Group;
  25. osg::Vec4 colorGre=osg::Vec4(0.0f,1.0f,0.0f,gre);
  26. osg::Vec4 colorYel=osg::Vec4(1.0f,1.0f,0.0f,yel);
  27. osg::Vec4 colorRed=osg::Vec4(1.0f,0.0f,0.0f,red);

  28. for (int i=0;i<buttomList->size()-1;i++)
  29. {
  30. osg::ref_ptr<osg::Group>group=new osg::Group;
  31. osg::ref_ptr<osg::Group>group2=new osg::Group;
  32. osg::ref_ptr<osg::Group>geodeGre=new osg::Group;
  33. osg::ref_ptr<osg::Group>geodeYel=new osg::Group;
  34. osg::ref_ptr<osg::Group>geodeRed=new osg::Group;
  35. osg::ref_ptr<osg::Vec3dArray>pointArrYel=new osg::Vec3dArray;
  36. osg::ref_ptr<osg::Vec3dArray>pointArrRed=new osg::Vec3dArray;
  37. osg::ref_ptr<osg::Vec3dArray> pointArrGre=new osg::Vec3dArray;
  38. osg::Vec3d end=buttomList->at(i);
  39. osg::Vec3dArray* hitList=new osg::Vec3dArray;
  40. getIntersections(hitList,group,model,eyePoint,end);

  41. osg::Vec3d end2=buttomList->at(i+1);
  42. osg::Vec3dArray* hitList2=new osg::Vec3dArray;
  43. getIntersections(hitList2,group2,model,eyePoint,end2);

  44. cout<<"hitList:--"<<hitList->size()<<"hitList2:--"<<hitList2->size()<<endl<<endl;
  45. //||((end-hitList->at(0)).length()<0.1&&(end2-hitList2->at(0)).length()<0.1)||((eyePoint-hitList->at(0)).length()<0.1&&(eyePoint-hitList2->at(0)).length()<0.1)
  46. if (hitList->size()==0 && hitList2->size()==0)
  47. {
  48. pointArrGre->push_back(eyePoint);
  49. pointArrGre->push_back(end);
  50. pointArrGre->push_back(end2);
  51. }
  52. if (hitList->size()==0&&hitList2->size()!=0)
  53. {
  54. osg::Vec3d visiablePoint2=hitList2->at(0);
  55. pointArrYel->push_back(eyePoint);
  56. pointArrYel->push_back(end);
  57. pointArrYel->push_back(visiablePoint2);
  58. pointArrRed->push_back(visiablePoint2);
  59. pointArrRed->push_back(end);
  60. pointArrRed->push_back(end2);
  61. }
  62. else if (hitList->size()!=0&&hitList2->size()==0)
  63. {
  64. osg::Vec3d visiablePoint=hitList->at(0);
  65. pointArrYel->push_back(eyePoint);
  66. pointArrYel->push_back(visiablePoint);
  67. pointArrYel->push_back(end2);

  68. pointArrRed->push_back(visiablePoint);
  69. pointArrRed->push_back(end);
  70. pointArrRed->push_back(end2);
  71. }
  72. else
  73. {
  74. osg::Vec3d visiablePoint=hitList->at(0);//(hitList->at(1)-hitList->at(0)).length()<0.2?hitList->at(1):
  75. osg::Vec3d visiablePoint2=hitList2->at(0);//(hitList2->at(1)-hitList->at(0)).length()<0.2?hitList2->at(1):
  76. pointArrYel->push_back(visiablePoint);
  77. pointArrYel->push_back(visiablePoint2);
  78. pointArrRed->push_back(visiablePoint);
  79. pointArrRed->push_back(end);
  80. pointArrRed->push_back(end2);
  81. pointArrRed->push_back(visiablePoint2);
  82. }
  83. geodeYel->addChild(getPoly(pointArrYel,colorYel));
  84. geodeRed->addChild(getPoly(pointArrRed,colorRed));
  85. geodeGre->addChild(getPoly(pointArrGre,colorGre));

  86. visiableRange->addChild(geodeYel);
  87. visiableRange->addChild(geodeRed);
  88. visiableRange->addChild(geodeGre);
  89. visiableRange->addChild(group);
  90. visiableRange->addChild(group2);
  91. }

  92. // break;
  93. return visiableRange;

  94. }
复制代码
osg::ref_ptr< osg::Vec3dArray> buttomList  =  new osg::Vec3dArray;
       buttomList->push_back(start);
       osg::ref_ptr<osg::Group>group=new osg::Group;
       getIntersections(buttomList,group,modelGroup,start,end);
       buttomList->push_back(end);
        cout<<"buttomPointList Size"<<buttomList->size()<<endl<<endl;
       viewer->getSceneData()->asGroup()->addChild(getVisiableRange( eyePoint,buttomList,modelGroup,0.2,0.2,0.2));

这个是handle()调用的上面函数的部分。
上面第一个函数:getIntersections()是求的交点的函数,使用lineSegmentIntersector;
第二个函数:getVisiableRange()是获得可是范围多边形的函数,分为四种情况:1)两条边都没有交点,直接可视,用绿色三角形表示;2)左边没有交点,右边有交点,取第一个交点作为可视与不可视的划分,该交点的前部分用黄色三角形表示,后部分用红色三角形;3)同2)条件相反;4)两条边都有交点,分别取第一个交点作为划分,黄色三角形为可见部分,红色的(应该是梯形)为不可见部分。

我还没有找到哪里错了,但是结果不对,各位人才,帮忙看看吧,拜谢……

该用户从未签到

发表于 2012-11-22 17:15:29 | 显示全部楼层
最大的可能性就是您的线段起点或终点正好和物体相交,但是因为float类型精度的问题,这个相交的判断可能会失败,把start和end都适当沿着线段方向延长就可以了

该用户从未签到

 楼主| 发表于 2012-11-23 09:50:13 | 显示全部楼层
array 发表于 2012-11-22 17:15
最大的可能性就是您的线段起点或终点正好和物体相交,但是因为float类型精度的问题,这个相交的判断可能会失 ...

那个起点和终点确实在物体上,因为起点和终点也是经过碰撞确定的。我换成double也不行,所以有就加了距离判断,如果和起点或终点的距离小于某个值,这个点就不算。但是我一直不明白,他到底算不算终点,如果按照我说的,起始点都是物体上的点,那么碰撞得到的intersections就应该直接包括起始点,可是有很多时候都没有包括。
2)还有个问题,碰撞的线段的起始点都在同一个平面上都有可能出现交点(非起始点的交点),为什么呢?

该用户从未签到

发表于 2012-11-27 10:46:19 | 显示全部楼层
1、难道您真的不知道计算机的float类型从来都不准确么。。。换成double是没用的因为Intersector内部依然用float来计算,我说的延长线的方法是最直接的也是最准确的

2、为什么您认为没有
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表