球面参数方程
球面的参数曲线可以用球坐标表示,引入参数u,v,其中v是球面点与原点的连线与z轴正向的夹角,u表示连线在xy平面的投影与x轴正向的夹角
球面法向量
已知球面的参数方程以后,很容易求得给定点的法向量,分别对u和v方向求偏导数
,然后对两个所得向量进行叉积即可:
osg::Vec3 getPoint(double u, double v)
{
double x = sin(osg::PI*v)*cos(osg::PI*2*u);
double y = sin(osg::PI*v)*sin(osg::PI * 2 *u);
double z = cos(osg::PI*v);
return osg::Vec3(x, y, z);
}
//主函数
osg::ref_ptr<osg::Geode> geode = new osg::Geode();
osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array();
osg::ref_ptr<osg::Geometry> triGeom = new osg::Geometry();
geode->addDrawable(triGeom);
int uStepsNum = 50, vStepNum = 50;
double ustep = 1 / (double)uStepsNum, vstep = 1 / (double)vStepNum;
double u = -0, v = -0;
int count = 0;
for (int i = 0; i < uStepsNum; i++)
{
osg::Vec3 a = getPoint(0, 0);
osg::Vec3 b = getPoint(u, vstep);
osg::Vec3 c = getPoint(u + ustep, vstep);
vertices->push_back(a);
vertices->push_back(b);
vertices->push_back(c);
triGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_LOOP, count, 3));
count += 3;
u += ustep;
}
//绘制中间四边形组
u = 0, v = vstep;
for (int i = 1; i < vStepNum - 1; i++)
{
for (int j = 0; j < uStepsNum; j++)
{
osg::Vec3 a = getPoint(u, v);
osg::Vec3 b = getPoint(u + ustep, v);
osg::Vec3 c = getPoint(u + ustep, v + vstep);
osg::Vec3 d = getPoint(u, v + vstep);
vertices->push_back(a);
vertices->push_back(b);
vertices->push_back(c);
vertices->push_back(d);
triGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_LOOP, count, 4));
count += 4;
u += ustep;
}
v += vstep;
}
//绘制下端三角形组
u = 0;
for (int i = 0; i < uStepsNum; i++)
{
osg::Vec3 a = getPoint(0, 1);
osg::Vec3 b = getPoint(u, 1 - vstep);
osg::Vec3 c = getPoint(u + ustep, 1 - vstep);
vertices->push_back(a);
vertices->push_back(b);
vertices->push_back(c);
triGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_LOOP, count, 3));
count += 3;
u += ustep;
}
triGeom->setVertexArray(vertices);
m_root->addChild(geode);
参考: