OSG 根据两点坐标绘制圆柱

OSG 根据两点坐标绘制圆柱



前言:在绘制脑节点和节点间关系时,需要根据两点坐标绘制圆柱。本文暂时介绍简单的绘制方式,如有需求,读者可以自行添加回调。


思想:

  1. 首先绘制两个球,得到球心!
  2. 根据球心坐标aVec和bVec,通过(aVec+bVec)/2 得到柱心,通过(aVec+bVec).length() 得到长度,绘制出在坐标(0,0,0)点的圆柱。
  3. 设置旋转和平移矩阵,先旋转,后平移,得到最终圆柱。

代码:

/************************************************************************/  
/* 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;
} 

效果截图:


猜你喜欢

转载自blog.csdn.net/missxy_/article/details/79863003