OSG环境实现Coons曲面的拼接绘制
来源:互联网 发布:手机淘宝怎么备注留言 编辑:程序博客网 时间:2024/06/07 06:13
最近在捣腾那个曲面的绘制,目的是想要绘制hermite曲面,经过查阅资料,发现coons曲面可以是hermite曲面的很好的实现途径。
coons曲面的简介:
由于是引用资料,在此贴图即可,观者有需要的可以自己搜索coos曲面相关的介绍。
以上便是coons曲面的简单介绍,下面给出例子实现的关键代码,例子代码部分引用网络的代码,有需要的观者可以到pudn网站下载。
关键代码:
(1)产生基函数
void Product(double V[], double p)//产生基函数,UV向均适用
{
double P[N + 1];
P[N] = 1;
for (int i = N - 1; i >= 0; i--)
P[i] = P[i + 1] * p;
V[0] = P[0] * 2 - P[1] * 3 + P[3];
V[1] = P[0] * (-2) + P[1] * 3;
V[2] = P[0] - P[1] * 2 + P[2];
V[3] = P[0] - P[1];
}
(2)产生coons算法的点,传进去的V顶点数组相当于是公式的中间矩阵:
osg::Vec3 coons(osg::ref_ptr<osg::Vec3Array> V, double u, double w)
{
osg::Vec3 pts[N + 1], pt;
double U[N + 1], W[N + 1];
int i, j;
Product(U, u);//产生u向的基函数,保存在U中
Product(W, w);//产生w向的基函数,保存在W中
pt = osg::Vec3(0, 0, 0);
for (i = 0; i <= N; i++)
{
pts[i] = osg::Vec3(0, 0, 0);
for (j = 0; j <= N; j++)
{
pts[i] += V->at(i*(N + 1) + j) * W[j];//V0,V1,V4,V5
}
pt += pts[i] * U[i];
}
return pt;
}
(3)产生曲面片段的顶点,保存在pts数组中:
void coons_to_points(osg::ref_ptr<osg::Vec3Array> CP, osg::ref_ptr<osg::Vec3Array> pts, int npoints)//参数:CP控制点,pts生成的点
{
double u, w, delt;
delt = 1 / (double)npoints;
u = w = 0;
for (int i = 0; i <= npoints; i++)
{
u = 0;
for (int j = 0; j <= npoints; j++)
{
pts->push_back(coons(CP, u, w));//产生一个coons曲面点
u += delt;
}
w += delt;
}
}
(4)产生整个曲面的顶点,并生成一个几何体Geometry:曲面插值点,UV向的切矢量,插值点的扭转矢量分别作为数组传进去,同时传进uv的细分值
osg::Geometry* GetRevitHermiteFacePoints(osg::ref_ptr<osg::Vec3Array> Totalpoints, osg::ref_ptr<osg::Vec3Array> TotalpointsUT, osg::ref_ptr<osg::Vec3Array> TotalpointsVT, osg::ref_ptr<osg::Vec3Array> TotalpointsUVT, int unums, int vnums)
{
osg::ref_ptr<osg::Vec3Array> GridPoints = new osg::Vec3Array;
osg::Geometry* geom = new osg::Geometry;
geom->setVertexArray(GridPoints);
int PSize = GridPoints->size();
auto Pnum = Totalpoints->size();
for (int i = 0; i <Pnum - 2; i += 2)//Pnum-2
{
osg::ref_ptr<osg::Vec3Array> points = new osg::Vec3Array;
osg::ref_ptr<osg::Vec3Array> pointsUT = new osg::Vec3Array;
osg::ref_ptr<osg::Vec3Array> pointsVT = new osg::Vec3Array;
osg::ref_ptr<osg::Vec3Array> pointsUVT = new osg::Vec3Array;
osg::ref_ptr<osg::Vec3Array> SubGridPoints = new osg::Vec3Array;
osg::ref_ptr<osg::Vec3Array> ConctrlP = new osg::Vec3Array;
for (int m = i; m < i+4; m += 2)
{
ConctrlP->push_back(Totalpoints->at(m));
ConctrlP->push_back(Totalpoints->at(m + 1));
ConctrlP->push_back(TotalpointsUT->at(m));
ConctrlP->push_back(TotalpointsUT->at(m + 1));
}
for (int m = i; m < i+4; m += 2)
{
ConctrlP->push_back(TotalpointsVT->at(m));
ConctrlP->push_back(TotalpointsVT->at(m + 1));
ConctrlP->push_back(TotalpointsUVT->at(m));
ConctrlP->push_back(TotalpointsUVT->at(m + 1));
}
//InitCP(ConctrlP);
coons_to_points(ConctrlP, SubGridPoints, unums);
int pNumm = SubGridPoints->size();//每一个子网格的顶点数
for (int k = 0; k < pNumm;k++)
{
GridPoints->push_back(SubGridPoints->at(k));
}
auto geomEle = new osg::DrawElementsUInt(osg::PrimitiveSet::LINES, 0);//DrawElements方式
int PNumU = unums + 1;//每个U向的顶点数
int PNumV = vnums + 1;//每个V向的顶点数
for (int k = 0; k < PNumV-1; k++)//PNumV
{
for (int i = 0; i < PNumU; i++)
{
if (i + 1 < PNumU)
{
//三角形
geomEle->push_back(PSize+k*PNumU + i);
geomEle->push_back(PSize+(k + 1)*PNumU + i);
geomEle->push_back(PSize+k*PNumU + (i + 1));
geomEle->push_back(PSize+k*PNumU + (i + 1));
geomEle->push_back(PSize+(k + 1)*PNumU + (i + 1));
geomEle->push_back(PSize+(k + 1)*PNumU + i);
}
}
}
geom->addPrimitiveSet(geomEle);
PSize += pNumm;
/*<绑定颜色>*/
osg::ref_ptr<osg::Vec4Array> V_C = new osg::Vec4Array;
V_C->push_back(osg::Vec4(0.0, 1.0, 1.0, 1.0));
geom->setColorArray(V_C);
geom->setColorBinding(osg::Geometry::BIND_OVERALL);
}
///*<绑定颜色>*/
//osg::ref_ptr<osg::Vec4Array> V_C = new osg::Vec4Array;
//V_C->push_back(osg::Vec4(0.0, 1.0, 1.0, 1.0));
//geom->setColorArray(V_C);
//geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
return geom;
}
测试使用的数据:
void InitialConctrlP1(osg::ref_ptr<osg::Vec3Array> Totalpoints1, osg::ref_ptr<osg::Vec3Array> TotalpointsUT1, osg::ref_ptr<osg::Vec3Array> TotalpointsVT1, osg::ref_ptr<osg::Vec3Array> TotalpointsUVT1)
{
Totalpoints1->push_back(osg::Vec3(0.0, 0.0, 2.0));//P0-[0][0]
Totalpoints1->push_back(osg::Vec3(10.0, 0.0, 2.0)); //P1-[1][0]
Totalpoints1->push_back(osg::Vec3(0.0, 10.0, 2.0)); //P2-[0][1]
Totalpoints1->push_back(osg::Vec3(10.0, 10.0, 2.0)); //P3-[1][1]
Totalpoints1->push_back(osg::Vec3(0, 15, 0));
Totalpoints1->push_back(osg::Vec3(10, 15, 0));
//Totalpoints1->push_back(osg::Vec3(0, 20, 0));
//Totalpoints1->push_back(osg::Vec3(10, 20, 0));
TotalpointsUT1->push_back(osg::Vec3(1.5, 1.5, 2.0));//P0u-[0][0]
TotalpointsUT1->push_back(osg::Vec3(3.0, 0.5, 2.5));//P1u-[1][0]
TotalpointsUT1->push_back(osg::Vec3(0.5, 3.0, 1.0));//P2u-[0][1]
TotalpointsUT1->push_back(osg::Vec3(1.5, 3.5, 1.5));//P3u-[1][1]
TotalpointsUT1->push_back(osg::Vec3(1, -1, 0));
TotalpointsUT1->push_back(osg::Vec3(1, -1, 0));
//TotalpointsUT1->push_back(osg::Vec3(1, -1, 0));
//TotalpointsUT1->push_back(osg::Vec3(1, -1, 0));
TotalpointsVT1->push_back(osg::Vec3(0.3, 1.5, 2.0));//P0v-[0][0]
TotalpointsVT1->push_back(osg::Vec3(1.0, 0.5, 2.5));//P1v-[1][0]
TotalpointsVT1->push_back(osg::Vec3(0.5, 1.0, 1.5));//P2v-[0][1]
TotalpointsVT1->push_back(osg::Vec3(1.5, 3.5, 1.5));//P3v-[1][1]
TotalpointsVT1->push_back(osg::Vec3(-1, 1, 1));
TotalpointsVT1->push_back(osg::Vec3(-1, 1, 1));
//TotalpointsVT1->push_back(osg::Vec3(-1, 1, 1));
//TotalpointsVT1->push_back(osg::Vec3(-1, 1, 1));
TotalpointsUVT1->push_back(osg::Vec3(1.3, 10.5, 12.3));//P0uv-[0][0]
TotalpointsUVT1->push_back(osg::Vec3(12.0, 11.5, 1.0));//P1uv-[1][0]
TotalpointsUVT1->push_back(osg::Vec3(1.5, 11.0, 11.1));//P2uv-[0][1]
TotalpointsUVT1->push_back(osg::Vec3(12.5, 11.5, 1.5));//P3uv-[1][1]
TotalpointsUVT1->push_back(osg::Vec3(1, 1, 1));
TotalpointsUVT1->push_back(osg::Vec3(-1, -1, -1));
//TotalpointsUVT1->push_back(osg::Vec3(1, 1, 1));
//TotalpointsUVT1->push_back(osg::Vec3(-1,-1, -1));
}
实现两个曲面片段拼接的效果图:
最后推荐一些阅读的网站:
http://netclass.csu.edu.cn/NCourse/hep089/Chapter3/CG_Txt_3_062.htm
https://en.wikipedia.org/wiki/Coons_patch
http://www.cgeo.ulg.ac.be/CAO/CAD_05.pdf
- OSG环境实现Coons曲面的拼接绘制
- Coons曲面
- 贝塞尔曲面的绘制
- Python绘制曲面和曲面对应的等高线图
- TWaver3D直线、曲线、曲面的绘制
- OSG环境下,使用glsl的几何着色器,绘制带纹理的三角形
- OSG::绘制
- OSG-简单的绘制一个坐标轴
- OSG绘制多重面的纹理
- OSG 学习第二天:几何体的绘制
- Matlab绘制三维曲面
- 曲面绘制Mesh
- 使用GLU的NURBS绘制曲线和曲面(获取分格化图元和曲面修剪)
- R语言 绘制三维散点图的预测曲面
- MATLAB绘制3D隐函数曲面的方法总结
- vtkPolygonalSurfaceContourLineInterpolator 多边形曲面上的多边形绘制器
- matlab之连续+离散的三维曲面绘制
- MATLAB绘制3D隐函数曲面的方法总结
- IE浏览器下使用localhost域名保存cookie的问题
- C-index/C-statistic 计算的5种不同方法及比较
- 最小二乘法
- 2016 沈阳 大致题意
- READING NOTE: Speed/accuracy trade-offs for modern convolutional object detectors
- OSG环境实现Coons曲面的拼接绘制
- 爬虫时碰到的socket.error: [Errno 10060]错误的原因以及解决方法
- 神啊
- oracle组函数
- 一个关于宠物的小代码
- 一个简单的逆向
- OJ习题acm求数列的和
- CF_671B Robin Hood(二分)
- HDU 1008