几何内核开发-实现自己的NURBS曲线生成API

我去年有一篇帖子,介绍了NURBS曲线生成与显示的实现代码。

https://blog.csdn.net/stonewu/article/details/133387469?spm=1001.2014.3001.5501文章浏览阅读323次,点赞4次,收藏2次。搞3D几何内核算法研究,必须学习NURBS样条曲线曲面。看《非均匀有理B样条 第2版》这本书,学习起来,事半功倍。在《插件化算法研究平台》上,做了一个样条曲线研究功能,可以分析Bezier曲线、BSpline、NURBS曲线的各种性质,有直观的体验,能更好地理解。https://blog.csdn.net/stonewu/article/details/133387469?spm=1001.2014.3001.5501

本贴子介绍如何在OGG几何内核上做个自己NURBS曲线API。

曲线代码框架参考示例如下:(具体实现代码,请参考我去年的帖子自行实现,或联系本人)

namespace stone
{using namespace std;
class Point3
{
public:float x, y, z;Point3(float x = 0, float y = 0, float z = 0) : x(x), y(y), z(z) {}double norm() { return sqrt(x * x + y * y + z * z); }Point3 operator*(double d) { return Point3(x * d, y * d, z * d); }Point3 operator+(const Point3& p) { return Point3(x + p.x, y + p.y, z + p.z); }
};
class BaseCurve
{
public:virtual ~BaseCurve() {}BaseCurve(double precision) { m_precision = precision; }bool finished = false; //完成控制点构成bool m_mousePressed = false;int  m_currentControlPointIndex = -1;double         m_precision = 0.01; //精度vector<Point3> controlPoints;vector<Point3> curvePoints;//nurbs参数vector<double> weights;    //权重vector<double> knots;      // 结点向量int            degree = 3; // 曲线次数virtual void clear(){//清空curvePoints.clear();//清空controlPoints.clear();finished = false;}virtual void curveInfo() = 0;virtual void createCurve() = 0;virtual void appendControlPoint(Point3 controlPoint) { controlPoints.push_back(controlPoint); }virtual void moveControlPoint(int index, Point3 controlPoint) { controlPoints[index] = controlPoint; }void initKnots(){。。。}void initWeights(){。。。}
};
class BezierCurve : public BaseCurve
{
public:BezierCurve(double precision = 0.01) : BaseCurve(precision){};public:void curveInfo() { debugx("BezierCurve!"); }// 生成N阶贝塞尔曲线点void createCurve(){curveInfo();if (controlPoints.size() <= 1)return;//清空curvePoints.clear();auto size = controlPoints.size();for (double t = 0; t < 1.0000; t += m_precision){ //根据精度绘制点。。。}}
};class BSplineCurve : public BaseCurve
{
public:void curveInfo() { debugx("BSplineCurve!"); }BSplineCurve(int aDegree, double precision) : BaseCurve(precision) { degree = aDegree; }BSplineCurve(vector<Point3> points, int k, double precision) : BaseCurve(precision){controlPoints = points;degree = k;// 初始化结点向量, m = n + 1+ k   ,m+1节点数量, n+1控制点数量 ,k 次数。。。}// 计算基函数值double basis(int i, int k, double u){
。。。return a * basis(i, k - 1, u) + b * basis(i + 1, k - 1, u);}// 计算样条曲线上的点virtual Point3 calculatePoint(double u){Point3 result;。。。return result;}void createCurve(){curveInfo();//清空curvePoints.clear();auto size = controlPoints.size();if (size < 2)return;//生成NURBS曲线上所有的点。。。}void moveControlPoint(int index, Point3 controlPoint){controlPoints[index] = controlPoint;if (controlPoints.size() < 2)return;createCurve();}
};class NURBSCurve : public BSplineCurve
{
public:void curveInfo() override { debugx("NURBSCurve!"); }NURBSCurve(int aDegree=3, double precision = 0.01) : BSplineCurve(aDegree, precision) {}// 计算样条曲线上的点Point3 calculatePoint(double u) override{。。。return result;}
};
} //namespace stonenamespace stone
{class CurveUtil
{
public:static BRepBuilderAPI_MakePolygon CreateBezierCurve(TColgp_Array1OfPnt Array1, double precision = 0.01){。。}static BRepBuilderAPI_MakePolygon CreateNURBSCurve(TColgp_Array1OfPnt Array1, int aDegree=3, double precision = 0.01){。。。return makePolygon;}
};} //namespace stone MakeAPI

调用代码参考示例:

主要功能Demo:

1、定义5个控制点,并在界面上显示出来。

2、调用自己的曲线算法API,生成BezierCurve,以此线条为路径,生成管道。并显示。

3、调用自己的曲线算法API,生成NURBSCurve,缺省权重为1,degree为3,节点向量自行生成。以此线条为路径,生成管道。并显示。

4、调用 OCCT几何内核的BSpline API。以此线条为路径,生成管道。并显示。

5、调用 OCCT几何内核的BSpline  API  NUBRS曲线。以此线条为路径,生成管道。并显示。

void myCurveDemo(OccView *view)
{gp_Ax2 ax2;ax2.SetLocation(gp_Pnt(0, 0, 0));TopoDS_Edge circleEdge = BRepBuilderAPI_MakeEdge(gp_Circ(ax2, 0.1));const int pointCount=5;TColgp_HArray1OfPnt points(1, pointCount);points.SetValue(1, gp_Pnt(0.1, 0, 0));points.SetValue(2, gp_Pnt(1.1, 1, 1));points.SetValue(3, gp_Pnt(2.1, 2, 0));points.SetValue(4, gp_Pnt(3.1, 1, -1));points.SetValue(5, gp_Pnt(5.1, 1, -3));// points.SetValue(6, gp_Pnt(5.1, 4, 5));// points.SetValue(7, gp_Pnt(6.1, 5, -3));// points.SetValue(8, gp_Pnt(8.1, 2, -5));//显示控制点for(int i=1;i<=pointCount;i++){auto p=points.Value(i);showPoint(view,p,QString::number(i).toStdString().c_str(),false);}//调用自己的曲线算法API,生成BezierCurveauto curve=stone::CurveUtil::CreateBezierCurve(points);if(curve.IsDone()){Handle(AIS_ColoredShape) ais = new AIS_ColoredShape(curve.Wire());view->Display(ais);}
//调用自己的曲线算法API,生成NURBSCurve,缺省权重为1,degree为3,节点向量自行生成curve=stone::CurveUtil::CreateNURBSCurve(points);if(curve.IsDone()){auto wire=curve.Wire();Handle(AIS_ColoredShape) ais = new AIS_ColoredShape(wire);ais->SetColor(Quantity_NOC_MAROON);view->Display(ais);{//扫掠TopoDS_Shape pipe=BRepOffsetAPI_MakePipe(wire,circleEdge);Handle(AIS_Shape) aisPipe = new AIS_Shape(pipe);aisPipe->SetColor(Quantity_NOC_MAROON);view->Display(aisPipe);}}
//调用 OCCT几何内核的BSpline API{// Make a BSpline curve from the points arrayHandle(Geom_BSplineCurve) aBSplineCurve = GeomAPI_PointsToBSpline(points).Curve();// Make an edge between two point on the BSpline curve.gp_Pnt aPntOnCurve1, aPntOnCurve2;aBSplineCurve->D0(0.75 * aBSplineCurve->FirstParameter()+ 0.25 * aBSplineCurve->LastParameter(),aPntOnCurve1);aBSplineCurve->D0(0.25 * aBSplineCurve->FirstParameter()+ 0.75 * aBSplineCurve->LastParameter(),aPntOnCurve2);TopoDS_Edge anEdgeBSpline = BRepBuilderAPI_MakeEdge(aBSplineCurve);Handle(AIS_ColoredShape) anAisEdgeBSpline = new AIS_ColoredShape(anEdgeBSpline);anAisEdgeBSpline->SetColor(Quantity_Color(Quantity_NOC_MAGENTA));view->Display(anAisEdgeBSpline);{//扫掠auto wire=BRepBuilderAPI_MakeWire(anEdgeBSpline).Wire();TopoDS_Shape pipe=BRepOffsetAPI_MakePipe(wire,circleEdge);Handle(AIS_Shape) aisPipe = new AIS_Shape(pipe);aisPipe->SetColor(Quantity_NOC_MAGENTA);view->Display(aisPipe);}}//调用 OCCT几何内核的BSpline  API  NUBRS曲线{/// 均匀B样条,节点向量中的节点值成等差排布/// 均匀B样条的基函数呈周期性,即所有的基函数有相同的形状/// 每个后续基函数仅仅市前面基函数在新位置上的重复Standard_Integer degree(2);Standard_Integer KNum = pointCount + degree + 1;TColStd_Array1OfReal knots(1,KNum);for(int i=0; i<KNum; ++i)knots.SetValue(i+1, i);TColStd_Array1OfInteger mults(1,KNum);for(int i=0; i<KNum; ++i)mults.SetValue(i+1, 1);Handle(Geom_BSplineCurve) curve = new Geom_BSplineCurve(points, knots, mults, degree);TopoDS_Edge ed1 = BRepBuilderAPI_MakeEdge(curve);TopoDS_Wire wr1 = BRepBuilderAPI_MakeWire(ed1);Handle(AIS_ColoredShape) ais = new AIS_ColoredShape(wr1);ais->SetColor(Quantity_NOC_SALMON);view->Display(ais);}{/// 准均匀B样条,节点向量中的节点值也是等差排布,但是起点和终点都有k-1的重复度,其中ke为曲线次数。Standard_Integer degree(2);Standard_Integer KNum = pointCount-1;TColStd_Array1OfReal knots(1,KNum);for(int i=0; i<KNum; ++i)knots.SetValue(i+1, i);TColStd_Array1OfInteger mults(1,KNum);for(int i=0; i<KNum; ++i)if(i == 0 || i == KNum-1)mults.SetValue(i+1, degree+1);elsemults.SetValue(i+1, 1);Handle(Geom_BSplineCurve) curve = new Geom_BSplineCurve(points, knots, mults, degree);TopoDS_Edge ed1 = BRepBuilderAPI_MakeEdge(curve);TopoDS_Wire wr1 = BRepBuilderAPI_MakeWire(ed1);Handle(AIS_ColoredShape) ais = new AIS_ColoredShape(wr1);ais->SetColor(Quantity_NOC_SIENNA);view->Display(ais);//扫掠圆,BSpline路径 BRepOffsetAPI_MakePipe{{TopoDS_Shape pipe=BRepOffsetAPI_MakePipe(wr1,circleEdge);Handle(AIS_Shape) aisPipe = new AIS_Shape(pipe);aisPipe->SetColor(Quantity_NOC_BISQUE);view->Display(aisPipe);}}}
}

运行效果:

从运行效果上来看,扫掠生成的管道,与曲线形状非常一致。

绿色的管道(粗线)和自定义算法生成的Bezier曲线路径,如下图:

绿色的管道(粗线)和自定义算法生成的NURBS曲线路径,如下图:

绿色的管道(粗线)和OCCT几何内核的NURBS曲线路径,如下图:

以上三个图中,黄色+处,是控制点位置。黄色+的右下边的数字1,2,3,4,5是控制点的顺序号。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/34038.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

动手学深度学习(Pytorch版)代码实践 -卷积神经网络-25使用块的网络VGG

25使用块的网络VGG import torch from torch import nn import liliPytorch as lp import matplotlib.pyplot as plt# 定义VGG块 # num_convs: 卷积层的数量 # in_channels: 输入通道的数量 # out_channels: 输出通道的数量 def vgg_block(num_convs, in_channels, out_channel…

基于Springboot + vue 的抗疫物质管理系统的设计与实现

目录 &#x1f4da; 前言 &#x1f4d1;摘要 &#x1f4d1;系统流程 &#x1f4da; 系统架构设计 &#x1f4da; 数据库设计 &#x1f4da; 系统功能的具体实现 &#x1f4ac; 系统登录注册 系统登录 登录界面 用户添加 &#x1f4ac; 抗疫列表展示模块 区域信息管理 …

