文章目录

  • 8、几何体对象、曲线、三维模型
    • 8.1 常见几何体和曲线API介绍
      • 几何体
      • 曲线
    • 8.2 直线、椭圆、圆弧、基类Curve
      • 圆弧线ArcCurve
      • 曲线Curve方法.getPoints()
      • 几何体方法.setFromPoints()
      • 绘制圆弧线案例
      • 绘制直线效果
    • 8.3 样条曲线、贝塞尔曲线
      • 一条光滑样条曲线案例
      • 贝塞尔曲线
    • 8.4 多个线条组合曲线CurvePath
      • U型案例
    • 8.5 曲线路径管道成型TubeGeometry
      • 样条曲面生成圆管案例
      • CurvePath多段路径生成管道案例
    • 8.6 旋转造型LatheGeometry
      • 样条曲线插值计算
    • 8.7 Shape对象和轮廓填充ShapeGeometry
      • 填充顶点构成的轮廓
      • shape外轮廓和内轮廓
    • 8.8 拉伸扫描成型ExtrudeGeometry

8、几何体对象、曲线、三维模型

8.1 常见几何体和曲线API介绍

几何体

所有几何体的基类分为Geometry和BufferGeometry两大类,两类几何体直接可以相互转化。

曲线

曲线和几何体同样本质上都是用来生成顶点的算法,曲线主要是按照一定的规则生成一系列沿着某条轨迹线分布的顶点。当你把曲线、几何体看成顶点的时候,查考文档很多属性和方法自然很同意理解。

8.2 直线、椭圆、圆弧、基类Curve

圆弧线ArcCurve

ArcCurve( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise )
参数 含义
aX, aY 圆弧圆心坐标
aRadius 圆弧半径
aStartAngle, aEndAngle 起始角度
aClockwise 是否顺时针绘制,默认值为false
//参数:0, 0圆弧坐标原点x,y  100:圆弧半径    0, 2 * Math.PI:圆弧起始角度
var arc = new THREE.ArcCurve(0, 0, 100, 0, 2 * Math.PI);

曲线Curve方法.getPoints()

var arc = new THREE.ArcCurve(0, 0, 100, 0, 2 * Math.PI);
//getPoints是基类Curve的方法,返回一个vector2对象作为元素组成的数组
var points = arc.getPoints(50);//分段数50,返回51个顶点

几何体方法.setFromPoints()

// setFromPoints方法从points中提取数据改变几何体的顶点属性vertices
geometry.setFromPoints(points);
console.log(geometry.vertices);
// 如果几何体是BufferGeometry,setFromPoints方法改变的是.attributes.position属性
// console.log(geometry.attributes.position);

绘制圆弧线案例

使用threejs的API圆弧线ArcCurve绘制一个圆弧轮廓。

var geometry = new THREE.Geometry(); //声明一个几何体对象Geometry
//参数:0, 0圆弧坐标原点x,y  100:圆弧半径    0, 2 * Math.PI:圆弧起始角度
var arc = new THREE.ArcCurve(0, 0, 100, 0, 2 * Math.PI);
//getPoints是基类Curve的方法,返回一个vector2对象作为元素组成的数组
var points = arc.getPoints(50);//分段数50,返回51个顶点
// setFromPoints方法从points中提取数据改变几何体的顶点属性vertices
geometry.setFromPoints(points);
//材质对象
var material = new THREE.LineBasicMaterial({color: 0x000000
});
//线条模型对象
var line = new THREE.Line(geometry, material);
scene.add(line); //线条对象添加到场景中

和上面绘制圆弧线代码实现的功能相同,不过没有借助圆弧线THREE.ArcCurve,通过三角函数计算生成圆弧线上的顶点。设置这个案例的目的就是,你可以通过对比两个代码案例,明白Threejs一些曲线API本质上就是通过某种算法得到了沿着特定轨迹的顶点数据。

