曲线离散化之GCPnts包解析


@版权声明:本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出,
本文链接https://www.jianshu.com/p/92ede833b8bc
如有问题, 可邮件(yumxuanyi@qq.com)咨询。


关键字:OpenCASCADE、OpenGL、曲线离散化、GCPnts

一、概要

计算机图形学中绘制曲线,无论是绘制参数曲线还是非参数曲线,都需要先将参数曲线进行离散化,通过离散化得到一组离散化的点集,然后再将点集发送给图形渲染管线进行处理,最终生成我们想要的曲线。

OpenCASCADE中提供了GCPnts包。利用GCPnts包中提供的类,我们可以很方便的将三维曲线进行离散化。

二、GCPnts包中各种类说明

1. GCPnts_AbscissaPoint 弧长点算法

a. 可以用来计算曲线长度。
b. 用来计算曲线上与给定参数位置间隔一定弧长的位置点。

其中b很有用,后面均匀弧长算法内部就用到了
通过函数积分来计算曲线弧长
math_GaussSingleIntegration: 该类使用高斯勒让得积分算法,实现了对只有一个自变量的函数求积分

算法如下:

  1. 微元弧长 ds
    已知曲线Adaptor3d_Curve adaptorCurve,可以求得任意一点的切向量
    gp_Pnt curentPnt; gp_Vec curVec;
    adaptorCurve.D1(parameter,curentPnt,curVec);
    切向量的两个坐标就是dx 和 dy,
    所以对于曲线有微元弧长 ds = sqrt(dx^2 + dy^2) =curVec.Magnitude();
  2. 根据高斯-勒让得积分公式进行积分求解。
    根据积分点和权重近似计算函数积分。这个近似精度非常高
    “”
2. GCPnts_QuasiUniformAbscissa 准均匀弧长分布算法

功能:计算的曲线上的一组离散点,这些点按弧长均匀分布
说明: 该方法需要指定一个期望的离散点的个数。
算法:每两个连续的离散点之间的弧长相等。
事例代码:

  //GCPnts_QuasiUniformAbscissa 准均匀弧长分布算法  也就是等弧长分布
  // 计算一组按弧长均匀分布的离散点   
  // 可以根据指定的弧长 或者指定的多少个点
  //Abscissa is the curvilinear distance between  two consecutive points of the distribution 
  //Abscissa 表示连续的两个分布点之间的弧长 
  //算法 两点之间的弧长等于的弧长  
  GCPnts_QuasiUniformAbscissa  QUATooler;

  //curveLength 可以由GCPnts_AbscissaPoint求得这里取曲线总长的两倍  
  Standard_Integer  needPointsCount = curveLength * 2.0;  //表示期望的点数量

  QUATooler.Initialize(adaptorCurve, needPointsCount);//取两倍曲线长度的点 也就是0.5mm弧长一个点

  Standard_Integer pointsCount = QUATooler.NbPoints();
  TColgp_SequenceOfPnt SeqP; 
  for (int i = 1; i <= pointsCount; i++) 
  {    
    SeqP.Append(adaptorCurve.Value(QUATooler.Parameter(i)));
  }

注:半径50圆 GCPnts_QuasiUniformAbscissa计算的点有628个。

3. GCPnts_UniformAbscissa 均匀弧长分布算法

功能:同方法GCPnts_QuasiUniformAbscissa,用于计算的曲线上的一组离散点,这些点按弧长均匀分布。
但是提供两种方式: a. 指定期望点的个数 b. 指定弧长。
事例代码:

GCPnts_UniformAbscissa UATooler;  
//a 指定期望点的个数  
//同GCPnts_QuasiUniformAbscissa 这里不举例  
//UATooler.Initialize(adaptorCurve, needPointsCount);  
//b 指定弧长   
 Standard_Real abscissa = 10;//弧长10mm
 UATooler.Initialize(adaptorCurve, abscissa);  
 Standard_Integer pntCount = UATooler.NbPoints();  TColgp_SequenceOfPnt SeqP; 
 for (int i = 1; i <= pntCount; i++) 
 {    
    SeqP.Append(adaptorCurve.Value(UATooler.Parameter(i))); 
 }

注:半径50圆 弧长 0.5mm 计算的点有630个
2 * 3.1415926 * 50 / 0.5 = 628.31852
半径50圆 弧长 10mm 计算的点有33个
2 * 3.1415926 * 50 / 10 = 31.415926

4. GCPnts_QuasiUniformDeflection 准均匀偏差分布算法

功能:计算的曲线上的一组离散点。
算法说明:
假定 Pi 和 Pj为 分布的两连续的离散点 ,它们的参数为ui和uj。
计算偏差deflection :Pi和Pj连线(弦长)的中点和曲线上中间参数 [(ui+uj) / 2 ] 位置点之间的距离。
则两连续的离散点的计算偏差deflection必须小于给定的偏差Deflection值。
事例代码:

GCPnts_QuasiUniformDeflection QUDTooler;  
QUDTooler.Initialize(adaptorCurve, 1.e-5);//这里我们要求 deflection <= 1.e-5  
Standard_Integer pointsLength = QUDTooler.NbPoints();  TColgp_SequenceOfPnt SeqP;  
for (int i = 1; i <= pointsLength; i++) 
 {   
    SeqP.Append(QUDTooler.Value(i)); 
 }

注:半径50圆 准均匀偏差分布算法计算的点有4969个。

5. GCPnts_UniformDeflection 均匀偏差算法

功能:用于计算C2连续的曲线上的一组离散点。
该算法比较耗时。请使用GCPnts_QuasiUniformDeflection算法。
GCPnts_QuasiUniformDeflection方法可以用于计算非C2连续的曲线。

6. GCPnts_TangentialDeflection 切矢量偏离算法

功能:计算的曲线上的一组离散点。
算法原理:如果P1(u1)和 P2(u2) 曲线上两个连续的离散点。
P3 表示曲线上中间参数 ((u1+u2)/2)点。
则P3需要满足如下条件:
条件1: ||P1P3^P3P2||/||P1P3||*||P3P2||<AngularDeflection
偏转角度小于给定的角度AngularDeflection
a * b = |a||b|cosθ 也就是 cosθ < AngularDeflection
条件2 : ||P1P2^P1P3||/||P1P2||<CurvatureDeflection
表示曲线切线 与 弦长夹角要小于 给定的曲线偏离率CurvatureDeflection
|a|cosθ < CurvatureDeflection

事例代码:

GCPnts_TangentialDeflection  TDTooler;  //声明算法类
Standard_Real AngularDeflection = 1 / M_PI_4;  //这里去角度偏差1 / M_PI_4
Standard_Real CurvatureDeflection = 1.e-5;  //这里去曲率偏差 1.e-5
TDTooler.Initialize(adaptorCurve, AngularDeflection, CurvatureDeflection); //算法初始化
Standard_Integer PLength = TDTooler.NbPoints();  
TColgp_SequenceOfPnt SeqP
 for (int i = 1; i <= PLength; i++)  
{    
   SeqP.Append(TDTooler.Value(i));
 }

注:半径50圆 使用切矢量偏离算法计算的点有4969个。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342