几何内核开发-实现自己的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.rhkb.cn/news/359181.html

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

相关文章

Java医院绩效考核系统源码:关于医院绩效考核系统的技术架构、系统功能、如何选择医院绩效考核管理系统

Java医院绩效考核系统源码&#xff1a;关于医院绩效考核系统的技术架构、系统功能、如何选择医院绩效考核管理系统 随着医疗技术的不断发展&#xff0c;医院绩效管理系统已经成为提升医疗服务质量和效率的关键技术之一。本文将介绍医院绩效管理系统的概念、开发环境、功能应用…

三维点云目标识别对抗攻击研究综述

源自&#xff1a;电子与信息学报 作者&#xff1a;刘伟权 郑世均 郭宇 王程 注&#xff1a;若出现无法显示完全的情况&#xff0c;可 V 搜索“人工智能技术与咨询”查看完整文章 摘 要 当前&#xff0c;人工智能系统在诸多领域都取得了巨大的成功&#xff0c;其中深度学…

Tailwindcss 提取组件

背景 随着项目的发展&#xff0c;您不可避免地会发现自己需要重复使用常用样式&#xff0c;以便在许多不同的地方重新创建相同的组件。这在小组件&#xff08;如按钮、表单元素、徽章等&#xff09;中最为明显。在我的项目中是图表标题样式如下&#xff1a; <div class&qu…

TensorFlow高阶API使用与PyTorch的安装

欢迎来到 Papicatch的博客 文章目录 &#x1f349;TensorFlow高阶API使用 &#x1f348;示例1&#xff1a;使用tf.keras构建模型 &#x1f34d;通过“序贯式”方法构建模型 &#x1f34d;通过“函数式”方法构建模型 &#x1f348;示例2&#xff1a;编译模型关键代码 &am…

新手(初学者)学R语言第一课,从学正确导入数据开始

初看题目好像我在教你怎么导入数据&#xff0c;不不不&#xff0c;我是在教你正确的导入数据&#xff0c;不是说数据导入R就叫正确导入数据了。本章为新手教程&#xff0c;老手可以跳过。 这个内容早就想写了&#xff0c;今天有点空和大家聊一下。为什么R语言对于新手而言不太友…

建议收藏!100款宝藏级AIGC工具分享,70款ChatGPT插件惊艳的开发过程与宏大的商业化愿景

建议收藏&#xff01;100款宝藏级AIGC工具分享&#xff0c;70款ChatGPT插件惊艳的开发过程与宏大的商业化愿景。 不输ChatGPT&#xff1f;整理了100款AIGC神器&#xff0c;打工人速进。 说到AIGC工具&#xff0c;你还是只知道ChatGPT&#xff1f; 实际上&#xff0c;越来越多…

【机器学习】自然语言处理的新前沿:GPT-4与Beyond

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 目录 &#x1f525;引言 背景介绍 文章目的 一、GPT-4简介 GPT-4概述 主要特性 局限性和挑战 二、自监督学习的新进展 自监督学习的原理 代表性模型和技术 三、少样本学习和零样本学习 少样本学习的挑战 先…

使用kibana创建索引的时候报错处理

报错信息&#xff1a;The index pattern youve entered doesnt match any indices. You can match your 1 index, below. 使用kibana创建索引的时候&#xff0c;无法进行下一步创建操作&#xff0c;出现这种情况有很多种情况&#xff0c;每个人遇到的问题会不一样。 第一种&am…

Linux系统本地部署Android模拟器并实现无公网IP远程访问开发测试

文章目录 前言1. 虚拟化环境检查2. Android 模拟器部署3. Ubuntu安装Cpolar4. 配置公网地址5. 远程访问小结 6. 固定Cpolar公网地址7. 固定地址访问 前言 本文主要介绍如何在Linux Ubuntu系统使用Docker部署docker-android安卓模拟器&#xff0c;并结合cpolar内网穿透工具实现…

已成功见刊检索的国际学术会议论文海报展示(2)

【先投稿先送审】第四届计算机、物联网与控制工程国际学术会议&#xff08;CITCE 2024) 大会官网&#xff1a;www.citce.org 时间地点&#xff1a;2024年11月1-3日&#xff0c;中国-武汉 收录检索&#xff1a;EI Compendex&#xff0c;Scopus 主办单位&#xff1a;四川师范…