var geometry = new THREE.Geometry(); //声明一个几何体对象Geometry
var R = 100; //圆弧半径
var N = 50; //分段数量
// 批量生成圆弧上的顶点数据
for (var i = 0; i < N; i++) {var angle = 2 * Math.PI / N * i;var x = R * Math.sin(angle);var y = R * Math.cos(angle);geometry.vertices.push(new THREE.Vector3(x, y, 0));
}
// 插入最后一个点,line渲染模式下,产生闭合效果
// geometry.vertices.push(geometry.vertices[0])
//材质对象
var material = new THREE.LineBasicMaterial({color: 0x000000
});
//线条模型对象
var line = new THREE.Line(geometry, material);
scene.add(line); //线条对象添加到场景中

绘制直线效果

直接给几何体Geometry设置两个顶点数据。

var geometry = new THREE.Geometry(); //声明一个几何体对象Geometry
var p1 = new THREE.Vector3(50, 0, 0); //顶点1坐标
var p2 = new THREE.Vector3(0, 70, 0); //顶点2坐标
//顶点坐标添加到geometry对象
geometry.vertices.push(p1, p2);
var material = new THREE.LineBasicMaterial({color: 0xffff00,
});//材质对象
//线条模型对象
var line = new THREE.Line(geometry, material);
scene.add(line); //线条对象添加到场景中

通过LineCurve3绘制一条三维直线。

var geometry = new THREE.Geometry(); //声明一个几何体对象Geometry
var p1 = new THREE.Vector3(50, 0, 0); //顶点1坐标
var p2 = new THREE.Vector3(0, 70, 0); //顶点2坐标
// 三维直线LineCurve3
var LineCurve = new THREE.LineCurve3(p1, p2);
// 二维直线LineCurve
var LineCurve = new THREE.LineCurve(new THREE.Vector2(50, 0), new THREE.Vector2(0, 70));
var pointArr = LineCurve.getPoints(10);
geometry.setFromPoints(pointArr);

通过LineCurve绘制一条二维直线。

var geometry = new THREE.Geometry(); //声明一个几何体对象Geometry
var p1 = new THREE.Vector2(50, 0); //顶点1坐标
var p2 = new THREE.Vector2(0, 70); //顶点2坐标
// 二维直线LineCurve
var LineCurve = new THREE.LineCurve(p1, p2);
var pointArr = LineCurve.getPoints(10);
geometry.setFromPoints(pointArr);

8.3 样条曲线、贝塞尔曲线

一条光滑样条曲线案例

var geometry = new THREE.Geometry(); //声明一个几何体对象Geometry
// 三维样条曲线  Catmull-Rom算法
var curve = new THREE.CatmullRomCurve3([new THREE.Vector3(-50, 20, 90),new THREE.Vector3(-10, 40, 40),new THREE.Vector3(0, 0, 0),new THREE.Vector3(60, -60, 0),new THREE.Vector3(70, 0, 80)
]);
//getPoints是基类Curve的方法,返回一个vector3对象作为元素组成的数组
var points = curve.getPoints(100); //分段数100,返回101个顶点
// setFromPoints方法从points中提取数据改变几何体的顶点属性vertices
geometry.setFromPoints(points);
//材质对象
var material = new THREE.LineBasicMaterial({color: 0x000000
});
//线条模型对象
var line = new THREE.Line(geometry, material);
scene.add(line); //线条对象添加到场景中

贝塞尔曲线

var p1 = new THREE.Vector3(-80, 0, 0);
var p2 = new THREE.Vector3(20, 100, 0);
var p3 = new THREE.Vector3(80, 0, 0);
// 三维二次贝赛尔曲线
var curve = new THREE.QuadraticBezierCurve3(p1, p2, p3);

var p1 = new THREE.Vector3(-80, 0, 0);
var p2 = new THREE.Vector3(-40, 100, 0);
var p3 = new THREE.Vector3(40, 100, 0);
var p4 = new THREE.Vector3(80, 0, 0);
// 三维三次贝赛尔曲线
var curve = new THREE.CubicBezierCurve3(p1, p2, p3, p4);

8.4 多个线条组合曲线CurvePath

U型案例

var geometry = new THREE.Geometry(); //声明一个几何体对象Geometry
// 绘制一个U型轮廓
var R = 80;//圆弧半径
var arc = new THREE.ArcCurve(0, 0, R, 0, Math.PI, true);
// 半圆弧的一个端点作为直线的一个端点
var line1 = new THREE.LineCurve(new THREE.Vector2(R, 200, 0), new THREE.Vector2(R, 0, 0));
var line2 = new THREE.LineCurve(new THREE.Vector2(-R, 0, 0), new THREE.Vector2(-R, 200, 0));
// 创建组合曲线对象CurvePath
var CurvePath = new THREE.CurvePath();
// 把多个线条插入到CurvePath中
CurvePath.curves.push(line1, arc, line2);
//分段数200
var points = CurvePath.getPoints(200);
// setFromPoints方法从points中提取数据改变几何体的顶点属性vertices
geometry.setFromPoints(points);
//材质对象
var material = new THREE.LineBasicMaterial({color: 0x000000
});
//线条模型对象
var line = new THREE.Line(geometry, material);
scene.add(line); //线条对象添加到场景中

8.5 曲线路径管道成型TubeGeometry

TubeGeometry的功能就是通过一条曲线生成一个圆管。它的本质就是以曲线上顶点为基准,生成一系列曲线等径分布的顶点数据, 具体算法如何实现的可以查看three.js引擎源码。

构造函数格式:TubeGeometry(path, tubularSegments, radius, radiusSegments, closed)
参数
path 扫描路径,基本类是Curve的路径构造函数
tubularSegments 路径方向细分数,默认64
radius 管道半径,默认1
radiusSegments 管道圆弧细分数,默认值8
closed Boolean 管道是否闭合

样条曲面生成圆管案例

//创建管道成型的路径(3D样条曲线)
var path = new THREE.CatmullRomCurve3([new THREE.Vector3(-10, -50, -50),new THREE.Vector3(10, 0, 0),new THREE.Vector3(8, 50, 50),new THREE.Vector3(-5, 0, 100)
]);
// path:路径   40:沿着轨迹细分数  2:管道半径   25:管道截面圆细分数
var geometry = new THREE.TubeGeometry(path, 40, 2, 25);

你也可以使用下面直线替换上面的样条曲线查看圆管生成效果。

// LineCurve3创建直线段路径
var path = new THREE.LineCurve3(new THREE.Vector3(0, 100, 0), new THREE.Vector3(0, 0, 0));

CurvePath多段路径生成管道案例

通过下面代码创建了一段样条曲线和两条直线拼接成的路径,然后通过曲线路径CurvePath把样条曲线和料条曲线合并成为一条路径。

// 创建多段线条的顶点数据
var p1 = new THREE.Vector3(-85.35, -35.36)
var p2 = new THREE.Vector3(-50, 0, 0);
var p3 = new THREE.Vector3(0, 50, 0);
var p4 = new THREE.Vector3(50, 0, 0);
var p5 = new THREE.Vector3(85.35, -35.36);
// 创建线条一:直线
let line1 = new THREE.LineCurve3(p1,p2);
// 重建线条2:三维样条曲线
var curve = new THREE.CatmullRomCurve3([p2, p3, p4]);
// 创建线条3:直线
let line2 = new THREE.LineCurve3(p4,p5);
var CurvePath = new THREE.CurvePath();// 创建CurvePath对象
CurvePath.curves.push(line1, curve, line2);// 插入多段线条
//通过多段曲线路径创建生成管道
//通过多段曲线路径创建生成管道,CCurvePath:管道路径
var geometry2 = new THREE.TubeGeometry(CurvePath, 100, 5, 25, false);

8.6 旋转造型LatheGeometry


生活中有很多的几何体具备旋转特征,比如球体,常见杯子, three.js提供了一个构造函数LatheGeometry(), LatheGeometry可以利用已有的二维数据生成三维顶点数据,二维数据可以通过二维向量对象Vector2定义,也可以通过3D曲线或2D线条轮廓生成。 LatheGeometry的二维坐标数据默认绕y轴旋转。

格式:LatheGeometry(points, segments, phiStart, phiLength)
参数
points Vector2表示的坐标数据组成的数组
segments 圆周方向细分数,默认12
phiStart 开始角度,默认0
phiLength 旋转角度,默认2π
*** 创建旋转网格模型*/
var points = [new THREE.Vector2(50,60),new THREE.Vector2(25,0),new THREE.Vector2(50,-60)
];
var geometry = new THREE.LatheGeometry(points,30);
var material=new THREE.MeshPhongMaterial({color:0x0000ff,//三角面颜色side:THREE.DoubleSide//两面可见
});//材质对象
material.wireframe = true;//线条模式渲染(查看细分数)
var mesh=new THREE.Mesh(geometry,material);//旋转网格模型对象
scene.add(mesh);//旋转网格模型添加到场景中

样条曲线插值计算

借助Shape对象的方法.splineThru(),把上面的三个顶点进行样条插值计算, 可以得到一个光滑的旋转曲面。

var shape = new THREE.Shape();//创建Shape对象
var points = [//定位定点new THREE.Vector2(50,60),new THREE.Vector2(25,0),new THREE.Vector2(50,-60)
];
shape.splineThru(points);//顶点带入样条插值计算函数
var splinePoints = shape.getPoints(20);//插值计算细分数20
var geometry = new THREE.LatheGeometry(splinePoints,30);//旋转造型

shape.getPoints(20)的作用是利用已有的顶点插值计算出新的顶点,两个顶点之间插值计算出20个顶点,如果细分数是1不是20,相当于不进行插值计算, 插值计算的规则通过Shape对象的方法.splineThru()定义,几何曲线的角度描述,splineThru的作用就是创建一个样条曲线,除了样条曲线还可以使用贝赛尔等曲线进行插值计算。

8.7 Shape对象和轮廓填充ShapeGeometry

填充顶点构成的轮廓

通过下面代码定义了6个顶点坐标,也可以说是5个,最后一个和第一个是重合的,构成一个五边形区域。然后使用这一组二维顶点坐标作为Shape的参数构成一个五边形轮廓。把五边形轮廓Shape作为ShapeGeometry的参数,可以根据轮廓坐标计算出一系列三角形面填充轮廓,形成一个平面几何体。

var points = [new THREE.Vector2(-50, -50),new THREE.Vector2(-60, 0),new THREE.Vector2(0, 50),new THREE.Vector2(60, 0),new THREE.Vector2(50, -50),new THREE.Vector2(-50, -50),
]
// 通过顶点定义轮廓
var shape = new THREE.Shape(points);
// shape可以理解为一个需要填充轮廓
// 所谓填充:ShapeGeometry算法利用顶点计算出三角面face3数据填充轮廓
var geometry = new THREE.ShapeGeometry(shape, 25);

调用Shape圆弧方法.absarc()绘制一个圆形轮廓,然后通过ShapeGeometry可以把该圆形轮廓填充为一个圆形平面几何体。

你可以尝试更改ShapeGeometry的参数2,参数2表示细分数,然后网格材质设置为wireframe: true查看圆形区域填充三角形的数量变化。

// 通过shpae基类path的方法绘制轮廓(本质也是生成顶点)
var shape = new THREE.Shape();
shape.absarc(0,0,100,0,2*Math.PI);//圆弧轮廓
console.log(shape.getPoints(15));//查看shape顶点数据
var geometry = new THREE.ShapeGeometry(shape, 25);

下面代码是通过shpae绘制了一个矩形区域,更多相关的轮廓绘制方法可以查看Shape文档。

shape外轮廓和内轮廓

shape可以用来绘制外轮廓,也可以用来绘制内轮廓,ShapeGeometry会使用三角形自动填充shape内轮廓和外轮廓中间的中部。

下面给出了几个通过shape绘制的轮廓图案。

// 圆弧与直线连接
var shape = new THREE.Shape(); //Shape对象
var R = 50;
// 绘制一个半径为R、圆心坐标(0, 0)的半圆弧
shape.absarc(0, 0, R, 0, Math.PI);
//从圆弧的一个端点(-R, 0)到(-R, -200)绘制一条直线
shape.lineTo(-R, -200);
// 绘制一个半径为R、圆心坐标(0, -200)的半圆弧
shape.absarc(0, -200, R, Math.PI, 2 * Math.PI);
//从圆弧的一个端点(R, -200)到(-R, -200)绘制一条直线
shape.lineTo(R, 0);
var geometry = new THREE.ShapeGeometry(shape, 30);

// 一个外轮廓圆弧嵌套三个内圆弧轮廓
var shape = new THREE.Shape(); //Shape对象
//外轮廓
shape.arc(0, 0, 100, 0, 2 * Math.PI);
// 内轮廓1
var path1 = new THREE.Path();
path1.arc(0, 0, 40, 0, 2 * Math.PI);
// 内轮廓2
var path2 = new THREE.Path();
path2.arc(80, 0, 10, 0, 2 * Math.PI);
// 内轮廓3
var path3 = new THREE.Path();
path3.arc(-80, 0, 10, 0, 2 * Math.PI);
//三个内轮廓分别插入到holes属性中
shape.holes.push(path1, path2, path3);

// 矩形嵌套矩形或圆弧
var shape=new THREE.Shape();//Shape对象
//外轮廓
shape.moveTo(0,0);//起点
shape.lineTo(0,100);//第2点
shape.lineTo(100,100);//第3点
shape.lineTo(100,0);//第4点
shape.lineTo(0,0);//第5点//内轮廓
var path=new THREE.Path();//path对象
// path.arc(50,50,40,0,2*Math.PI);//圆弧
path.moveTo(20,20);//起点
path.lineTo(20,80);//第2点
path.lineTo(80,80);//第3点
path.lineTo(80,20);//第4点
path.lineTo(20,20);//第5点
shape.holes.push(path);//设置内轮廓

// 轮廓对象1var shape=new THREE.Shape();shape.arc(-50,0,30,0,2*Math.PI);// 轮廓对象2var shape2=new THREE.Shape();shape2.arc(50,0,30,0,2*Math.PI);// 轮廓对象3var shape3=new THREE.Shape();shape3.arc(0,50,30,0,2*Math.PI);
// 多个shape作为元素组成数组,每一个shpae可以理解为一个要填充的轮廓
var geometry = new THREE.ShapeGeometry([shape,shape2,shape3], 30);

// 河南边界轮廓坐标
let arr = [[110.3906, 34.585],[110.8301, 34.6289],
...
...
...[110.6543, 34.1455],[110.4785, 34.2334],[110.3906, 34.585]
]
var points = [];
// 转化为Vector2构成的顶点数组
arr.forEach(elem => {points.push(new THREE.Vector2(elem[0],elem[1]))
});
// 样条曲线生成更多的点
var SplineCurve = new THREE.SplineCurve(points)
var shape = new THREE.Shape(SplineCurve.getPoints(300));
// var shape = new THREE.Shape(points);
var geometry = new THREE.ShapeGeometry(shape);
geometry.center();//几何体居中
geometry.scale(30,30,30);//几何体缩放
var material = new THREE.MeshPhongMaterial({color: 0x0000ff,side: THREE.DoubleSide //两面可见
}); //材质对象
var mesh = new THREE.Mesh(geometry, material); //网格模型对象

8.8 拉伸扫描成型ExtrudeGeometry


构造函数ExtrudeGeometry()和ShapeGeometry一样是利用Shape对象生成几何体对象,区别在于ExtrudeGeometry()可以利用2D轮廓生成3D模型, 如果你使用任何三维软件都知道可以先绘制一个二维的轮廓图,然后拉伸成型得到三维模型。ExtrudeGeometry()第二个参数是拉伸参数,数据类型是对象, 属性amount表示拉伸长度,bevelEnabled表示拉伸是否产生倒角,其它参数见下表。

构造函数ExtrudeGeometry()拉伸参数

参数 含义
amount 拉伸长度,默认100
bevelEnabled 是否使用倒角
bevelSegments 倒角细分数,默认3
bevelThickness 倒角尺寸(经向)
curveSegments 拉伸轮廓细分数
steps 拉伸方向细分数
extrudePath 扫描路径THREE.CurvePath,默认Z轴方向
material 前后面材质索引号
extrudeMaterial 拉伸面、倒角面材质索引号
bevelSize 倒角尺寸(拉伸方向)
/*** 创建拉伸网格模型*/
var shape = new THREE.Shape();
/**四条直线绘制一个矩形轮廓*/
shape.moveTo(0,0);//起点
shape.lineTo(0,100);//第2点
shape.lineTo(100,100);//第3点
shape.lineTo(100,0);//第4点
shape.lineTo(0,0);//第5点
var geometry = new THREE.ExtrudeGeometry(//拉伸造型shape,//二维轮廓//拉伸参数{amount:120,//拉伸长度bevelEnabled:false//无倒角});

通过使用点模式渲染上面的几何体,可以看出几何体拉伸的本质效果就是空间分布顶点数据的产生。

var material=new THREE.PointsMaterial({color:0x0000ff,size:5.0//点对象像素尺寸
});//材质对象
var mesh=new THREE.Points(geometry,material);//点模型对象
scene.add(mesh);//点模型添加到场景中


拉伸和扫描一样都是三维造型建模方法,three.js提供了一个共同的构造函数来实现扫描和拉伸,对于扫描而言不需要定义amount属性设置拉伸距离,设置扫描路径即可, 定义属性extrudePath,extrudePath的值是路径THREE.CurvePath,可以通过样条曲线、贝赛尔曲线构造函数创建不规则曲线扫描轨迹。

/**
* 创建扫描网格模型
*/
var shape = new THREE.Shape();
/**四条直线绘制一个矩形轮廓*/
shape.moveTo(0,0);//起点
shape.lineTo(0,10);//第2点
shape.lineTo(10,10);//第3点
shape.lineTo(10,0);//第4点
shape.lineTo(0,0);//第5点
/**创建轮廓的扫描轨迹(3D样条曲线)*/
var curve = new THREE.SplineCurve3([new THREE.Vector3( -10, -50, -50 ),new THREE.Vector3( 10, 0, 0 ),new THREE.Vector3( 8, 50, 50 ),new THREE.Vector3( -5, 0, 100)
]);
var geometry = new THREE.ExtrudeGeometry(//拉伸造型shape,//二维轮廓//拉伸参数{bevelEnabled:false,//无倒角extrudePath:curve,//选择扫描轨迹steps:50//扫描方向细分数}
);

Three.js(八)—— 几何体对象、曲线、三维模型相关推荐

  1. threejs 形状几何体_Three.js模型几何体面积、体积计算

    Three.js模型几何体面积.体积计算 在工作中通过Three.js开发项目的时候,一些特定的情况下你可能需要计算一个三维模型的表面积或者体积,比如在3D打印的Web项目中,你需要计算一个三维模型的 ...

  2. three.js使用OrbitControls.js控制几何体旋转、平移、缩放

    附带一个可用的OrbitControls.js http://www.yanhuangxueyuan.com/threejs/examples/js/controls/OrbitControls.js ...

  3. 102 Three.js 使用几何体生成拱门形状

    Three.js的几何体已经能够创建很多的几何体模型,但是,远远还达不到特殊需求的几何体模型.今天,我就记一下如何制作特殊几何模型的感想. 这是我制作的一个简单的拱门形状的几何体.这个创建可以使用BS ...

  4. 初识javaScript(八)对象(一)

    初识javaScript(八)对象(一) 1 对象的相关概念 2 js中的对象的基本定义形式 3 对象的键和值的说明 4 访问对象的值 5 创建对象的方式 6 对象赋值传引用 7 对对象的键值对的操作 ...

  5. Java、JS解析JSON对象、JSON数组

    一:三种JSON格式 基本类型 {"student": "张三","age": 18,"sex": true } 数组类 ...

  6. three.js自定义几何体

    three.js提供了很多创建几何体对象的方法,如BoxGeometry,SphereGeometry等,当然也可以自己创建几何体如下面这段代码 var gemo=new THREE.Geometry ...

  7. JS获取当前对象大小以及屏幕分辨率等...

    <!DOCTYPE html> <html> <head><meta charset="utf-8"/><meta name= ...

  8. JS的事件对象和事件冒泡

    2019独角兽企业重金招聘Python工程师标准>>> 1.事件对象 js的事件对象中保存了当前被触发事件的一些相关的属性信息,如事件源.事件发生时的鼠标位置.事件按键等. 事件对象 ...

  9. JS中集合对象(Array、Map、Set)及类数组对象的使用与对比

    JS中集合对象(Array.Map.Set)及类数组对象的使用与对比 在使用js编程的时候,常常会用到集合对象,集合对象其实是一种泛型,在js中没有明确的规定其内元素的类型,但在强类型语言譬如Java ...

最新文章

  1. iOS 总结遇到的各种坑儿
  2. oracle取两个小时内的数据,【求解】一个时间条件,查两个不同时间段数据怎么查...
  3. UTL_FILE包用法小记
  4. Winform中使用FastReport的PictureObject时通过代码设置图片源并使Image图片旋转90度
  5. 用户(三次)登录--作业小编完成
  6. 过滤器链模式PK匿名方法实现,哪个更优雅?
  7. win10子系统编译android,基于win10子系统ijkplayer全量编译(支持所有格式)流程
  8. 满屋花网页代码_成为更好的程序猿!2020年给网页开发人员的32条建议
  9. Juniper设备管理
  10. 一个完整的物联网项目管理流程
  11. 无法启动此程序因为计算机丢失uplay,Uplay登录不上咋办?Uplay登录不上的解决方法...
  12. MATLAB多算法进行图像去雾处理
  13. KEIL5 各个版本编译器的下载
  14. 量化金融-分类数据的检验
  15. Vue3中使用Vform3(自定义表单工具)
  16. slam十四讲-ch6-非线性优化(包含手写高斯牛顿、使用g2o库、使用ceres库三种方法的源码详细注释)
  17. Error: Rule can only have one resource source (provided resource and test + include + exclude) in {.
  18. Datawhale 图神经网络task4
  19. 电脑快捷键大全(2)
  20. Adobe Photoshop 2020 21.2.2.289 中文版 — 图像处理工具

热门文章

  1. java使用线程安全的单例模式实现网站计数器
  2. 网站如何启用https
  3. ⚔疯狂输出⚔ Java中的继承。
  4. 如何让手机的增强型4GLTE开关默认处于关闭状态?
  5. 带你实现开发者头条(二) 实现左滑菜单
  6. 项目管理心得分享九点总结
  7. 思科 路由与交换基础 实验一
  8. Watching for file changes with StatReloader
  9. 一个全基因组重测序分析实战
  10. 词法分析器java语言_词法分析器java版(java词法分析器)