three.js学习之类球多面体

在将three.js学习之常见几何体圆柱和球一章中我们学习了球SphereGeometry,创建时需要传如的第一个参数就是radius球面半径,今天咱们学的这些多面体,在这一点上和SphereGeometry球很相似,因此我想将它们归类成类球多面体。还是秉承咱们一贯的习惯,复制three.js学习之平面图形圆环和平面的html代码,并删除有关平面圆形和平面的代码,保留公用部分。

完成了以上工作,我们就可以开始学习今天的内容了。

TetrahedronGeometry (四面体)学习

顾名思义,四面体就是只有四个面嘛。而四面体的构造也是相比其它的要简单。只需要传入两个参数就行,如下:

  • radius 四面体的半径
  • detail 这个参数用来决定四面体的顶点数,默认为0。也就是我们用到的四面体,当把它设置为大于0的数时,原先的四面体就会增加一个顶点,将不再是四面体。点数足够多时,四面体就会变成一个球。
  • TetrahedronGeometry (四面体)基本使用演示

    1
    2
    3
    4
    5
    const radius = 1
    const detail = 0
    const tetrahedronGeometry = new THREE.TetrahedronGeometry(radius, detail)
    const material = new THREE.MeshPhongMaterial({ color: 0x00F5FF })
    const tetrahedron = new THREE.Mesh(tetrahedronGeometry, material)
  • TetrahedronGeometry (四面体)改变参数detail

    1
    2
    3
    4
    5
    const radius = 1
    const detail = 1
    const tetrahedronGeometry = new THREE.TetrahedronGeometry(radius, detail)
    const material = new THREE.MeshPhongMaterial({ color: 0x00F5FF })
    const tetrahedron = new THREE.Mesh(tetrahedronGeometry, material)

下面是我做出来的demo示例,左边是默认的四面体,右面是detail为1的多面体,各位如果看到这里的话可以自己尝试一下修改一下detail,看看修改后的不同表现。

OctahedronGeometry (八面体)学习

如果认真看了四面体的代码,八面体这就很简单了,只需要将只需要改一个单词,八面体的代码立即生效。先看参数

  • radius 八面体的半径
  • detail 这个参数用来决定八面体的顶点数,默认为0。也就是我们用到的八面体,当把它设置为大于0的数时,原先的八面体就会增加一个顶点,将不再是八面体。点数足够多时,四面体就会变成一个球。
  • OctahedronGeometry (八面体)基本使用演示

    1
    2
    3
    4
    5
    const radius = 1
    const detail = 0
    const octahedronGeometry = new THREE.OctahedronGeometry(radius, detail)
    const material = new THREE.MeshPhongMaterial({ color: 0x00F5FF })
    const octahedron = new THREE.Mesh(octahedronGeometry, material)
  • OctahedronGeometry (八面体)改变参数detail

    1
    2
    3
    4
    5
    const radius = 1
    const detail = 1
    const octahedronGeometry = new THREE.OctahedronGeometry(radius, detail)
    const material = new THREE.MeshPhongMaterial({ color: 0x00F5FF })
    const octahedron = new THREE.Mesh(octahedronGeometry, material)

下面是我做出来的TetrahedronGeometry (八面体)demo示例,左边是默认的八面体,右面是detail为1的多面体,各位如果看到这里的话可以自己尝试一下修改一下detail,看看修改后的不同表现。

DodecahedronGeometry (十二面体)学习

看参数

  • radius 十二面体的半径
  • detail 这个参数用来决定十二面体的顶点数,默认为0。也就是我们用到的十二面体,当把它设置为大于0的数时,原先的八面体就会增加一个顶点,将不再是十二面体。点数足够多时,四面体就会变成一个球。
  • DodecahedronGeometry (十二面体)基本使用演示

    1
    2
    3
    4
    5
    const radius = 1
    const detail = 0
    const dodecahedronGeometry = new THREE.DodecahedronGeometry(radius, detail)
    const material = new THREE.MeshPhongMaterial({ color: 0x00F5FF })
    const dodecahedron = new THREE.Mesh(dodecahedronGeometry, material)
  • DodecahedronGeometry (十二面体)改变参数detail

    1
    2
    3
    4
    5
    const radius = 1
    const detail = 0
    const dodecahedronGeometry = new THREE.DodecahedronGeometry(radius, detail)
    const material = new THREE.MeshPhongMaterial({ color: 0x00F5FF })
    const dodecahedron = new THREE.Mesh(dodecahedronGeometry, material)

