内容来自高老师的《三维CAD建模》课,本文就主要介绍半边结构和欧拉操作以及代码实现。

1. 边界表示法及其数据结构

· 拓扑结构

a.拓扑元素:面、边、点、体

b.拓扑关系:9种。V{V},V{E},V{F};  E{V},E{E},E{F};  F{V},F{E},F{F};

· 几何信息(狭义):描述物体的大小位置和尺寸等信息。点->坐标;边->方程;面->方程;

· 拓扑与集合元素对应关系

Vertex<-->Point;    Edge<-->Curve;     Face<-->Surface;

2. 翼边数据结构(Wing-Edge)

定义:一组首尾相连封闭二维区域形成一个环(Loop)

拓扑关系选择:E{V},E{E},E{F},V{E}

翼边结构表示:

通过判定Loop在边的左边还是右边,判断绕向来找到Loop上的所有边。

这种边的结构是不满足二维流形的可定向条件。在这个基础上对翼边的结构进行改进,提出了半边结构的思想,满足了可定向性。

半边结构表示:

半边结构在计算机中的数据结构表示:

虚线代表可以生成线框模型:{V},{E},E{V}

带空的环称为(rings)

核心思想:边在三维模型的表达中是一个重要元素,以边为重点来组织数据结构

3. 基于B-rep的建模操作

3.1 欧拉操作

欧拉操作旨在有效的构建B-rep中的拓扑结构(通用、有效)

欧拉公式:V+F-E=2

扩展:V+F-E=2(S-h)+r,其中S是体的个数,h是柄的个数,r是内环的个数

3.2 欧拉操作的设计思想

基于欧拉公式来保证其有效性。希望提供一组通用、完备的B-rep的拓扑生成操作。我的理解是欧拉操作给模型的拓扑生成提供了完备的理论依据。

3.3 欧拉操作的选择(6维空间的5维超平面)

v     e     f     h    r    s     Operator

1     1     0    0    0    0       mev

0     1     1    0    0    0       mef

1     0     1    0    0    1       mvfs

0    -1     0    0    1    0       kemr

0     0    -1    1    1    0       kfmrh

· mvsf(v, f): 生成含有一个点的面,并且构成一个新的体

· kvsf: 删除一个体,该体仅含有一个点的面

· mev(v1, v2, e):生成一个新的点e2,连接该点到已有点v1,构造一条新的边

· kev(e, v):删除一条边和该边的一个端点v

· mef(v1,v2,f1,f2,e):连接面f1上的两个点v1,v2,生成一条新边e,并产生一个新面

· kef(e):删除一条边e和该边的一个邻面f

· kemr(e):删除一条边e,生成该边某一邻面上的新的内环

· mekr(v1,v2,e):连接两个点v1、v2、,生成一条新的边e,并删除掉v1和v2所在面上一个内环

· kfmrh(f1,f2,):删除与面f1相接触的一个面f2,生成面f1上的一个内环,并形成体上的一个通孔

· mfkrh(f1,f2):删除面f1上的一个内环,生成一个新的面f2,由此也删除了体上的一个通孔

两个辅助操作:

· semv(e1,v,e2):将e1分割成两段,生成一个新的点v和一条新的边e2

· jekv(e1,e2):合并两条相邻的边e1、e2,删除它们的公共端点

以上欧拉操作仅适用正则形体

3.4 欧拉操作具体功能与实现

(1)mvfs():定义一个体、一个面、一个外环、一个点。

伪代码:

1 OBJECT *mvfs()
2 {
3     FACE *f; OBJECT *ob; LOOP *lp; VERTEX *v;//对以上元素开辟空间
4     ob->sfaces = f; f->fsolid = ob;
5     f->floops = lp; lp->lface = f; lp->ledge = NULL;
6     return ob;
7 }

View Code

(2)mev():构造一个新点,同是构造一条连接新点与一给定点的边

伪代码:

 1 HalfEdge *mev(v1, lp)
 2 {
 3     HalfEdge *he1, *he2, *he;
 4     Edge *eg; VERTEX *v2;
 5     he1->edge = he2->edge = eg;
 6     eg->he1 = he1; eg->he2 = he2;
 7     he1->wloop = he2->wloop = lp;
 8     he1->startv = v1;
 9     he2->startv = v2;
10     he1->next = he2;
11     if (lp->ledge == NULL)
12         he2->next = he1;
13         lp->ledge = he1;
14     else
15         for (he = lp->ledge; he = next->startv != v1; he = he->next)
16             he2->next = he->next;
17             he->next = he1;
18     return he1;
19 }

View Code

这里列出的伪代码是上课讲解的一部分,后面会附上C++的源码。

我自己的理解,关键在于弄懂欧拉操作构造实体时候它的Loop环绕向一定要正确,每个拓扑面的关系,根据这个自己可以很容易的实现上面的伪代码。

3.5 欧拉操作的几个讨论

可以证明:欧拉操作是有效的;用欧拉操作对形体操作结果在物理上是可实现的,欧拉操作是完备的,任何形体可在有限步的欧拉操作中构造出来。

· 所有流形体的B-rep,欧拉操作都能构造

 · 在拓扑结构上都有效

· 将其正确嵌入3维空间结果一定是流形体

这些都给CAD模型中流形体的构建提供了理论的依据,所以底层的大厦由此慢慢开始建立,就像数学的光辉殿堂一样,理论的强有力的证明为它带来了严谨而且让人信服的意义。

3.6 扫成操作(Sweeping)

  日常生活中的物体都是由基本的长方体、圆柱(70%)以及锥、球等形成

  扫成体:有一个平面区域(直线段、圆弧、自由曲线围成的二维曲线),延一条可定的轨迹线,扫描产生三维空间点集

  平移扫成(translational sweeping)    轨迹是一条直线。

几何构造:

· 每一个给定点->新点->新边(侧边)

· 每一个给定边->新边->新面(平面,圆柱面、指纹面,自由曲面)

伪代码:

 1 Sweep(S:Solid, F:Face, V:Vector, d:Real)
 2 begin:
 3     L = loop of F;
 4     firstv = first Vertex of L;
 5     firstup = firstv + d.v;
 6     mev(firstv, firstup, newe);
 7     prevup = firstup; nextv = next Vertex of L;
 8     while (nextv not equal to firstv)
 9     begin:
10         up = nextv + d.v;
11         mev(nextv, up, newe);
12         mef(prevup, up, F, newf, newe);
13         prevup = up; nextv = next Vertex of L;
14     end
15     mef(prevup, firstup, F, newf, newe);
16 end

View Code

3.7 相关实际实现代码分析

  作业的要求是实现实现基本的欧拉操作,完成带孔正则物体的构造。我采用的是Glut作为显示部分,自己编写半边结构和欧拉操作。总体的模块分为HalfEdgeDS负责半边结构的定义和欧拉操作实现,SolidFactoy负责产生实体Solid通过欧拉操作或Sweep扫成,GlutDisplay负责显示得到的Solid模型。

半边结构的定义:

/************************************************************************/
/*                          Author: Li Xin                                   */
/*                            Date: 2013-10-19                            */
/************************************************************************/class Solid;
class Face;
class Loop;
class Edge;
class HalfEdge;
class Vertex;
class Point;//体
class Solid
{
public:Solid():prevs(NULL), nexts(NULL), sface(NULL), edge(NULL){}Solid *prevs;Solid *nexts;Face *sface;    //首面;Edge *edge;        //用于线框显示的边
};//面
class Face
{
public:Face():prevf(NULL), nextf(NULL), fsolid(NULL), floops(NULL){}Face *prevf;Face *nextf;Solid *fsolid;Loop *floops;    //首环
};//环
class Loop
{
public:Loop():prevl(NULL), nextl(NULL), lface(NULL), ledge(NULL){}Loop *prevl;Loop *nextl;Face *lface;HalfEdge *ledge;//首边
};//半边
class HalfEdge
{
public:HalfEdge():prev(NULL), next(NULL), adjacent(NULL), startv(NULL), endv(NULL), hloop(NULL), edge(NULL){}HalfEdge *prev;HalfEdge *next;HalfEdge *adjacent;Vertex *startv;Vertex *endv;Loop *hloop;Edge *edge;    //边
};//边
class Edge
{
public:Edge():preve(NULL), nexte(NULL), HalfEdge1(NULL), HalfEdge2(NULL){}Edge *preve;Edge *nexte;HalfEdge *HalfEdge1;HalfEdge *HalfEdge2;
};//几何点
class Point
{
public:double coord[3];double* GetCoord(){return coord;}void SetCoord(double x, double y, double z);void SetCoord(Point point);friend inline istream & operator >> (istream & is,Point & point){is >> point.coord[0] >> point.coord[1] >> point.coord[2];return is ;}friend inline ostream& operator << (ostream & os,Point & point){os << "( " << point.coord[0] << ", " << point.coord[1] << ", " << point.coord[2] << " )";return os ;}
};//顶点
class Vertex
{
public:Vertex():prevv(NULL), nextv(NULL) {}Vertex *prevv;Vertex *nextv;Point point;
};class Half_Edge_DS
{
public:Half_Edge_DS():solid(NULL){}~Half_Edge_DS();//数据结构Solid        *solid;//欧拉操作Solid * mvfs(Point point, Vertex *& newVertex);    //构造一个体,一个面,一个外环,一个点HalfEdge * mev(Vertex *v1, Point p2, Loop *lp ); //构造一个新点,同时构造一条连接新点与一给定点的边Loop * mef(Vertex *v1, Vertex *v2, Loop *lp);//构造一个边,一个面,一个环Loop * kemr(Vertex *v1, Vertex *v2, Loop *lp);//删除一条边构造一个环void kfmrh(Loop *outlp, Loop *lp);//删除一个与面f1相接触的一个面f2,声称面f1上的一个面上内环,并形成体上一个通孔

};

View Code

mvfs的实现:

 1 Solid * Half_Edge_DS::mvfs(Point point, Vertex *& newVertex)
 2 {
 3     //建立点、面、体、环
 4     Solid *newSolid = new Solid;
 5     Face *newFace = new Face;
 6     Loop *newLoop = new Loop;
 7
 8     newVertex = new Vertex;
 9     //记录初始点的几何信息
10     newVertex->point.SetCoord(point);
11
12     //构建拓扑关系
13     newSolid->sface = newFace;
14     newFace->fsolid = newSolid;
15     newFace->floops = newLoop;
16     newLoop->lface = newFace;
17     newLoop->ledge = NULL;
18     return newSolid;
19 }

View Code

mev的实现:

 1 HalfEdge * Half_Edge_DS::mev( Vertex *v1, Point p2, Loop *lp )
 2 {
 3     Solid *solid = lp->lface->fsolid;
 4     HalfEdge *he1 = new HalfEdge;
 5     HalfEdge *he2 = new HalfEdge;
 6     HalfEdge *he = new HalfEdge;
 7     Edge *edge = new Edge;
 8
 9     Vertex *v2 = new Vertex;
10     v2->point.SetCoord(p2);
11
12     he1->edge = he2->edge = edge;
13     edge->HalfEdge1 = he1;
14     edge->HalfEdge2 = he2;
15
16     he1->hloop = he2->hloop = lp;
17     he1->startv = v1;
18     he1->endv = v2;
19     he2->startv = v2;
20     he2->endv = v1;
21
22     he1->adjacent = he2;
23     he2->adjacent = he1;
24
25     if (lp->ledge == NULL)
26     {//First create edge
27         he1->next = he2;
28         he2->prev = he1;
29         he2->next = he1;
30         he1->prev = he2;
31         lp->ledge = he1;
32     }
33     else
34     {//Following create edges
35         for (he = lp->ledge; he->next->startv != v1; he = he->next);
36
37         he1->next = he2;
38         he1->prev = he;
39         he2->next = he->next;
40         he2->prev = he1;
41         he->next->prev = he2;
42         he->next = he1;
43     }
44
45     //Maintain Edge List
46     Edge *curEdge = solid->edge;
47     while (curEdge != NULL && curEdge->nexte != NULL)
48     {
49         curEdge = curEdge->nexte;
50     }
51     if (curEdge == NULL)    solid->edge = edge;
52     else
53     {
54         curEdge->nexte = edge;
55         edge->preve = curEdge;
56     }
57
58     return he1;
59 }

View Code

mef的实现:

 1 Loop * Half_Edge_DS::mef( Vertex *v1, Vertex *v2, Loop *lp )
 2 {
 3     Solid *solid = lp->lface->fsolid;
 4     Face *face = new Face;
 5     Loop *loop = new Loop;
 6     HalfEdge *he1 = new HalfEdge;
 7     HalfEdge *he2 = new HalfEdge;
 8     Edge *edge = new Edge;
 9
10     //Create HalfEdge and Edge
11     he1->startv = v1;
12     he1->endv = v2;
13     he2->startv = v2;
14     he2->endv = v1;
15     he1->adjacent = he2;
16     he2->adjacent = he1;
17
18     edge->HalfEdge1 = he1;
19     edge->HalfEdge2 = he2;
20     he1->edge = he2->edge = edge;
21
22     //Find the HalfEdge
23     HalfEdge *tmphe1, *tmphe2, *tmphe;
24     for (tmphe = lp->ledge; tmphe->startv != v1; tmphe = tmphe->next);
25     tmphe1 = tmphe;
26
27     for (; tmphe->startv != v2; tmphe = tmphe->next);
28     tmphe2 = tmphe;
29     tmphe = tmphe->next;
30     while (tmphe->startv != v2)
31     {
32         tmphe = tmphe->next;
33     }
34     bool HaveRoll = false;
35     if(tmphe != tmphe2)
36     {
37         HaveRoll = true;
38         tmphe2 = tmphe;
39     }
40
41     //for (tmphe2 = lp->ledge; tmphe2->endv != v2; tmphe2 = tmphe2->next);
42
43 //  he1->next = tmphe2->next;
44 //  he1->prev = tmphe1;
45 //  he2->next = tmphe1->next;
46 //  he2->prev = tmphe2;
47 //  tmphe1->next->prev = he2;
48 //  tmphe1->next = he1;
49 //  tmphe2->next->prev = he1;
50 //  tmphe2->next = he2;
51
52     he1->next = tmphe2;
53     he1->prev = tmphe1->prev;
54     he2->next = tmphe1;
55     he2->prev = tmphe2->prev;
56
57
58     tmphe1->prev->next = he1;
59     tmphe1->prev = he2;
60
61     tmphe2->prev->next = he2;
62     tmphe2->prev = he1;
63
64     //loop have problem
65
66     //Inner loop
67     loop->ledge = he1;
68     //Recur loop
69     lp->ledge = he2;
70
71     //Create A new Face
72     face->floops = loop;
73     face->fsolid = solid;
74     loop->lface = face;
75     //Add Face to Solid
76     Face *tmpFace;
77     for (tmpFace = solid->sface; tmpFace->nextf != NULL; tmpFace = tmpFace->nextf);
78     tmpFace->nextf = face;
79     face->prevf = tmpFace;
80     face->fsolid = solid;
81
82
83     //Maintain Edge List
84     Edge *curEdge = solid->edge;
85     while (curEdge != NULL && curEdge->nexte != NULL)
86     {
87         curEdge = curEdge->nexte;
88     }
89     if (curEdge == NULL)    solid->edge = edge;
90     else
91     {
92         curEdge->nexte = edge;
93         edge->preve = curEdge;
94     }
95
96     return loop;
97
98 }

View Code

  其实mef考虑的时候,有两种情况。1.不带内环,3次mev操作然后mef操作;2.带内环mef,在kemr之前的,这时候在寻找半边的时候需要注意一下半边的方向,这里我写的代码判断复杂了,画一个图分析下,也很好改,这里就不再赘述了。

kemr的实现:

 1 Loop * Half_Edge_DS::kemr( Vertex *v1, Vertex *v2, Loop *lp )
 2 {
 3     Face *face = lp->lface;
 4     Solid *solid = face->fsolid;
 5     Loop *loop = new Loop;
 6
 7     HalfEdge *he;
 8     //find the half edge
 9     for (he = lp->ledge; (he->startv != v2) || (he->endv != v1); he = he->next);
10
11     //get related edge
12     Edge *edge;
13     edge = he->edge;
14
15     //create loop relation
16     he->next->prev = he->adjacent->prev;
17     he->adjacent->prev->next = he->next;
18
19     he->prev->next = he->adjacent->next;
20     he->adjacent->next->prev = he->prev;
21
22     lp->ledge = he->next->prev;
23
24     loop->ledge = he->prev;
25     loop->lface = face;
26
27     //insert the inner loop
28     if (face->floops == NULL)
29         face->floops = loop;
30     else
31     {
32         Loop *tmpLoop;
33         for (tmpLoop = face->floops; tmpLoop->nextl != NULL; tmpLoop = tmpLoop->nextl);
34         tmpLoop->nextl = loop;
35         loop->prevl = tmpLoop;
36     }
37
38     //find edge will delete
39     Edge *tmpEdge = solid->edge;
40     while ( tmpEdge != edge)
41     {
42         tmpEdge = tmpEdge->nexte;
43     }
44     //delete edge
45     if (tmpEdge->nexte == NULL)
46     {
47         tmpEdge->preve->nexte = NULL;
48     }
49     else if(tmpEdge->preve == NULL)
50     {
51         solid->edge = tmpEdge->nexte;
52         tmpEdge->nexte->preve = NULL;
53     }
54     else
55     {
56         tmpEdge->preve->nexte = tmpEdge->nexte;
57         tmpEdge->nexte->preve = tmpEdge->preve;
58     }
59     delete tmpEdge;
60     return loop;
61 }

View Code

kfmrh的实现:

 1 void Half_Edge_DS::kfmrh( Loop *outlp, Loop *lp )
 2 {
 3
 4     Face *face1 = outlp->lface;
 5     Face *face2 = lp->lface; // 要删去的顶面 的环,将它降到底面当内环,删去这个面。
 6     //add inner loop to face
 7     if (face1->floops == NULL)
 8         face1->floops = lp;
 9     else
10     {
11         Loop *tmpLoop;
12         for (tmpLoop = face1->floops; tmpLoop->nextl != NULL; tmpLoop = tmpLoop->nextl);
13         tmpLoop->nextl = lp;
14         lp->prevl = tmpLoop;
15     }
16     lp->lface = face1;
17
18     //Find the face to remove
19     Solid *solid = face1->fsolid;
20     Face *tmpFace = solid->sface;
21     while ( tmpFace != face2)
22     {
23         tmpFace = tmpFace->nextf;
24     }
25     //delete Face
26     if (tmpFace->nextf == NULL)
27     {
28         tmpFace->prevf->nextf = NULL;
29     }
30     else if(tmpFace->prevf == NULL)
31     {
32         solid->sface = tmpFace->nextf;
33         tmpFace->nextf->prevf = NULL;
34     }
35     else
36     {
37         tmpFace->prevf->nextf = tmpFace->nextf;
38         tmpFace->nextf->prevf = tmpFace->prevf;
39     }
40     delete tmpFace;
41 }

View Code

扫成操作:

 1 void SolidFactory::Sweep( Face *face, double vec[3], double d )
 2 {
 3     Solid *solid = face->fsolid;
 4     Loop *loop;
 5     HalfEdge *he;
 6     Vertex *firstv;
 7     Vertex *upvertex;
 8     Vertex *prevupvertex;
 9     Vertex *nextv;
10     Point uppoint;
11     HalfEdge *uphe;
12     HalfEdge *firstuphe;
13
14     for (loop = face->floops; loop != NULL; loop = loop->nextl)
15     {
16         he = loop->ledge;
17         firstv = he->startv;
18         uppoint.SetCoord(firstv->point.coord[0] + d*vec[0],
19             firstv->point.coord[1] + d*vec[1],
20             firstv->point.coord[2] + d*vec[2]);
21         firstuphe = _HalfEdgeDS->mev(firstv, uppoint, loop);
22         prevupvertex = firstuphe->endv;
23         he = he->next;
24         nextv = he->startv;
25         while (nextv != firstv)
26         {
27             uppoint.SetCoord(nextv->point.coord[0] + d*vec[0],
28                 nextv->point.coord[1] + d*vec[1],
29                 nextv->point.coord[2] + d*vec[2]);
30             uphe = _HalfEdgeDS->mev(nextv, uppoint, loop);
31             upvertex = uphe->endv;
32             _HalfEdgeDS->mef(upvertex, prevupvertex, loop);
33             prevupvertex = upvertex;
34             he = he->next;
35             nextv = he->startv;
36         }
37         _HalfEdgeDS->mef(firstuphe->endv, prevupvertex, loop);
38     }
39 }

View Code

总结

  这里我认为比较复杂的操作就是mef,kemr的操作,其实只要理解了半边的结构的本质,自己画画拓扑结构图,多多注意Loop的走向,这些问题都是可以迎刃而解的。

  这里有一个求是鹰的效果图,其中的点是我用Catia在草图中画好,然后导出坐标来用,扫成实现了最后的效果图,总过有5个实体对象,求是鹰、1、8、9、7。

实体模型图:

线框模型图:

  总体来说,仅仅实现了半边结构和欧拉操作的基本功能,不存在特别难懂和实现很费力的地方,出现的小bug调试调试也可以比较轻松的解决,具体实现的过程也学习了不少别人的实现,看到也有写成交互式,通过描绘封闭二维直线区域,指定扫成方向和距离的版本,这些实现的效果都是很不错。但是,自己动手实践的过程能够发掘出很多问题,比如对于Glut的使用,欧拉操作以及模型实现过程中的调试等。中间的代码的细节讲的不是很细,源代码工程请戳这里,brp的格式文件就是solid模型文件。

  第一行记录模型vertex个数n,以及num操作个数m,然后n行都是顶点坐标,再接下来m行是相关操作。

转载于:https://www.cnblogs.com/tiny656/p/3537085.html

三维CAD——基于B_rep的建模操作相关推荐

  1. 三维CAD建模 基于Brep的扫成与欧拉操作

    基于B-rep的建模操作及其算法 欧拉操作 基于B-rep的建模操作及其算法 上了高老师的cad课,高老师的课十几年来不变的大作业就是基于半边结构的5个欧拉操作和sweep扫成cad模型的实现,以下是 ...

  2. CAD画图软件测试自学,三维CAD软件功能对比测试要点

    摘要:本文结合市面上多款三维CAD软件的作用及共性特点,着重从功能方面说明了对三维CAD软件对比时需要选择的测试要点, 关键词:三维CAD软件  测试要点 三维CAD软件被广泛应用在军工.机械制造.航 ...

  3. 三维CAD建模——基于半边数据结构的基本欧拉操作建模

    三维CAD建模--基于半边数据结构的基本欧拉操作建模(elar, B_REP) (欧拉操作  三维CAD建模课 三维CAD建模 高曙明老师  渲染框架 brep 带洞 带柄 B_REP brep el ...

  4. CrownCAD首席技术官:梅敬成博士亮相中国国际软件发展大会(基于云架构的国产自主三维CAD平台——CrownCAD )

    "2022中国国际软件发展大会暨第五届软件产业年会",给大家介绍一下华天软件研发的国内首款.完全自主.基于云架构的三维CAD平台 CrownCAD(也就是皇冠CAD). 什么是工业 ...

  5. cad模型轻量化_国内首款:新一代基于云架构的三维CAD产品CrownCAD正式公测!

    4月15号,华天软件控股子公司华云三维科技有限公司研发的国内首款.完全自主可控的新一代基于云架构的三维CAD产品CrownCAD正式上线公测. 公测地址:http://www.crowncad.com ...

  6. 人脸扫描建模_一种基于三维扫描数据的人脸建模方法

    一种基于三维扫描数据的人脸建模方法 黄炎辉 1 , 樊养余 1 , 董卫军 2 [摘 要] 三维扫描仪可以准确获取人脸的几何形状与纹理,但原始的人脸扫描 数据仅为一张连续曲面,不符合实际的人脸结构,无 ...

  7. 国产三维CAD华天软件STNOVATION 几何造型内核CRUX IV 解析

    国际主流的建模设计模式 1.SINOVATION产品发展史 SINOVATION软件作为一款从日本引进源代码技术基础上开发的工业设计软件,华天软件购买日本UEL公司CADmeister软件源代码! 三 ...

  8. 华天软件 SINOVATION 9.1 自主可控三维CAD内核CRUX IV 历史由来

    说起"CAD软件"这个专业词汇,很多人都感觉非常陌生,其实它跟我们的生活息息相关,不管是汽车制造还是航工航天,都要依靠工业软件进行设计. 官网:http://www.hoteams ...

  9. 梅敬成 三维CAD软件发展历程:过去,现在和未来 (ACIS,Parasolid,OCC, 中望OV,华天CRUX IV )

    梅敬成博士在工作 梅敬成 三维CAD软件发展历程:过去 现在和未来 梅敬成早年远赴法国留学,获得博士学位后,在世界顶级的达索系统.think3公司等CAD CAM(计算机辅助设计 制造)软件研发公司就 ...

最新文章

  1. LabVIEW图像增强算法(基础篇—5)
  2. nsdata是java什么类型_Swift中基本数据类型与NSData转换
  3. gst-rtsp-server编译测试
  4. 又遇到问题:wrong ELF class: ELFCLASS32 in Unknown on line
  5. C++的精髓——虚函数
  6. 【Todo】【读书笔记】Linux高性能服务器编程
  7. Day01-计算机入门
  8. 项目过程总结 和某个字段的更新
  9. 190413每日一句
  10. 迅雷极速版禁止自动升级的方法
  11. 几种数字仿真的物理意义与代码实现
  12. html个人主题制作,个人网页制作
  13. XX公司的薪酬设计案例分析
  14. 马尔可夫不等式和切比雪夫不等式
  15. chrome下载速度慢,提高下载速度
  16. 怎么能防止网站被注入eval(base64_decode这种类型的木马?
  17. 随机梯度下降法,批量梯度下降法和小批量梯度下降法以及代码实现
  18. php地区代码吗,将国家/地区名称转换为国家/地区代码缩写php
  19. matlab | 程序运行时间
  20. 10个深度学习的工具

热门文章

  1. 参与腾讯云数据迁移与视频转码,就有机会赢1000元京东卡!
  2. 吐槽下银联1分钱乘公交
  3. 我以为自己MySQL够牛逼了,直到看到了Alibaba的面试题
  4. coreldraw梯形校正_CorelDRAW如何绘制等腰梯形
  5. 关于fi dd ler 手机抓包 网卡地址地址_[问题]Android 7.0+使用VirtualXposed+Charles进行抓包
  6. excel流程图分叉 合并_Excel流程图绘制技巧,对齐组合轻松便利,在奇怪的流程一样搞定...
  7. 关于fi dd ler 手机抓包 网卡地址地址_关闭手机位置权限,安卓App仍能获取位置...
  8. lucene4.10.3入门
  9. 瞧瞧咱的电脑一天浪费多少电
  10. vue 2 滚动条加载更多数据实现