OSG 根据两点坐标绘制圆柱
前言:在绘制脑节点和节点间关系时,需要根据两点坐标绘制圆柱。本文暂时介绍简单的绘制方式,如有需求,读者可以自行添加回调。
思想:
- 首先绘制两个球,得到球心!
- 根据球心坐标aVec和bVec,通过(aVec+bVec)/2 得到柱心,通过(aVec+bVec).length() 得到长度,绘制出在坐标(0,0,0)点的圆柱。
- 设置旋转和平移矩阵,先旋转,后平移,得到最终圆柱。
代码:
/************************************************************************/ /* Author: Lcy /* Mail: [email protected] /* Bolg: http://blog.csdn.net/MissXy_ /* Describe: 根据两点坐标绘制圆柱 /* Date: 2018-4-9 /************************************************************************/ #include <osgViewer/Viewer> #include <osg/Node> #include <osg/Geode> #include <osg/Group> #include <osg/BlendColor> #include <osg/BlendFunc> #include <osg/ShapeDrawable> #include <osg/MatrixTransform> #include <osg/NodeCallback> #include <osgDB/ReadFile> #include <osgDB/WriteFile> #include <osgUtil/Optimizer> #include <osgViewer/ViewerEventHandlers> #include <osgGA/TrackballManipulator> #include <osgGA/StateSetManipulator> /** * 创建一个脑节点:节点信息 */ osg::ref_ptr<osg::ShapeDrawable> createOneBNode(const osg::Vec3& center, float size) { osg::ref_ptr<osg::ShapeDrawable> oneShape = new osg::ShapeDrawable(); osg::ref_ptr<osg::TessellationHints> hints = new osg::TessellationHints(); hints->setDetailRatio(1.0f); oneShape = new osg::ShapeDrawable(new osg::Sphere(center, size), hints.get()); oneShape->setColor(osg::Vec4(65.0/255,105.0/255,225.0/255, 1.0)); return oneShape.release(); } /** * 创建一个边信息 */ osg::ref_ptr<osg::MatrixTransform> createCylinder(const osg::Vec3 &from, const osg::Vec3 &to, float radius) { osg::ref_ptr<osg::Geode> geode = new osg::Geode(); osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform(); osg::ref_ptr<osg::ShapeDrawable> cylinder = new osg::ShapeDrawable(); osg::ref_ptr<osg::TessellationHints> hints = new osg::TessellationHints(); hints->setDetailRatio(0.8f); osg::Vec3 cylCenter = (to + from)/2; //得到柱心 float height = (to - from).length(); //得到长度 cylinder = new osg::ShapeDrawable(new osg::Cylinder(osg::Vec3(0.0, 0.0, 0.0), radius, height),hints.get()); cylinder->setColor(osg::Vec4(255.0/255, 228.0/255, 181.0/255, 1.0f)); //鹿皮鞋色 geode->addDrawable(cylinder.get()); osg::Matrix mRotate, mTrans; mRotate.makeRotate(osg::Vec3f(0.0f, 0.0f, 1.0f), to - from); mTrans.makeTranslate(cylCenter); mt->setMatrix(mRotate*mTrans); mt->addChild(geode.get()); return mt.get(); } int main() { osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer(); viewer->setUpViewInWindow(100, 100, 1080, 960); viewer->addEventHandler(new osgViewer::StatsHandler()); viewer->setCameraManipulator(new osgGA::TrackballManipulator()); osg::ref_ptr<osg::Group> root = new osg::Group(); osg::ref_ptr<osg::Group> group = new osg::Group(); osg::ref_ptr<osg::Geode> geode = new osg::Geode(); osg::Vec3 aVec(osg::Vec3(0.0f, 0.0f, 0.0f)); osg::Vec3 bVec(osg::Vec3(10.0f, 0.0f, 0.0f)); geode->addDrawable(createOneBNode(aVec, 2.f)); geode->addDrawable(createOneBNode(bVec, 2.f)); osg::ref_ptr<osg::MatrixTransform> mt = createCylinder(aVec, bVec, 0.5f); group->addChild(mt.get()); root->addChild(geode.get()); root->addChild(group.get()); viewer->setSceneData(root.get()); viewer->realize(); viewer->run(); return 0; }
效果截图: