大家好,欢迎来到IT知识分享网。
本期话题:切比雪夫(最小区域法)直线拟合算法
背景
ptb认证(切比雪夫认证)
之前有高斯认证点击前往
ptb是对几何体拟合算法的认证。
主要涉及2D直线,平面,2D圆,球,圆柱。
官方会给出点云信息,由用户将拟合结果上传到官方服务器进行对比答案,返回结果。
拟合有很多种度量标准,不同的标准出来的答案可能不完全精确。所以,要通过认证必须用官方给定的度量方法,具体可以参考论文。
认证精度要求
对于位置类型,比如圆心,直线的点等,误差不能超过0.0001mm。
对于方向,与标准值夹角不能直过0.0000001rad。
对于半径,误差不能超过0.0001mm。
对于最小区域宽度,误差不能超过0.00001mm。
学习资料
论文资料
线性规划求解最小区域
General solution for Tsebyshev approximation of form elements in coordinate measurement
线性规划应用点击前往
直线拟合输入和输出要求
输入
- 10到631个点,全部采样自直线附近。
- 每个点3个坐标,坐标精确到小数点后面20位,最后1个坐标为0。
- 坐标单位是mm, 范围[-500mm, 500mm]。
输出
- 直线上1点X0,用三个坐标表示。
- 直线方向A,用三个坐标表示,需要单位化。
- 直线度F,所有点到直线距离最大的2倍。
对于直线来讲,最小区域是指用两条平行的直线去夹住点云,使得平行线之间的距离最小。这个最小距离就是F。拟合结果就是平行线中间的那条直线。
精度要求
- X0点到标准直线距离不能超过0.0001mm。
- A与标准法向的夹角不能超过0.0000001rad。
- F与标准直线度误差不能超过0.00001mm。
直线优化标函数
根据认证要求,直线拟合转化成数学表示如下:
直线参数化表示
- 直线上1点X0 = (x0, y0,0)。
- 方向单位向量A=(a,b, 0)。
点到直线距离
第i个点 pi(xi, yi,0)。
可以根据叉乘长度为面积,面积又等于底乘高,点到直线的距离是叉乘结果除以底。底是单位向量。
d i = H = ∥ ( p i − X 0 ) × A ∥ ∥ A ∥ d_i = H =\frac { \left \| (p_i-X_0)\times A \right \|}{\left \| A \right \|} di=H=∥A∥∥(pi−X0)×A∥
d i = ∥ ( p i − X 0 ) × A ∥ d_i = \left \| (p_i-X_0)\times A \right \| di=∥(pi−X0)×A∥
展开一下:
d i = ( u i 2 + v i 2 + w i 2 ) = w i d_i = \sqrt{(u_i^2+v_i^2+w_i^2)}=w_i di=(ui2+vi2+wi2)=wi
u i = c ( y i − y 0 ) − b ( z i − z 0 ) = 0 u_i = c(y_i-y_0)-b(z_i-z_0) =0 ui=c(yi−y0)−b(zi−z0)=0
v i = a ( z i − z 0 ) − c ( x i − x 0 ) = 0 v_i = a(z_i-z_0)-c(x_i-x_0)=0 vi=a(zi−z0)−c(xi−x0)=0
w i = b ( x i − x 0 ) − a ( y i − y 0 ) w_i = b(x_i-x_0)-a(y_i-y_0) wi=b(xi−x0)−a(yi−y0)
优化能量方程
切比雪夫拟合要求所有距离中的最大值要最小。
能量方程 H = f ( X 0 , A ) = max 1 n d i H=f(X0, A)=\displaystyle \max_1^n {d_i} H=f(X0,A)=1maxndi
上式X0, A是未知量,拟合直线的过程也可以理解为优化X0, A使得方程H最小。
这里给出2种解法,1 利用凸包性质求解,2 转化为线性规划问题解决
凸包+旋转卡壳
问题解析
算法过程
正确性证明
2.一条边的最远点,可以作为下一条边的初始点。
可以看出对于红线来说,最远点是一个凸函数,会先上升后下降。
当找到点后,逆时针找蓝线的最高点,O对于蓝来说肯定还处长上升趋势。
代码实现
代码链接:https://gitcode.com/chenbb1989/3DAlgorithm/blob/master/CBB3DAlgorithm/Fitting/chebyshev/LineFitter.cpp
拟合代码
// 凸包旋转卡壳算法 namespace Chebyshev {
using namespace std; const int M = 1e6 + 10; const double eps = 1e-6; using Point = Eigen::Vector2d; double operator^ (const Point & p1, const Point &p2) {
return p1.x()* p2.y() - p1.y() * p2.x(); } Point points[M]; Point lowPoint; int st[M], top; bool cmp(Point p1, Point p2) {
p1 = p1 - lowPoint; p2 = p2 - lowPoint; double xmult = p1^p2; // 求叉积 if (abs(xmult)>eps) {
return xmult > 0; } return p1.norm() < p2.norm(); } void graham(int n) {
lowPoint = points[0]; for (int j = 0; j < n; ++j) {
if (points[j].y() < lowPoint.y() || (points[j].y() == lowPoint.y() && points[j].x() < lowPoint.x())) lowPoint = points[j]; } sort(points, points + n, cmp); top = 2; st[0] = 0; st[1] = 1; for (int i = 2; i < n; ++i) {
while (top > 2 && ((points[st[top - 1]] - points[st[top - 2]]) ^ (points[i] - points[st[top - 1]])) <= eps)top--; st[top++] = i; } } double rotate(Fitting::Line2D & line) {
double err = -1; st[top] = st[0]; // 将第一点连接后最后,作为最后一条边的终点 int up = 1; for (int i = 0; i < top; ++i) {
Point bottom = points[st[i + 1]] - points[st[i]]; bottom.normalize(); // 以i, i+1 线段为底 // 查看顶部最高点, 发现下一个点比当前点高,就+1 while (abs(bottom ^ (points[st[up]] - points[st[i]])) < abs(bottom ^ (points[st[up + 1]] - points[st[i]]))) up = (up + 1) % top; double d = abs((points[st[up]] - points[st[i]]) ^ bottom); if (err < 0 || d < err) {
err = d; line.BasePoint = points[st[up]] + points[st[i]]; line.BasePoint /= 2; line.Orient = bottom; } } return err; } double ConvexRotateFitting(const std::vector<Eigen::Vector3d>& point3ds, Fitting::Line2D& line) {
for (int i = 0; i < point3ds.size(); ++i) points[i] = Point(point3ds[i].x(), point3ds[i].y()); graham(point3ds.size()); double err = rotate(line); return err; } }
测试结果
https://gitcode.com/chenbb1989/3DAlgorithm/blob/master/CBB3DAlgorithm/Fitting/chebyshev/chebyshev-testdata/officialtest/fitting_result/result.txt C01 : LINE_2D : pass C02 : LINE_2D : pass C03 : LINE_2D : pass C04 : LINE_2D : pass C05 : LINE_2D : pass C06 : LINE_2D : pass C07 : LINE_2D : pass C08 : LINE_2D : pass
线性规划迭代法
化整为零
设 a = ( x 0 , y 0 , a , b ) , d i = F ( x i ; a ) , 引入 Γ = M A X i = 1 n d i 设a=(x_0, y_0, a, b), d_i=F(x_i;\ a), 引入\Gamma=\overset n{\underset {i=1}{MAX}}\;d_i 设a=(x0,y0,a,b),di=F(xi; a),引入Γ=i=1MAXndi
根据上述定义,可以将原来的最值问题转化为下述条件
对于所有点应该满足
F ( x i ; a ) ≤ Γ , ( F ( x i ; a ) > 0 ) F(x_i;\ a)\le \Gamma, (F(x_i;\ a)>0) F(xi; a)≤Γ,(F(xi; a)>0)
− F ( x i ; a ) ≤ Γ , ( F ( x i ; a ) < 0 ) -F(x_i;\ a)\le \Gamma, (F(x_i;\ a)<0) −F(xi; a)≤Γ,(F(xi; a)<0)
我们可以通过小量迭代慢慢减小Γ
增量基本原理
设 a = ( a 0 , a 1 , . . . , a n ) 、 Γ 是待求解变量, a ^ , Γ ^ 是初始给定值, a = a ^ + Δ a , Γ = Γ ^ − Δ Γ . Δ a 、 Δ Γ 是我们每次迭代后移动的量 设 a=(a_0, a_1,…,a_n)、\Gamma 是待求解变量,\widehat {a}, \widehat {\Gamma} 是初始给定值,a = \widehat {a} +\Delta a, \Gamma = \widehat {\Gamma} -\Delta \Gamma. \ \Delta a、 \Delta \Gamma 是我们每次迭代后移动的量 设a=(a0,a1,…,an)、Γ是待求解变量,a
,Γ
是初始给定值,a=a
+Δa,Γ=Γ
−ΔΓ. Δa、ΔΓ是我们每次迭代后移动的量
定义距离函数为 F ( x , a ) , d i = F ( x i , a ) , 进行泰勒 1 阶展开, F ( x , a ) = F ( x , a ^ ) + ∂ F ∂ a ^ Δ a = F ( x , a ^ ) + J Δ a 定义距离函数为 F(x, a), d_i = F(x_i, a), 进行泰勒1阶展开, F(x, a) = F(x, \widehat a) + \frac {\partial F}{\partial \widehat a}\Delta a = F(x, \widehat a) + J\Delta a 定义距离函数为F(x,a),di=F(xi,a),进行泰勒1阶展开,F(x,a)=F(x,a
)+∂a
∂FΔa=F(x,a
)+JΔa
每次迭代,其实就是希望通过调整 Δ a , Δ Γ ≥ 0 使得 F ( x , a ^ ) + J Δ a ≤ Γ ^ − Δ Γ . 每次迭代,其实就是希望通过调整\Delta a, \Delta \Gamma\ge0 使得 F(x, \widehat a) + J\Delta a \le \widehat {\Gamma} -\Delta \Gamma. 每次迭代,其实就是希望通过调整Δa,ΔΓ≥0使得F(x,a
)+JΔa≤Γ
−ΔΓ.
J = [ ∂ F ( x 0 , a ^ ) ∂ a 0 ∂ F ( x 0 , a ^ ) ∂ a 1 . . . ∂ F ( x 0 , a ^ ) ∂ a n ∂ F ( x 1 , a ^ ) ∂ a 0 ∂ F ( x 1 , a ^ ) ∂ a 1 . . . ∂ F ( x 1 , a ^ ) ∂ a n . . . . . . . . . . . . ∂ F ( x n , a ^ ) ∂ a 0 ∂ F ( x n , a ^ ) ∂ a 1 . . . ∂ F ( x n , a ^ ) ∂ a n ] J = \begin {bmatrix} \frac {\partial F(x_0, \widehat {a})} {\partial a_0} & \frac {\partial F(x_0, \widehat {a})} {\partial a_1} & …& \frac {\partial F(x_0, \widehat {a})} {\partial a_n} \\ \\ \frac {\partial F(x_1, \widehat {a})} {\partial a_0} & \frac {\partial F(x_1, \widehat {a})} {\partial a_1} & …& \frac {\partial F(x_1, \widehat {a})} {\partial a_n} \\\\ … & … & …& … \\ \\ \frac {\partial F(x_n, \widehat {a})} {\partial a_0} & \frac {\partial F(x_n, \widehat {a})} {\partial a_1} & …& \frac {\partial F(x_n, \widehat {a})} {\partial a_n} \end {bmatrix} J=
∂a0∂F(x0,a
)∂a0∂F(x1,a
)…∂a0∂F(xn,a
)∂a1∂F(x0,a
)∂a1∂F(x1,a
)…∂a1∂F(xn,a
)…………∂an∂F(x0,a
)∂an∂F(x1,a
)…∂an∂F(xn,a
)
F ( x , a ^ ) = [ d 1 d 2 . . . d m ] F(x, \widehat a) = \begin {bmatrix} d_1 \\ d_2 \\… \\ d_m \end {bmatrix} F(x,a
)=
d1d2…dm
整体问题就转化为线性规划问题
m a x Δ Γ s . t . F ( x i , a ) + J Δ a ≤ Γ − Δ Γ , ( i = 1 , 2… n ) − ( F ( x i , a ) + J Δ a ) ≤ Γ − Δ Γ , ( i = 1 , 2… n ) Δ Γ ≥ 0 \begin {array}{c}max \ \ \ \ \Delta {\Gamma}\\ s.t.\ \ \ F(x_i, a) + J\Delta a \le \Gamma -\Delta \Gamma, (i=1,2…n)\\ \ \ \ \ \ \ \ \ \ -(F(x_i, a) + J\Delta a) \le \Gamma -\Delta \Gamma, (i=1,2…n)\\ \Delta \Gamma \ge0\end{array} max ΔΓs.t. F(xi,a)+JΔa≤Γ−ΔΓ,(i=1,2…n) −(F(xi,a)+JΔa)≤Γ−ΔΓ,(i=1,2…n)ΔΓ≥0
上述条件不需要管 F ( x i , a ) + J Δ a 正负情况,若 F ( x i , a ) + J Δ a 为正 − ( F ( x i , a ) + J Δ a ) ≤ Γ − Δ Γ 必成立,反之亦然。 上述条件不需要管F(x_i, a) + J\Delta a正负情况,若F(x_i, a) + J\Delta a为正-(F(x_i, a) + J\Delta a) \le \Gamma -\Delta \Gamma必成立,反之亦然。 上述条件不需要管F(xi,a)+JΔa正负情况,若F(xi,a)+JΔa为正−(F(xi,a)+JΔa)≤Γ−ΔΓ必成立,反之亦然。
求解出以后更新a, Γ。
用2个数表示2D直线
如果直接拿4个参数表示直线去做迭代,1是比较麻烦,会出现比较难解的方向,2是法向长度不固定,结果不唯一。
当直线与Y轴偏差比较小的时候可以使用2个参数来表示直线。
如上图,绿线为Y轴,橙色线为X轴。
由于法向与Y轴比较相近,可以设法向为(a, 1), a 是比较小的量。
规定直线上1点需要在以(1, -a)为法向,过0点的平面上。
则有 ax0+y0=0, 只要知道x0可知 y0 = -ax0。
直线拟合模型转化(旋转到接近Y轴后)
将线性规划模型应用于直线拟合
m a x Δ Γ s . t . F ( x i , { x 0 , a } ) + J ⋅ ( Δ x 0 , Δ a ) ≤ Γ − Δ Γ , ( i = 1 , 2… n ) − F ( x i , { x 0 , a } ) − J ⋅ ( Δ x 0 , Δ a ) ≤ Γ − Δ Γ , ( i = 1 , 2… n ) Δ Γ ≥ 0 \begin {array}{c}max \ \ \ \ \Delta {\Gamma}\\ s.t.\ \ \ F(x_i, \{x_0, a\}) + J \cdot (\Delta x_0, \Delta a) \le \Gamma -\Delta \Gamma, (i=1,2…n)\\ -F(x_i, \{x_0, a\}) – J \cdot (\Delta x_0, \Delta a) \le \Gamma -\Delta \Gamma, (i=1,2…n)\\ \Delta \Gamma \ge0\end{array} max ΔΓs.t. F(xi,{
x0,a})+J⋅(Δx0,Δa)≤Γ−ΔΓ,(i=1,2…n)−F(xi,{
x0,a})−J⋅(Δx0,Δa)≤Γ−ΔΓ,(i=1,2…n)ΔΓ≥0
上述条件还不能直接用单纯形求解,要转化为线性规划点击前往问题
需要对 Δ x 0 , Δ a 拆解,要求变量都要大于等于 0 需要对\Delta x_0, \Delta a 拆解,要求变量都要大于等于0 需要对Δx0,Δa拆解,要求变量都要大于等于0
m a x Δ Γ s . t . J i ⋅ ( Δ x 0 + - Δ x 0 - , Δ a + - Δ a - ) + Δ Γ ≤ Γ - d i , ( i = 1 , 2… n ) − J i ⋅ ( Δ x 0 + - Δ x 0 - , Δ a + - Δ a - ) + Δ Γ ≤ Γ + d i , ( i = 1 , 2… n ) Δ x 0 + , Δ x 0 − , Δ a + , Δ a − , Δ Γ ≥ 0 \begin {array}{c}max \ \ \ \ \Delta {\Gamma}\\ s.t.\ \ \ J_i \cdot (\Delta x_0^+-\Delta x_0^-, \Delta a^+-\Delta a^-) +\Delta \Gamma\\\le \Gamma-d_i, (i=1,2…n)\\ -J_i \cdot (\Delta x_0^+-\Delta x_0^-, \Delta a^+-\Delta a^-) +\Delta \Gamma\\\le \Gamma+d_i, (i=1,2…n)\\ \Delta x_0^+, \Delta x_0^-, \Delta a^+, \Delta a^-,\Delta \Gamma \ge0\end{array} max ΔΓs.t. Ji⋅(Δx0+-Δx0-,Δa+-Δa-)+ΔΓ≤Γ-di,(i=1,2…n)−Ji⋅(Δx0+-Δx0-,Δa+-Δa-)+ΔΓ≤Γ+di,(i=1,2…n)Δx0+,Δx0−,Δa+,Δa−,ΔΓ≥0
算法描述
回顾一下
d i = b ( x i − x 0 ) − a ( y i − y 0 ) = x i , x 0 = 0 , y 0 = 0 , a = 0 , b = 1 d_i= b(x_i-x_0) – a(y_i-y_0)= x_i, x_0=0, y_0=0, a=0, b=1 di=b(xi−x0)−a(yi−y0)=xi,x0=0,y0=0,a=0,b=1
J, D的计算。
J = ∂ d 1 ∂ x 0 ∂ d 1 ∂ a ∂ d 2 ∂ x 0 ∂ d 2 ∂ a . . . . . . ∂ d n ∂ x 0 ∂ d n ∂ a , D = d 1 d 2 . . . d n J= \begin{array}{l} \frac {\partial d_1}{\partial x_0}& \frac {\partial d_1}{\partial a} \\ \frac {\partial d_2}{\partial x_0}& \frac {\partial d_2}{\partial a}\\…&…\\\frac {\partial d_n}{\partial x_0}& \frac {\partial d_n}{\partial a}\\ \end {array}, \ D= \begin{array}{l} d_1\\d_2\\…\\d_n\end {array} J=∂x0∂d1∂x0∂d2…∂x0∂dn∂a∂d1∂a∂d2…∂a∂dn, D=d1d2…dn
2个未知分别对d_i求导结果如下:
∂ d i ∂ x 0 = − b = − 1 \frac {\partial d_i} {\partial x_0}=-b=-1 ∂x0∂di=−b=−1
∂ d i ∂ a = − y i \frac {\partial d_i} {\partial a}=-y_i ∂a∂di=−yi
一次迭代过程
- 确定直线初值
- 将中轴通过刚体变换U至Z轴,U的构建可以参考代码
[ x i y i ] = U ⋅ ( [ x i y i ] − [ x 0 y 0 ] ) \begin {bmatrix}x_i \\ y_i \end {bmatrix} = U \cdot \left (\begin {bmatrix}x_i \\ y_i \\ \end {bmatrix}- \begin{bmatrix}x_0 \\ y_0 \end {bmatrix}\right ) [xiyi]=U⋅([xiyi]−[x0y0]) - 根据上述公式构建线性规划方程
- 求解 Δ p \Delta p Δp
- 更新解
[ x 0 y 0 ] = [ x 0 y 0 ] + U T ⋅ [ p x 0 − p a p x 0 ] [ a b ] = U T ⋅ [ p a 1 ] . n o r m a l i z e ( ) Γ = Γ − Δ Γ \begin {array}{l}\\ \begin {bmatrix}x_0 \\ y_0 \end {bmatrix} = \begin {bmatrix}x_0 \\ y_0 \end {bmatrix} + U^T \cdot \begin{bmatrix}p_{x_0} \\ -p_ap_{x_0}\end {bmatrix} \\ \\\begin {bmatrix}a \\ b \end {bmatrix} = U^T \cdot \begin{bmatrix}p_a \\ 1 \end {bmatrix}.normalize() \\\\ \Gamma=\Gamma-\Delta \Gamma \end {array} [x0y0]=[x0y0]+UT⋅[px0−papx0][ab]=UT⋅[pa1].normalize()Γ=Γ−ΔΓ - 重复2直到收敛
最后,输出时F=2*Γ
初值确定
枚举所有两点确定直线,直线度误差最小的作为结果。
代码实现
代码链接:https://gitcode.com/chenbb1989/3DAlgorithm/blob/master/CBB3DAlgorithm/Fitting/chebyshev/LineFitter.cpp
拟合代码
namespace Chebyshev {
double LineFitter::F(Fitting::Line2D line, const Point& p) {
auto de = Eigen::Vector2d(p.x(), p.y()) - line.BasePoint; return abs(de.x() * line.Orient.y() - de.y() * line.Orient.x()); } double LineFitter::GetError(Fitting::Line2D line, const std::vector<Eigen::Vector3d>& points) {
double err = 0; for (auto& p : points) {
err = std::max(err, F(line, p)); } return err; } Fitting::Matrix LineFitter::Jacobi(const std::vector<Eigen::Vector3d>& points) {
Fitting::Matrix J(points.size(), 2); for (int i = 0; i < points.size(); ++i) {
auto& p = points[i]; J(i, 0) = -1; J(i, 1) = -p.y(); } return J; } void LineFitter::beforHook(const std::vector<Eigen::Vector3d>& points) {
U.setIdentity(); U(0, 0) = line.Orient.y(); U(0, 1) = -line.Orient.x(); U(1, 0) = line.Orient.x(); U(1, 1) = line.Orient.y(); Point kBasePt(line.BasePoint.x(), line.BasePoint.y(), 0); for (int i = 0; i < points.size(); ++i)transPoints[i] = U * (points[i] - kBasePt); } void LineFitter::afterHook(const Eigen::VectorXd& xp) {
Point bp = U.transpose() * Point(xp(0), -xp(0) * xp(1), 0); line.BasePoint += Eigen::Vector2d(bp.x(), bp.y()); bp = U.transpose() * Point(xp(1), 1, 0).normalized(); line.Orient = Eigen::Vector2d(bp.x(), bp.y()); gamma -= xp(2); } Eigen::VectorXd LineFitter::getDArray(const std::vector<Eigen::Vector3d>& points) {
Eigen::VectorXd D(points.size()); for (int i = 0; i < points.size(); ++i)D(i) = points[i].x(); return D; } bool LineFitter::GetInitFit(const std::vector<Eigen::Vector3d>& points) {
if (points.size() < 2)return false; gamma = -1; // 枚举任意两点,选取误差最小的直线 for (int i = 0; i < points.size(); ++i) {
for (int j = i + 1; j < points.size(); ++j) {
Fitting::Line2D tline; tline.BasePoint = {
points[i].x(), points[i].y() }; tline.Orient = {
points[i].x() - points[j].x(), points[i].y() - points[j].y() }; tline.Orient.normalize(); double err = GetError(tline, points); if (gamma < 0 || err < gamma) {
gamma = err; line = tline; } } } return true; } double LineFitter::F(const Eigen::Vector3d& p) {
return Chebyshev::LineFitter::F(line, p); } double LineFitter::GetError(const std::vector<Eigen::Vector3d>& points) {
return Chebyshev::LineFitter::GetError(line, points); } void LineFitter::Copy(void* ele) {
memcpy(ele, &line, sizeof(Fitting::Line2D)); } LineFitter::LineFitter() {
ft = Fitting::FittingType::CHEBYSHEV; } }
测试代码
void TestAllCase() {
string caseDir = "D:/selfad/alg_and_graph/3DAlgorithm/CBB3DAlgorithm/Fitting/chebyshev/chebyshev-testdata/officialtest/"; FILE* caseList = fopen((caseDir+"data/kind.txt").c_str(), "r"); char baseID[100], kind[100]; FILE* testResult = fopen((caseDir + "fitting_result/result.txt").c_str(), "w"); while (fscanf(caseList, "%s", baseID) != EOF) {
strcpy(kind, baseID + 4); baseID[3] = 0; /*puts(baseID); puts(kind);*/ Fitting::TestBase* testLogic = getTestObj(kind); if (testLogic == NULL)continue; fprintf(testResult, "%s : %s : ", baseID, kind); printf("%s : %s : ", baseID, kind); testLogic->SetFile(caseDir, baseID); testLogic->readPoints(); testLogic->Fitting(); FILE* ansfp = fopen((caseDir + "fitting_result/" + baseID + ".txt").c_str(), "w"); testLogic->SaveAnswer(ansfp); fprintf(testResult, "%s\n", testLogic->JudgeAnswer(NULL)?"pass":"failed"); printf("%s\n", testLogic->JudgeAnswer(NULL)?"pass":"failed"); fclose(ansfp); delete testLogic; } fclose(caseList); fclose(testResult); puts("TEST COMPLETE"); }
测试结果
https://gitcode.com/chenbb1989/3DAlgorithm/blob/master/CBB3DAlgorithm/Fitting/chebyshev/chebyshev-testdata/officialtest/fitting_result/result.txt C01 : LINE_2D : pass C02 : LINE_2D : pass C03 : LINE_2D : pass C04 : LINE_2D : pass C05 : LINE_2D : pass C06 : LINE_2D : pass C07 : LINE_2D : pass C08 : LINE_2D : pass
本人码农,希望通过自己的分享,让大家更容易学懂计算机知识。创作不易,帮忙点击公众号的链接。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/120859.html




