在three.js学习之盒子中,我们已经能够做出立方体并且根据需要进行变换了,点此可以查看demo。
有了上一节的基础,我们就可以适当加快学习进度。这一节我们一起学习一些常见的几何体图形。
首先还是将three.js学习之盒子中的代码复制过来,新将html文件learnAboutCommonGeometry.html
,然后删除掉有关立方体的代码,保留下来的代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50function main () {
const canvas = document.querySelector('#three')
const renderer = new THREE.WebGLRenderer({canvas})
const fov = 75;
const aspect = 2;
const near = 0.1;
const far = 200;
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far)
const group = new THREE.Group()
group.position.z = -10
const scene = new THREE.Scene()
{
const lightColor = 0xffffff; // 灯光颜色
const intensity = 1; // 灯光强度
const light = new THREE.DirectionalLight(lightColor, intensity);
light.position.set(-1, 2, 4);
scene.add(light);
}
scene.add(group)
function resizeRenderSizeToDisplaySize () {
const pixelRatio = window.devicePixelRatio;
const displayWidth = canvas.clientWidth * pixelRatio
const displayHeight = canvas.clientHeight * pixelRatio
const renderWidth = canvas.width;
const renderHeight = canvas.height;
const needResize = displayWidth !== renderWidth || displayHeight !== renderHeight
return needResize
}
function render (time) {
if (resizeRenderSizeToDisplaySize()) {
const pixelRatio = window.devicePixelRatio;
const width = canvas.clientWidth * pixelRatio
const height = canvas.clientHeight * pixelRatio
renderer.setSize(width, height, false)
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
}
time *= 0.001
group.position.y = time
group.position.x = time
renderer.render(scene, camera)
requestAnimationFrame(render)
}
requestAnimationFrame(render)
}
细心的朋友应该发现我对自适应代买resizeRenderSizeToDisplaySize
做了调整,各位根据自己的喜好,这一部分可调整可不调整。关于three.js中的自适应问题,可以查看threejs响应式设计开发。
平面圆形(CircleGeometry)
CircleGeometry
可以接收四个参数,分别是:
- radius 圆的半径
- segments 分段数(组成圆的三角形的数量),最小值为3,默认为8
- thetaStart 第一个分段的起始角,默认为0。起始角位于三点钟方向处。
- thetaLength,圆心角的大小,默认是2Pi。正好组成一个圆,如果参数不是2PI的时候,方向为逆时针。
可以看出来,在构造圆形时,我们可以不传入任何参数,就能构造出一个圆形来,因为我们以学几何体为主,所以我们所有的材料(Material)和线条,直接开始构造设计图
1 | const circle1Geometry = new THREE.CircleGeometry() |
是不是感觉一切正常。接下来我们分别传入半径和分段数看看情况
1 | const circle1Geometry = new THREE.CircleGeometry(1, 3) |
可以看到,分段数为3的时候,我们做出了一个平面三角形。可以自己去尝试为4,5,6,7,8的情形。是不是发现,分段数是几就是几边形。只不过边数多的时候就显得圆了,边数越多圆越圆。为了保证圆看起来圆点,three.js
默认值设为了8,但是架不住咱们有特殊需求,因此还是可以自定义。当然特殊也有下限,如果你将分段数设置为1或者2,将会强行当成3处理。
thetaStart
和thetaLength
这两个参数,是为了帮助我们造出不完整的圆形来,当然,如果你脑洞足够大,应该还能造出更多的来。
我们将上面的代码加入弧度数来看看1
2
3
4const circle1Geometry = new THREE.CircleGeometry(1, 3, 0, 1 * Math.PI)
const circleMaterial = new THREE.MeshPhongMaterial({ color: 0x00F5FF })
const circle1 = new THREE.Mesh(circle1Geometry, circleMaterial)
group.add(circle1)
如果你实际操作了,会发现,在边数比较小的情况下,设置不同的开始角度和结束角度,你能看到很多不同的图形来,这些图形,你在圆的基础上去想,就能明白。
three.js中的平面圆形学习就到这里。我们接下来学习圆锥(ConeGeometry)
圆锥(coneGeometry)
结合已经学习过的平面圆形的构造方法,我们可以猜测一下,圆锥底部圆的半径长度,圆锥的高度,圆锥底部分段数,圆锥侧面分段数在构造时是可以根据自己的需要去传的。
实际上也确实是这样,接下来我们一起看看立体圆锥需要传的基本参数:
- radius 圆锥底部圆的半径,默认为1
- height 圆锥的高度,默认值为1
- radialSegments 圆锥底部圆的分段数,像切蛋糕一样分割圆锥,会影像到底面,所以我觉得叫做底部分段数也没问题,就是把底部针对着你,然后去一刀刀的切
- heightSegments 圆锥侧面沿着高度的分界线,像切萝卜一样,一片片的。是把圆锥身体横对着你,然后一刀刀的切。
前面这几个是咱们能够猜测到的,实际上,还应该猜到两个参数,即底部圆的开始角度和结束角度 - openEnded 布尔值,默认是关闭的,可以手动打开
- thetaStart 底部圆的开始角度,和平面圆形相同,虽然说是底部圆的角度,但是会影像到整体
- thetaLength 圆心角大小,和平面圆相同,默认都是2*PI。
除了这两个我们应该想到的,实际上还有一个我们多想想可能会想到的参数,那就是底部要不要搞成开口状的
圆锥(coneGeometry)基本案例
基础案例只写和圆锥(coneGeometry)相关的,完整代码会附在文末,也可以点击链接右键查看源代码
- 默认参数展示
在默认展示中,我们全部使用默认值,如下:1
2
3const coneMaterial = new THREE.MeshPhongMaterial({color: 0x0000FF})
const coneGeometry = new THREE.ConeGeometry()
const cone = new THREE.Mesh(coneGeometry1, coneMaterial1)
- 圆锥(coneGeometry)radius和height设置
默认情况下这看着有点胖,我们接下来给圆锥瘦瘦身
1 | const coneMaterial = new THREE.MeshPhongMaterial({color: 0x0000FF}) |
- 圆锥(coneGeometry)同时设置
radialSegments
对于radialSegments
的理解,最好还是自己亲自放上去看一下,为了看的真切,咱们这次换一个颜色,自己的代码上可以根据需要调试看看看不清点我1
2
3const coneMaterial = new THREE.MeshPhongMaterial({color: 0xFF1493})
const coneGeometry = new THREE.ConeGeometry(1,3, 10)
const cone = new THREE.Mesh(coneGeometry, coneMaterial)
heightSegments
,thetaStart
,thetaLength
可以自己动手看看,就是加字段的问题。最后一起看看openEnded
- 圆锥(coneGeometry)同时设置
openEnded
1 | const coneMaterial = new THREE.MeshPhongMaterial({color: 0xFF1493}) |
可以看到,当
openEnded
设置为true时,圆锥内部为空,像个甜甜筒。最后需要强调一下的是,参数的传入顺序如下,别传错了,不然会出现莫名其妙的问题:
radius
,height
, radialSegments
, heightSegments
,openEnded
,thetaStart
, thetaLength
本来想这一篇将所有常见图形讲完,感觉篇幅还是稍微长了点。所以我还是分开写吧。
下面是本篇完整的源代码和示例
1 | <!DOCTYPE html> |