最近在倒腾项目的一些小算法,这是其中擦边横生出来的小算法,思想很简单,实现的启迪来自于圆形的绘制,实现环境为OSG库,采用OSG中的DrawElements的形式组织顶点。
(1)核心算法为:由曲线上的离散点作为V向,每一个离散点旋转一周作为U向(相当于是生成U方向上的顶点)。
如下:C(v)代表曲线上的点,Rx代表x轴向的半径,Ry代表y轴向的半径。
P(u,v)=C(v) + Rx* cos(u) + Ry*sin(u)
(2)实现代码如下:
osg::ref_ptr<osg::Group> Draw_Revolved_Face_New_ByLine_Piple(osg::Vec3 Rx, osg::Vec3 Ry, osg::Vec2 MinUMaxU, osg::Vec2 MinVMaxV, osg::ref_ptr<osg::Vec3Array> LinePoints, int NumU = 50)
{
osg::ref_ptr<osg::Group> root = new osg::Group;
osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
//创建一个DrawElelemnts对象
osg::DrawElementsUInt* geomEle = new osg::DrawElementsUInt(osg::PrimitiveSet::LINE_STRIP, 0);//新建一个DrawElemnts对象(图元类型,索引数量)
///*<UV的绘制范围>*/
float MinV = MinVMaxV.x();
float MaxV = MinVMaxV.y();
float MinU = MinUMaxU.x();
float MaxU = MinUMaxU.y();
float Radius = 0.5;
osg::ref_ptr<osg::Vec3Array> P1 = new osg::Vec3Array;//保存了一部分顶点
int NumV = LinePoints->size();
for (int v = 0; v < NumV; v++)
{
for (int u = 0; u <= NumU; u++)
{
osg::Vec3 tempP1;
//osg::Vec3 tempP1nor;
osg::Vec3 CP1;
//外置线顶点
CP1 = LinePoints->at(v);
tempP1 = CP1 + (Rx* cos((MinU + ((MaxU - MinU) / NumU)*u)) + Ry*sin((MinU + ((MaxU - MinU) / NumU)*u)));
P1->push_back(tempP1);
}
}
顶点组织绘制
geom->setVertexArray(P1);
auto Num = NumU + 1;
for (int k = 0; k < NumV - 1; k++)
{
for (int i = 0; i < NumU; i++)
{
geomEle->push_back(k*Num + i);
geomEle->push_back(k*Num + (i + 1));
geomEle->push_back((k + 1)*Num + i);
geomEle->push_back((k + 1)*Num + i);
geomEle->push_back(k*Num + (i + 1));
geomEle->push_back((k + 1)*Num + (i + 1));
}
}
geom->addPrimitiveSet(geomEle);
/*<绑定颜色>*/
osg::ref_ptr<osg::Vec4Array> V_C = new osg::Vec4Array;
V_C->push_back(osg::Vec4(1.0, 0.0, 0.0, 1.0));
geom->setColorArray(V_C);
geom->setColorBinding(osg::Geometry::BIND_OVERALL);
root->addChild(geom);
return root;
}
(3)测试效果