当前位置: 首页 > news >正文

网站建设的付款方式/合肥seo网站排名

网站建设的付款方式,合肥seo网站排名,网站投注员怎么做,企业网络营销的推广方法文章目录一、贝塞尔曲线二、B样条曲线三、Python 代码实现B样条曲线离散化四、C 代码实现B样条曲线离散化4.1 主要代码4.2 其余类4.3 离散效果展示(在CAD中展示)本文只做简介,关于贝塞尔曲线和B样条曲线的详细介绍,请参考&#xf…

文章目录

  • 一、贝塞尔曲线
  • 二、B样条曲线
  • 三、Python 代码实现B样条曲线离散化
  • 四、C++ 代码实现B样条曲线离散化
    • 4.1 主要代码
    • 4.2 其余类
    • 4.3 离散效果展示(在CAD中展示)


本文只做简介,关于贝塞尔曲线和B样条曲线的详细介绍,请参考:详解样条曲线(上)(包含贝塞尔曲线)
部分图片来源于:https://zhuanlan.zhihu.com/p/344934774

一、贝塞尔曲线

讲之前,我们先看一张图:
在这里插入图片描述
这里的 P0、P1、P2 分别称之为控制点,贝塞尔曲线的产生完全与这三个点位置相关。

这也就意味着,我们可以通过调节控制点的位置,进而调整整个曲线。

那么,似乎最开始的控制点,也不一定是三个?如果是四个、五个,甚至更多呢?

在这里插入图片描述

如此一来,你会发现贝塞尔曲线内的递归结构。实际上,上述介绍的分别是三阶、四阶、五阶的贝塞尔曲线,贝塞尔曲线可以由阶数递归定义。

一个在线玩贝塞尔曲线的链接:在线玩贝塞尔曲线

下面直接给贝塞尔曲线的通用公式

假设一共有 n+1\mathrm{n}+1n+1 个点 P0,P1,⋯,Pn\mathrm{P}_0, \mathrm{P}_1, \cdots, \mathrm{P}_{\mathrm{n}}P0,P1,,Pn ,这 n+1\mathrm{n}+1n+1 个点确定了 n\mathrm{n}n 次的贝塞尔曲线。
nnn 阶贝塞尔曲线 Bn(t)B^n(t)Bn(t) 可以由前 nnn 个点决定的 n−1n-1n1 次贝塞尔曲线 Bn−1(t∣P0,⋯,Pn−1)B^{n-1}\left(t \mid P_0, \cdots, P_{n-1}\right)Bn1(tP0,,Pn1) 与后 nnn 个点决定的 n−1n-1n1 次贝塞尔曲线 Bn−1(t∣P1,⋯,Pn)\mathrm{B}^{\mathrm{n}-1}\left(\mathrm{t} \mid \mathrm{P}_1, \cdots, \mathrm{P}_{\mathrm{n}}\right)Bn1(tP1,,Pn) 线性组合递推而来,即
Bn(t∣P0,P1,⋯,Pn)=(1−t)Bn−1(t∣P0,P1,⋯,Pn−1)+tBn−1(t∣P1,P2,⋯,Pn)\mathrm{B}^{\mathrm{n}}\left(\mathrm{t} \mid \mathrm{P}_0, \mathrm{P}_1, \cdots, \mathrm{P}_{\mathrm{n}}\right)=(1-\mathrm{t}) \mathrm{B}^{\mathrm{n}-1}\left(\mathrm{t} \mid \mathrm{P}_0, \mathrm{P}_1, \cdots, \mathrm{P}_{\mathrm{n}-1}\right)+\mathrm{t} \mathrm{B}^{\mathrm{n}-1}\left(\mathrm{t} \mid \mathrm{P}_1, \mathrm{P}_2, \cdots, \mathrm{P}_{\mathrm{n}}\right) Bn(tP0,P1,,Pn)=(1t)Bn1(tP0,P1,,Pn1)+tBn1(tP1,P2,,Pn)
且一次贝塞尔曲线,即为由两点决定的线段,也即
B1(t∣P0,P1)=(1−t)P0+tP1\mathrm{B}^1\left(\mathrm{t} \mid \mathrm{P}_0, \mathrm{P}_1\right)=(1-\mathrm{t}) \mathrm{P}_0+\mathrm{tP}_1 B1(tP0,P1)=(1t)P0+tP1
可以得到 n\mathrm{n}n 次贝塞尔曲线的表达通式为
B(t)=∑i=0nCni(1−t)n−itiPiB(t)=\sum_{i=0}^n C_n^i(1-t)^{n-i} t^i P_i B(t)=i=0nCni(1t)nitiPi

有了通用公式,我们就可以通过遍历t来离散化贝塞尔曲线了!