Codeforces Round 954 (Div. 3) A B C D

A. X Axis time limit per test: 2 second memory limit per test: 256 megabytes input: standard input output: standard output You are given three points with integer coordinates x 1 x_1 x1​, x 2 x_2 x2​, and x 3 x_3 x3​ on the X X X axis ( 1 ≤ x i ≤ …

MyBatis 源码分析-- SQL请求执行流程( Mapper 接口方法的执行的过程)

前言 前面我们从源码层面梳理了 SqlSessionFactory、SqlSession 的创建过程及 Mapper 获取过程&#xff0c;本篇我们继续分析一下 Mapper 接口方法的执行的过程&#xff0c;也就是 SQL 的执行流程。 Mybatis 相关知识传送门 初识 MyBatis 【MyBatis 核心概念】 MyBatis 源码…

Anaconda3 常用命令及配置

1、Anaconda是什么? 2、conda常用命令 系统环境&#xff1a;windows10 Anaconda版本&#xff1a;Anaconda3-2024.02-1-Windows-x86_64 2.1、虚拟环境管理 1、查看虚拟环境 conda env list conda info -e 2、创建虚拟环境 # 创建名为 pyenv 的虚拟环境 conda create --na…

计算机软件著作权申请流程及费用_快速登记_经验分享收藏级教程

最近需要申请计算机软件著作权&#xff0c;申请流程走了一遍&#xff0c;整理了分享给大家。软件著作权申请流程及费用&#xff0c;软著快速登记、软著材料及问题解答FAQ&#xff0c;阿里云百科阿里云计算机软件著作权登记20天下证&#xff0c;那么如何申请阿里云软件著作权登记…

MTK7628+MT7612 加PA定频数据

1、硬件型号TR726A5G121-DPA PC9.02.0017。如下所示&#xff1a; 2、WIFI5.8 AC模式 42&#xff08;5120MHz&#xff09;信道&#xff0c;80带宽 3、WIFI5.8 AC模式 38&#xff08;5190MHz&#xff09;信道&#xff0c;40带宽 4、WIFI5.8 AC模式 36&#xff08;5180 MHz&…

股票分析学习

库&#xff1a; pandas to_datetime:它可以处理各种格式的日期和时间数据&#xff0c;并将其统一转换为 Pandas 可以理解和操作的内部日期时间格式。 matplotlib.pyplot 用户可以轻松地创建各种静态、动态、交互式和 3D 图形。 1. 绘制线图&#xff08;plot()&#xff09; …

FEP耐酸碱耐高温可定制滴瓶60ml透明四氟瓶F46滴加瓶

FEP滴瓶&#xff1a;又叫聚全氟乙丙烯滴瓶&#xff0c;特氟龙滴瓶。广泛应用于痕量分析、超痕量分析、ICP-MS分析、同位素分析等实验。 主要特性如下&#xff1a; 1.耐高低温&#xff1a;使用温度可达-200&#xff5e;205℃&#xff1b; 2.材质为高纯实验级进口TeflonFEP加工…

虚拟机链接不上usb

传输速度慢 记得换一个支持usb3.0的口和支持usb3.0的线

C语言从入门到进阶(15万字总结)

前言&#xff1a; 《C语言从入门到进阶》这本书可是作者呕心沥血之作&#xff0c;建议零售价1元&#xff0c;当然这里开个玩笑。 本篇博客可是作者之前写的所有C语言笔记博客的集结&#xff0c;本篇博客不止有知识点&#xff0c;还有一部分代码练习。 有人可能会问&#xff…

运维技术栈总结

文章目录 Linux CommandBasecd/lschmod/chown/chgrpvi/vimscptarsudf Installrpmyumdeb/apt Filtertailgrepawkfindnetstatechotelnetwhereistouch/mkdirgzip/rar/tar Statistics Linux MonitorCPUtophtopsar Memoryfreevmstat I/Oiostatpidstatiotop Networknetstatiftoptcpdu…

认识Retrieval Augmented Generation(RAG)

什么是RAG&#xff1f; Retrieval-Augmented Generation (RAG) 是一种结合信息检索和生成式AI技术的框架。它通过从外部数据源检索信息&#xff0c;增强语言模型&#xff08;如GPT-3&#xff09;的生成能力&#xff0c;从而提供更加准确和相关的回答。 RAG的组成部分 信息检…

用腾讯云语音合成(TTS)批量生成英语绘本的朗读音频

孩子进行英语启蒙&#xff0c;需要看很多英语绘本&#xff0c;而且要听配套的音频来练听力。但有些英语绘本是没有对应音频的&#xff0c;下面简单几步&#xff0c;就可以将任意英语绘本制作出对应的英语朗读音频。 先到电子书资源网站搜索这个绘本名称&#xff0c;如果有电子…

三.iOS核心动画 - 关于图层几何(frame,bounds,transform,position)

引言 关于UIView的布局有一个经常被问到的问题&#xff0c;frame和bounds有什么区别&#xff0c;同样CALayer也有frame和bounds这两个属性&#xff0c;还有一个与UIView的center对应的position属性&#xff0c;本篇博客我们就来详细的探讨一下图层中的frame和bounds到底有什么…

Python酷库之旅-第三方库openpyxl(07)

目录 一、 openpyxl库的由来 1、背景 2、起源 3、发展 4、特点 4-1、支持.xlsx格式 4-2、读写Excel文件 4-3、操作单元格 4-4、创建和修改工作表 4-5、样式设置 4-6、图表和公式 4-7、支持数字和日期格式 二、openpyxl库的优缺点 1、优点 1-1、支持现代Excel格式…

十大经典排序算法——选择排序和冒泡排序

一、选择排序 1.基本思想 每一次从待排序的数据元素中选出最小&#xff08;或最大&#xff09;的一个元素&#xff0c;存放在序列的起始位置&#xff0c;直到全部待排序的数据全部排完。 2.直接选择排序 (1) 在元素集合arr[i] — arr[n - 1]中选择关键妈的最大&#xff08;小…

高考十字路口:24年考生如何权衡专业与学校的抉择?

文章目录 每日一句正能量前言专业解析理工科专业商科专业人文社科专业艺术与设计专业个人经验与思考过程结论 名校效应分析名校声誉与品牌效应资源获取学术氛围就业优势个人发展结论 好专业和好学校的权衡个人职业目标行业需求教育质量资源和机会学术氛围就业优势经济和地理位置…

嵌入式学习——数据结构(单向无头链表)——day46

1. 数据结构 1.1 定义 数据结构是指计算机中数据的组织、管理和存储方式。它不仅包括数据元素的存储方式&#xff0c;还包括数据元素之间的关系&#xff0c;以及对数据进行操作的方法和算法。数据结构的选择和设计直接影响算法的效率和程序的性能&#xff0c;是计算机科学与编…

说一说三大运营商的流量类型,看完就知道该怎么选运营商了!

说一说三大运营商的流量类型&#xff0c;看完就知道该怎么选运营商了&#xff1f;目前三大运营商的流量类型大致分为通用流量和定向流量&#xff0c;比如&#xff1a; 中国电信&#xff1a;通用流量定向流量 电信推出的套餐通常由通用流量定向流量所组成&#xff0c;通用流量…