osg三维空间旋转扇形绘制

 参考博客:http://blog.csdn.net/qiuchangyong/archive/2010/09/02/5859628.aspx

图一
图二

        先放成品图如上图一所示(为了更好展示三维图,有两个面没有进行封闭),其是由图二在空间内绕特定向量(x,y,z)(并非坐标轴)旋转一定角度绘制而成,之前想在osg里找到一种绘制空间旋转体通用方法,找了很久都未曾找到,所以在这里我是采用自己瞄点,由点及面渲染最后生成osg::Node而成的,虽然比较麻烦,但是增加了灵活性并适用于更多的场景下的需求,下面贴出自己的绘制过程,如有更简单方法烦请诸位告知。

        绘制空间扇形旋转几何体首先从基础图元着手,首先采用基础函数绘制出一个平面扇形,函数及入参说明如下所示,弧长分段数参数表示你打算扇形弧边分为多少段进行绘制,段数越多弧显得更圆润,当然计算随之变大,这个数值自己取舍,一般绘制整圆采用72个点,我这里使用了16个点。

/* fn MakeSectorVer
 *	coords  存放点集
 *  rad     半径
 *  arc     扇形圆心角
 *  count   弧长分段数
 *  head    偏转角
 */
void MakeSectorVer(osg::ref_ptr<osg::Vec3Array> &coords, double rad, double arc, double count, double head)
{
	arc = arc / 180 * PI;
	head = head / 180 * PI;
	double degree = 0;
	for (int i = 0; i < count; i++)
	{
		coords->push_back(osg::Vec3(rad * cos(head + degree), rad * sin(head + degree), 0.0));
		degree += arc / count;
	}
}

 

       有了基础扇形就是对刚才绘制的Coords点集随着旋转轴一起旋转即可,基本思路如上图所示(画的比较粗糙), 在这个地方我是将XOY平面内扇形以Y轴为旋转轴进行旋转α度所得,当然你可以选择任意向量为轴都可以,但是代入计算时候务必是单位向量,其实旋转这种基本图元最难的地方的是侧面的渲染,在这里我是将α分为count(上面入参)份进行旋转,得到coords内所有点向下旋转的又一个点集,然后再进行渲染绘制,也就是coords内每个点进行旋转再得到count个点集数组,可能比较难以理解,这需要一定空间想象能力,下面为主要代码

/* fn CreateOneTri
 *	rotaxia     旋转轴
 *  line        存放点集
 *  point       目标旋转点
 *  sidearc     旋转角
 *  count       数量
 */
void CreateOneTri(osg::Vec3 &rotaxis, osg::ref_ptr<osg::Vec3Array> &line, osg::Vec3 &point, double sidearc, int count)
{
	double degree = 0;
	sidearc = sidearc / 180 * PI;
	for (int i = 0; i < count; i++)
	{
		double c = cos(degree);
		double s = sin(degree);
		double x = (pow(rotaxis.x(), 2) * (1 - c) + c) * point.x() + (rotaxis.x()*rotaxis.y() * (1 - c) - rotaxis.z()*s)*point.y() + (rotaxis.x()*rotaxis.z() * (1 - c) + rotaxis.y() * s) * point.z();
		double y = (rotaxis.x()*rotaxis.y() * (1 - c) + rotaxis.z()*s)*point.x() + (pow(rotaxis.y(), 2) * (1 - c) + c) * point.y() + (rotaxis.y()*rotaxis.z()*(1 - c) - rotaxis.x()*s)*point.z();
		double z = (rotaxis.x()*rotaxis.z()*(1 - c) - rotaxis.y()*s)*point.x() + (rotaxis.y()*rotaxis.z()*(1 - c) + rotaxis.x()*s)*point.y() + (pow(rotaxis.z(), 2) * (1 - c) + c)*point.z();
		line->push_back(osg::Vec3(x, y, z));
		degree += sidearc / count;
	}
}

       最后就是点的组合渲染,我这里采用的是QUAD的方式连接渲染,在网上有很多的源码,这里我就不贴出来了,最核心的部分已经贴出来,自我感觉这种三维编程还是需要自己动手写才会有更多的领悟,DEMO地址后续再贴出来。

完整Demo链接:https://download.csdn.net/download/qq_41303159/12412870

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值