二、B样条曲线

几个概念

  • 控制点: 也就是控制曲线的点,等价于贝塞尔函数的控制点,通过控制点可以控制曲线形状。假设有 n+1n+1n+1 个控制点 P0,P1,P2,⋯,Pn\mathrm{P}_0, \mathrm{P}_1, \mathrm{P}_2, \cdots, \mathrm{P}_{\mathrm{n}}P0,P1,P2,,Pn
  • 节点: 这个跟控制点没有关系,而是人为地将目标曲线分为若干个部分,其目的就是尽量使得各个部分有所影响但也有一定独立性, 这也是为什么B样条中,有时一个控制点的改变,不会很大影响到整条曲线,而只影响到局部的原因,这是区别于贝塞尔曲线的一 点。节点划分影响到权重计算,可以预想到的是,实现局部性的影响的原理应该是在生成某区间内的点时,某些控制点前的权重值会 为 0 ,即对该点没有贡献,所以才有上述特点。事实上,就是如此的。先了解有这个概念即可。假设我们划分了 m+1m+1m+1 个节点 t0,t1,⋯,tm\mathrm{t}_0, \mathrm{t}_1, \cdots, \mathrm{t}_{\mathrm{m}}t0,t1,,tm ,将曲线分成了 m\mathrm{m}m
  • 次与阶:次的概念就是贝塞尔中次的概念,即权重中 ttt 的最高幂次。而 阶=次 +1 。这里只需要知道次这个概念即可。假设我们用 kkk 表示次,即 k\mathrm{k}k 次。

B 样条曲线比贝塞尔曲线的设计要复杂许多,我们直接通过他们的公式大致比较一下贝塞尔曲线与 B 样条曲线的区别:

贝塞尔曲线

B(t)=∑i=0nCni(1−t)n−itiPi,t∈[0,1]B(t)=\sum_{i=0}^n C_n^i(1-t)^{n-i} t^i P_i, \quad t \in[0,1]B(t)=i=0nCni(1t)nitiPi,t[0,1]

B样条曲线

对于 n+1n+1n+1 个控制点 P0,P1,⋯,PnP_0, P_1, \cdots, P_nP0,P1,,Pn ,有一个包含 m+1m+1m+1 个节点的列表 (或节点向量) t0,t1,⋯,tmt_0, t_1, \cdots, t_mt0,t1,,tm ,其 kkkBBB 样条曲线表达式为 (且 m=n+k+1)m=n+k+1)m=n+k+1)

P(t)=∑i=0nBi,k(t)Pi\mathrm{P}(\mathrm{t})=\sum_{\mathrm{i}=0}^{\mathrm{n}} \mathrm{B}_{\mathrm{i}, \mathrm{k}}(\mathrm{t}) \mathrm{P}_{\mathrm{i}}P(t)=i=0nBi,k(t)Pi

可以发现,B样条曲线的核心就是 Bi,k(t)\mathrm{B}_{\mathrm{i}, \mathrm{k}}(\mathrm{t})Bi,k(t) ,它被称为 k 次 B 样条基函数,也叫调和函数。

它满足如下递推式(deBoor递推式):