下面是我做出来的DodecahedronGeometry (十二面体)demo示例,左边是默认的十二面体,右面是detail为1的多面体,各位如果看到这里的话可以自己尝试一下修改一下detail,看看修改后的不同表现。

IcosahedronGeometry (二十面体)学习

看参数

  • radius 二十面体的半径
  • detail 这个参数用来决定二十面体的顶点数,默认为0。也就是我们用到的二十面体,当把它设置为大于0的数时,原先的八面体就会增加一个顶点,将不再是二十面体。点数足够多时,四面体就会变成一个球。
  • IcosahedronGeometry (二十面体)基本使用演示

    1
    2
    3
    4
    5
    const radius = 1
    const detail = 0
    const icosahedronGeometry = new THREE.IcosahedronGeometry(radius, detail)
    const material = new THREE.MeshPhongMaterial({ color: 0x00F5FF })
    const icosahedron = new THREE.Mesh(icosahedronGeometry, material)
  • IcosahedronGeometry (二十面体)改变参数detail

    1
    2
    3
    4
    5
    const radius = 1
    const detail = 0
    const icosahedronGeometry = new THREE.IcosahedronGeometry(radius, detail)
    const material = new THREE.MeshPhongMaterial({ color: 0x00F5FF })
    const icosahedron = new THREE.Mesh(icosahedronGeometry, material)

下面是我做出来的IcosahedronGeometry (二十面体)demo示例,左边是默认的二十面体,右面是detail为1的多面体,各位如果看到这里的话可以自己尝试一下修改一下detail,看看修改后的不同表现。

到这里,典型的类球多面体咱们就学完了,还是一如既往,奉上本章完整的源代码,也可以点击three.js学习之类球多面体一次性查看所有demo,右键查看所有源代码。