Springboot整合阿里云ONS RocketMq(4.0 http)

1. 引入依赖 <!--阿里云ons&#xff0c;方便的接入到云服务--> <dependency><groupId>com.aliyun.openservices</groupId><artifactId>ons-client</artifactId><version>1.8.4.Final</version> </dependency>2. 配置 配…

项目五 OpenStack镜像管理与制作

任务一 理解OpenStack镜像服务 1.1 •什么是镜像 • 镜像通常是指一系列文件或一个磁盘驱动器的精确副本。 • 虚拟机 所使用的 虚拟磁盘 &#xff0c; 实际上是 一种 特殊格式的镜像文件 。 • 云 环境下尤其需要 镜像。 • 镜像 就是一个模板&#xff0c;类似于 VMware 的虚…

Windwos +vs 2022 编译openssl 1.0.2 库

一 前言 先说 结论&#xff0c;编译64位报错&#xff0c;查了一圈没找到解决方案&#xff0c;最后换了32位的。 使用qt访问web接口&#xff0c;因为是https&#xff0c;没有openssl库会报错 QNetworkReply* reply qobject_cast<QNetworkReply*>(sender());if (reply){…

C语言入门系列:探秘二级指针与多级指针的奇妙世界

文章目录 一&#xff0c;指针的回忆杀1&#xff0c;指针的概念2&#xff0c;指针的声明和赋值3&#xff0c;指针的使用3.1 直接给指针变量赋值3.2 通过*运算符读写指针指向的内存3.2.1 读3.2.2 写 二&#xff0c;二级指针详解1&#xff0c;定义2&#xff0c;示例说明3&#xff…

Python爬虫-贝壳新房

前言 本文是该专栏的第32篇,后面会持续分享python爬虫干货知识,记得关注。 本文以某房网为例,如下图所示,采集对应城市的新房房源数据。具体实现思路和详细逻辑,笔者将在正文结合完整代码进行详细介绍。接下来,跟着笔者直接往下看正文详细内容。(附带完整代码) 正文 地…

北京智慧养老平台app打造,智慧养老,安心享老

目前&#xff0c;我国60岁以上老年人占人口比重已超过21%&#xff0c;我国老年人口数量快速增长&#xff0c;人口老龄化程度不断加深。与此同时&#xff0c;老年人的养老需求也在逐步上升。除了日常吃穿等生活需求外&#xff0c;他们在健康、精神方面也提出来新的要求。为了满足…

高职人工智能专业实训课之“自然语言处理”

一、前言 在人工智能领域&#xff0c;自然语言处理&#xff08;NLP&#xff09;技术日益成为研究和应用的热点。为了满足高职院校对NLP专业实训课程的需求&#xff0c;唯众人工智能教学实训凭借其前沿的教育技术平台&#xff0c;特别是GPU虚拟化技术&#xff0c;为学生提供了高…

【R语言】对一个Plot绘制多个图,并且每个图单元也包含多个图

以一个Plot绘制五行六列共30个图&#xff0c;然后每30个图单元包含两个图为例&#xff1a; 如下图所示&#xff1a; 代码如下&#xff1a; for (i in 1:(5*6)) {create_subplots <- function() {library(ggplot2)library(dplyr)library(tidyr)# 创建一个随机的数据框simula…

linux系统指令查漏补缺

目录 一.磁盘操作 二.lvm 三.top 4.nohup 一.磁盘操作 1. lsblk -f 显示磁盘和它的相关内容 2.tuen2fs -c -1 /dev/sdx 关闭某个磁盘的自检 3.修改配置&#xff0c;使文件系统不要开机自检 cat /etc/fstab 全0表示开机不自检 全1表示开机自检 同时在这个文件中可添加…

sql资料库

1、distinct(关键词distinct用于返回唯一不同的值)&#xff1a;查询结果中去除重复行的关键字 select distinct(university) from user_profile select distinct university from user_profile distinct是紧跟在select后面的&#xff0c;不能在其他位置&#xff0c;不然就…