参考博客:http://blog.youkuaiyun.com/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.youkuaiyun.com/download/qq_41303159/12412870