k=0,Bi,0(t)={1,t∈[ti,ti+1]0,Otherwise k>0,Bi,k(t)=t−titi+k−tiBi,k−1(t)+ti+k+1−tti+k+1−ti+1Bi+1,k−1(t)\begin{gathered} \mathrm{k}=0, \quad \mathrm{~B}_{\mathrm{i}, 0}(\mathrm{t})= \begin{cases}1, & \mathrm{t} \in\left[\mathrm{t}_{\mathrm{i}}, \mathrm{t}_{\mathrm{i}}+1\right] \\ 0, & \text { Otherwise }\end{cases} \\ \mathrm{k}>0, \quad \mathrm{~B}_{\mathrm{i}, \mathrm{k}}(\mathrm{t})=\frac{\mathrm{t}-\mathrm{t}_{\mathrm{i}}}{\mathrm{t}_{\mathrm{i}+\mathrm{k}}-\mathrm{t}_{\mathrm{i}}} \mathrm{B}_{\mathrm{i}, \mathrm{k}-1}(\mathrm{t})+\frac{\mathrm{t}_{\mathrm{i}+\mathrm{k}+1}-\mathrm{t}}{\mathrm{t}_{\mathrm{i}+\mathrm{k}+1}-\mathrm{t}_{\mathrm{i}+1}} \mathrm{~B}_{\mathrm{i}+1, \mathrm{k}-1}(\mathrm{t}) \end{gathered} k=0, Bi,0(t)={1,0,t[ti,ti+1] Otherwise k>0, Bi,k(t)=ti+ktittiBi,k1(t)+ti+k+1ti+1ti+k+1t Bi+1,k1(t)

三、Python 代码实现B样条曲线离散化

import timeimport numpy as np
from matplotlib import pyplot as pltdef getB(i, k, t, T, B):'''获取B[i][k]的值:param i: B样条基函数矩阵行索引:param k: 当前阶数(B样条基函数矩阵列索引):param t: 当前t值:param T: 节点值列表:param B: B样条基函数矩阵:return: B[i][k]的值'''if B[i, k] < 0:if k == 0:if T[i] <= t <= T[i + 1]:B[i, k] = 1else:B[i, k] = 0else:w1 = w2 = 0if T[i + k] - T[i] != 0:w1 = (t - T[i]) / (T[i + k] - T[i])if T[i + k + 1] - T[i + 1] != 0:w2 = (T[i + k + 1] - t) / (T[i + k + 1] - T[i + 1])B[i, k] = w1 * getB(i, k - 1, t, T, B) + w2 * getB(i + 1, k - 1, t, T, B)return B[i][k]def plot_spline(P, K, T):'''根据P、K、T绘制离散化的B样条曲线及其控制点:param P: 控制点列表:param K: B样条曲线阶数:param T: 节点值列表:return: None'''startTime = time.time()t = min(T)step = T[-1] / 100X, Y = [], []while t <= max(T):B = np.zeros((len(T) - 1, K + 1))B.fill(-1)x = y = 0for i in range(len(P)):b = getB(i, K, t, T, B)x += b * P[i][0]y += b * P[i][1]X.append(x)Y.append(y)t += stepprint("用时:", (time.time() - startTime), "s")plt.plot(X, Y, marker='o', label="fit point")plt.scatter([p[0] for p in P], [p[1] for p in P], color="red", label="control point")plt.legend()plt.show()if __name__ == '__main__':'''P: 控制点列表T: 节点值列表K: B样条曲线阶数'''# 测试案例1P = [[50, 50], [100, 300], [300, 100], [380, 200], [400, 600]]T = [0, 0, 0, 4 / 9, 5 / 9, 1, 1, 1]K = 2plot_spline(P, K, T)# 测试案例2P = [[2982.51, 9384.89], [3478.42, 4212.45], [9353.02, 6690.64], [4635.54, 1810.51], [12951.5, 5940.83],[7458.4, 10299.9], [14973.3, 7948.8], [8780.82, 11392.9], [14792.3, 10948.1]]T = [0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 6, 6, 6]K = 3plot_spline(P, K, T)

控制台输出

用时: 0.001992940902709961 s
用时: 0.003986835479736328 s

结果展示

在这里插入图片描述
在这里插入图片描述

四、C++ 代码实现B样条曲线离散化

4.1 主要代码

// 递归填B表
double getBValue(int i, int k, double t, vector<double> kVector, vector<vector<double>> B){if (B[i][k] == NULL){if (k == 0){if (kVector[i] <= t && kVector[i + 1] >= t){B[i][k] = 1;}else{B[i][k] = 0;}}else{double w1 = 0;double w2 = 0;if (kVector[i + k] - kVector[i] != 0){w1 = (t - kVector[i]) / (kVector[i + k] - kVector[i]);}if (kVector[i + k + 1] - kVector[i + 1] != 0){w2 = (kVector[i + k + 1] - t) / (kVector[i + k + 1] - kVector[i + 1]);}B[i][k] = w1 * getBValue(i, k - 1, t, kVector, B) + w2 * getBValue(i + 1, k - 1, t, kVector, B);}}return B[i][k];
}// B样条曲线离散化
DXFPolyLineEntities splineDiscretization(DXFSpline spline){DXFPolyLineEntities poly = DXFPolyLineEntities();int K = spline.degree;// 获取kVectorvector<double> kVector(spline.kVector.size());for (int i = 0; i < spline.kVector.size(); i++){kVector[i] = spline.kVector[i].k;}// 根据函数获得离散点for (double t = kVector[0]; t <= kVector[spline.nKnots - 1]; t += (kVector[spline.nKnots - 1] / SPLINE_D)){double x = 0.0;double y = 0.0;// 初始化B表vector<vector<double>> B(spline.nKnots - 1, vector<double>(K + 1,NULL));// 遍历控制点集合for (int i = 0; i < spline.controlPointVector.size(); i++){// 已知 i,K,t, 推出B值double bValue = getBValue(i, K, t, kVector, B);x += (bValue * spline.controlPointVector[i].x);y += (bValue * spline.controlPointVector[i].y);}poly.vertex.push_back(DL_VertexData(x, y));}return poly;
}

4.2 其余类

//多段线实体对象
class DXFPolyLineEntities
{
public:vector<DL_VertexData> vertex;//顶点bool isclose;//闭合标志位
};
/*** Vertex Data.*/
struct DXFLIB_EXPORT DL_VertexData {/*** Constructor.* Parameters: see member variables.*/DL_VertexData(double px=0.0, double py=0.0, double pz=0.0,double pBulge=0.0) {x = px;y = py;z = pz;bulge = pBulge;}/*! X Coordinate of the vertex. */double x;/*! Y Coordinate of the vertex. */double y;/*! Z Coordinate of the vertex. */double z;/*! Bulge of vertex.* (The tangent of 1/4 of the arc angle or 0 for lines) */double bulge;
};
// 样条曲线对象
class DXFSpline
{
public:// 样条曲线的阶数int degree;// 节点数int nKnots;// 控制点数int nControl;// 拟合点数(如果有)int nFit;// 样条曲线标志(按位编码)// 1 = 闭合样条曲线;// 2 = 周期样条曲线;// 4 = 有理样条曲线;// 8 = 平面;// 16 = 线性(同时设置平面位)int flags;// 相切开始和结束点坐标double tangentStartX;double tangentStartY;double tangentStartZ;double tangentEndX;double tangentEndY;double tangentEndZ;// 控制点集合vector<DL_ControlPointData> controlPointVector;// 拟合点集合vector<DL_FitPointData> fitPointVector;// 节点值集合vector<DL_KnotData> kVector;
};
/**
* Spline control point data.
*/
struct DXFLIB_EXPORT DL_ControlPointData {/*** Constructor.* Parameters: see member variables.*/DL_ControlPointData(){}DL_ControlPointData(double px, double py, double pz, double weight) {x = px;y = py;z = pz;w = weight;}/*! X coordinate of the control point. */double x;/*! Y coordinate of the control point. */double y;/*! Z coordinate of the control point. */double z;/*! Weight of control point. */double w;
};
/**
* Spline fit point data.
*/
struct DXFLIB_EXPORT DL_FitPointData {/*** Constructor.* Parameters: see member variables.*/DL_FitPointData(){}DL_FitPointData(double x, double y, double z) : x(x), y(y), z(z) {}/*! X coordinate of the fit point. */double x;/*! Y coordinate of the fit point. */double y;/*! Z coordinate of the fit point. */double z;
};
/**
* Spline knot data.
*/
struct DXFLIB_EXPORT DL_KnotData {/*** Constructor.* Parameters: see member variables.*/DL_KnotData() {}DL_KnotData(double pk) {k = pk;}/*! Knot value. */double k;
};

4.3 离散效果展示(在CAD中展示)

案例1

在这里插入图片描述

在这里插入图片描述

案例2

在这里插入图片描述

在这里插入图片描述

案例3

在这里插入图片描述
在这里插入图片描述

http://www.jmfq.cn/news/4909321.html

相关文章:

  • 济南建设网站/百度信息流广告推广
  • 中国交通建设监理协会试验检测工作委员会网站/澳门seo推广
  • 政府网站建设的现状及问题分析/cpm广告联盟平台
  • 公司做网站属于什么费用/湖南企业竞价优化
  • 中山做网站/优化师助理
  • 苏州 手机网站/希爱力5mg效果真实经历
  • 网站建设技术哪些内容/营销网站制作
  • 中国哪家做网站的公司最大/长沙市最新疫情
  • 有效的网络推广/乐山网站seo
  • 打开国外网站很慢怎么办/推广系统
  • 事业单位网站方案/免费打广告平台有哪些
  • 南京企业网站制作哪家好/seo优化排名方法
  • 用CMS做网站的好处/盐城seo培训
  • 设计师一般用什么网站/网站开发流程有哪几个阶段
  • 网站的当前位置导航如何做/店铺运营
  • 洋县住房和城乡建设管理局网站/百度游戏风云榜
  • 江西省建设工程安全质量监督管理局网站/seo计费系统开发
  • 上海服装品牌网站建设/典型的口碑营销案例
  • 手机上怎么做网站/杭州关键词排名工具
  • 网站备案跟做哪个推广有关系吗/佛山快速排名seo
  • iis7配置asp网站/百度怎么打广告在首页
  • 视频网站源码下载/seo网站优化专员
  • 深圳做微网站/中国唯一没有疫情的地方
  • 自己做网站步骤 域名/广州网站seo推广
  • 做细胞激活的母液网站/百度竞价外包
  • 金华网站建设方案开发/西安整站优化
  • 怎么生成网站源代码/影视剪辑培训机构排名
  • 百合网 网站 开发/seo站长网怎么下载
  • 汉鼎网站建设/网络营销推广的特点
  • 永川建网站/慈溪seo排名