three.js学习之类球多面体完整源代码

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
<!DOCTYPE html>
<html>
<head>
<title>three.js学习之典型类圆多面体学习</title>
<meta name="keywords" content="">
<meta name="description" content="">
<meta charset="utf8" />
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no">
<!-- <script src="https://cdn.bootcdn.net/ajax/libs/three.js/r99/three.min.js"></script> -->
<script src="./js/three.min.js"></script>
<style>
html,body{
height: 100%;
margin: 0;
}
#three{
display: block;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<canvas id="three"></canvas>
<script>
function main () {
const search = location.search
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 material = new THREE.MeshPhongMaterial({ color: 0x00F5FF })
const lineMaterial = new THREE.LineBasicMaterial({ color: 0xffffff })


{
// 创建四面体 MeshPhongMaterial
const radius = 2
const detail = 0
const tetrahedronGeometry = new THREE.TetrahedronGeometry(radius, detail)
const tetrahedron1 = new THREE.Mesh(tetrahedronGeometry, material)

const lineGeometry1 = new THREE.WireframeGeometry(tetrahedronGeometry)
const line = new THREE.Line(lineGeometry1, lineMaterial)
tetrahedron1.position.x = -2
line.position.x = -2
if (search.includes('tetrahedron') || !search) {
group.add(tetrahedron1, line)
}

const radius2 = 2
const detail2 = 1
const tetrahedronGeometry2 = new THREE.TetrahedronGeometry(radius2, detail2)
const tetrahedron2 = new THREE.Mesh(tetrahedronGeometry2, material)

const lineGeometry2 = new THREE.WireframeGeometry(tetrahedronGeometry2)
const line2 = new THREE.Line(lineGeometry2, lineMaterial)
tetrahedron2.position.x = 4
line2.position.x = 4
if (search.includes('tetrahedron') || !search) {
group.add(tetrahedron2, line2)
}

}

{
// 创建八面体 OctahedronGeometry
const radius1 = 2
const details1 = 0
const octahedronGeometry1 = new THREE.OctahedronGeometry(radius1, details1)
const octahedron1 = new THREE.Mesh(octahedronGeometry1, material)

const lineGeometry1 = new THREE.WireframeGeometry(octahedronGeometry1)
const line = new THREE.Line(lineGeometry1, lineMaterial)

octahedron1.position.x = -2
line.position.x = -2
if (!search.includes('octahedron')) {
octahedron1.position.y = 4
line.position.y = 4
}


if (search.includes('octahedron') || !search) {
group.add(octahedron1, line)
}

const radius2 = 2
const details2 = 1
const octahedronGeometry2 = new THREE.OctahedronGeometry(radius2, details2)
const octahedron2 = new THREE.Mesh(octahedronGeometry2, material)

const lineGeometry2 = new THREE.WireframeGeometry(octahedronGeometry2)
const line2 = new THREE.Line(lineGeometry2, lineMaterial)
octahedron2.position.x = 4
line2.position.x = 4
if (!search.includes('octahedron')) {
octahedron2.position.y = 4
line2.position.y = 4
}

if (search.includes('octahedron') || !search) {
group.add(octahedron2, line2)
}
}

{
// 创建十二面体
const radius = 2
const details = 0
const dodecahedronGeometry = new THREE.DodecahedronGeometry(radius, details)
const dodecahedron1 = new THREE.Mesh(dodecahedronGeometry, material)

const lineGeometry1 = new THREE.WireframeGeometry(dodecahedronGeometry)
const line = new THREE.Line(lineGeometry1, lineMaterial)

dodecahedron1.position.x = -2
line.position.x = -2
if (!search.includes('dodecahedron')) {
dodecahedron1.position.y = -4
line.position.y = -4
}
if (search.includes('dodecahedron') || !search) {
group.add(dodecahedron1, line)
}

const radius2 = 2
const details2 = 1
const dodecahedronGeometry2 = new THREE.DodecahedronGeometry(radius2, details2)
const dodecahedron2 = new THREE.Mesh(dodecahedronGeometry2, material)

const lineGeometry2 = new THREE.WireframeGeometry(dodecahedronGeometry2)
const line2 = new THREE.Line(lineGeometry2, lineMaterial)

dodecahedron2.position.x = 4
line2.position.x = 4

if (!search.includes('dodecahedron')) {
dodecahedron2.position.y = -4
line2.position.y = -4
}
if (search.includes('dodecahedron') || !search) {
group.add(dodecahedron2, line2)
}

}

{
// 创建20面体
const radius = 2
const details = 0
const icosahedronGeometry = new THREE.DodecahedronGeometry(radius, details)
const icosahedron1 = new THREE.Mesh(icosahedronGeometry, material)

const lineGeometry1 = new THREE.WireframeGeometry(icosahedronGeometry)
const line = new THREE.Line(lineGeometry1, lineMaterial)

icosahedron1.position.x = -8
line.position.x = -8
if (search.includes('icosahedron')) {
icosahedron1.position.x = 2
line.position.x = 2
}
if (search.includes('icosahedron') || !search) {
group.add(icosahedron1, line)
}

const radius2 = 2
const details2 = 1
const icosahedronGeometry2 = new THREE.DodecahedronGeometry(radius2, details2)
const icosahedron2 = new THREE.Mesh(icosahedronGeometry2, material)

const lineGeometry2 = new THREE.WireframeGeometry(icosahedronGeometry2)
const line2 = new THREE.Line(lineGeometry2, lineMaterial)

icosahedron2.position.x = -8
line2.position.x = -8
if (!search.includes('icosahedron')) {
icosahedron2.position.y = -4
line2.position.y = -4
} else {
icosahedron2.position.x = -4
line2.position.x = -4
}
if (search.includes('icosahedron') || !search) {

group.add(icosahedron2, line2)
}

}



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['children'].forEach((each, index) => {
if (each.position.y === 0) {
each.rotation.y = -time
} else {
each.rotation.y = -time
}
// if (index % 2 === 0) {
// each.rotation.z = -time
// } else {
// each.rotation.z = time
// }
})

// group.position.y = time
// group.position.x = time
renderer.render(scene, camera)
requestAnimationFrame(render)
}
requestAnimationFrame(render)
// render()
}
main()
</script>
</body>
</html>