当前位置:网站首页>第2章 还记得点、线、面吗(二)
第2章 还记得点、线、面吗(二)
2022-06-28 10:53:00 【用户9365514】
我们下面会学习使用直线画一个网格出来,为了更好的理解这个网格在空间中的位置,我们是时候,讲一讲空间坐标系了。
1、右手坐标系
Threejs使用的是右手坐标系,这源于opengl默认情况下,也是右手坐标系。下面是右手坐标系的图例,如果对这个概念不理解,可以百度一下,我保证你伸出手比划的那一瞬间你就明白了,如果不明白请给作者留言,我会尽快补上关于坐标系的知识。
图中右边那个手对应的坐标系,就是右手坐标系。在Threejs中,坐标和右边的坐标完全一样。x轴正方向向右,y轴正方向向上,z轴由屏幕从里向外。
5、线条的深入理解
在Threejs中,一条线由点,材质和颜色组成。
点由THREE.Vector3表示,Threejs中没有提供单独画点的函数,它必须被放到一个THREE.Geometry形状中,这个结构中包含一个数组vertices,这个vertices就是存放无数的点(THREE.Vector3)的数组。这个表示可以如下图所示:
为了绘制一条直线,首先我们需要定义两个点,如下代码所示:
var p1 = new THREE.Vector3( -100, 0, 100 ); |
|---|
var p2 = new THREE.Vector3( 100, 0, -100 ); |
请大家思考一下,这两个点在坐标系的什么位置,然后我们声明一个THREE.Geometry,并把点加进入,代码如下所示:
var geometry = new THREE.Geometry(); |
|---|
geometry.vertices.push(p1); |
geometry.vertices.push(p2); |
geometry.vertices的能够使用push方法,是因为geometry.vertices是一个数组。这样geometry 中就有了2个点了。
然后我们需要给线加一种材质,可以使用专为线准备的材质,THREE.LineBasicMaterial。
最终我们通过THREE.Line绘制了一条线,如下代码所示:
var line = new THREE.Line( geometry, material, THREE.LinePieces ); |
|---|
ok,line就是我们要的线条了。
6、画高中时深爱的坐标平面
我还深爱着高中时的那个坐标平面,它勾起了我关于前排同学的细细长发的回忆…
这个平面的效果如下所示,截图不完整哦:
它横竖分别绘制了20条线段,在摄像机的照射下,就形成了这般模样。你可以在[初级教程\chapter2\2-2.html]发现这些代码:
<!DOCTYPE html> |
|---|
<html> |
<head> |
<meta charset="UTF-8"> |
<title>Three框架</title> |
<script src="js/Three.js"></script> |
<style type="text/css"> |
div#canvas-frame { |
border: none; |
cursor: pointer; |
width: 100%; |
height: 600px; |
background-color: #EEEEEE; |
} |
</style> |
<script> |
var renderer; |
function initThree() { |
width = document.getElementById('canvas-frame').clientWidth; |
height = document.getElementById('canvas-frame').clientHeight; |
renderer = new THREE.WebGLRenderer({ |
antialias : true |
}); |
renderer.setSize(width, height); |
document.getElementById('canvas-frame').appendChild(renderer.domElement); |
renderer.setClearColor(0xFFFFFF, 1.0); |
} |
var camera; |
function initCamera() { |
camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000); |
camera.position.x = 0; |
camera.position.y = 1000; |
camera.position.z = 0; |
camera.up.x = 0; |
camera.up.y = 0; |
camera.up.z = 1; |
camera.lookAt({ |
x : 0, |
y : 0, |
z : 0 |
}); |
} |
var scene; |
function initScene() { |
scene = new THREE.Scene(); |
} |
var light; |
function initLight() { |
light = new THREE.DirectionalLight(0xFF0000, 1.0, 0); |
light.position.set(100, 100, 200); |
scene.add(light); |
} |
var cube; |
function initObject() { |
var geometry = new THREE.Geometry(); |
geometry.vertices.push( new THREE.Vector3( - 500, 0, 0 ) ); |
geometry.vertices.push( new THREE.Vector3( 500, 0, 0 ) ); |
for ( var i = 0; i <= 20; i ++ ) { |
var line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } ) ); |
line.position.z = ( i * 50 ) - 500; |
scene.add( line ); |
var line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } ) ); |
line.position.x = ( i * 50 ) - 500; |
line.rotation.y = 90 * Math.PI / 180; |
scene.add( line ); |
} |
} |
function threeStart() { |
initThree(); |
initCamera(); |
initScene(); |
initLight(); |
initObject(); |
renderer.clear(); |
renderer.render(scene, camera); |
} |
</script> |
</head> |
<body onload="threeStart();"> |
<div id="canvas-frame"></div> |
</body> |
</html> |
画网格关键之处initObject函数中,我们不浪费纸,但是浪费一些电,在下面重复一下上面的代码:
var cube; |
|---|
function initObject() { |
var geometry = new THREE.Geometry(); |
// B begin |
geometry.vertices.push( new THREE.Vector3( - 500, 0, 0 ) ); |
geometry.vertices.push( new THREE.Vector3( 500, 0, 0 ) ); |
// B end |
for ( var i = 0; i <= 20; i ++ ) { |
var line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } ) ); |
line.position.z = ( i * 50 ) - 500; |
scene.add( line ); |
var line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } ) ); |
line.position.x = ( i * 50 ) - 500; |
line.rotation.y = 90 * Math.PI / 180; |
scene.add( line ); |
} |
} |
思路:我们要画一个网格的坐标,那么我们就应该找到线的点。把网格虚拟成正方形,在正方形边界上找到几个等分点,用这些点两两连接,就能够画出整个网格来。
1、定义2个点
在x轴上定义两个点p1(-500,0,0),p2(500,0,0)。
geometry.vertices.push( new THREE.Vector3( - 500, 0, 0 ) ); |
|---|
geometry.vertices.push( new THREE.Vector3( 500, 0, 0 ) ); |
2、算法
这两个点决定了x轴上的一条线段,将这条线段复制20次,分别平行移动到z轴的不同位置,就能够形成一组平行的线段。
同理,将p1p2这条线先围绕y轴旋转90度,然后再复制20份,平行于z轴移动到不同的位置,也能形成一组平行线。
经过上面的步骤,就能够得到坐标网格了。代码如下:
for ( var i = 0; i <= 20; i ++ ) { |
|---|
var line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } ) ); |
line.position.z = ( i * 50 ) - 500; |
scene.add( line ); |
var line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } ) ); |
line.position.x = ( i * 50 ) - 500; |
line.rotation.y = 90 * Math.PI / 180; // 旋转90度 |
scene.add( line ); |
} |
好了,本节课讲完了,感觉自己写了好久好久。要兼顾深度和初学者,确实有些困难。最后,希望您喜欢。
边栏推荐
- Understanding of FTP protocol
- AGCO AI frontier promotion (6.28)
- MySQL(二)
- JS foundation 5
- MarkDown——基本使用语法
- Internet of things application case of wireless module transparent transmission technology
- Pop up and push in sequence of stack < difficulty coefficient >
- Fastposter v2.8.4 release e-commerce poster generator
- Hystrix deployment
- 使用 Calendar 计算时间
猜你喜欢

Realize an air conditioner with compose to bring you cool in summer

无线模块透明传输技术的物联网应用案例

【monkey】monkey测试入门

Summary of spatial temporal time series prediction modeling methods

DlhSoft Kanban Library for WPF

Katalon框架测试web(二十)自定义关键字以及上传弹窗操作

港伦敦金行情走势图所隐藏的信息

利用soapUI获取freemarker的ftl文件模板

还在用 SimpleDateFormat 做时间格式化?小心项目崩掉!

Mysql database overview and installation process
随机推荐
一款自动生成单元测试的 IDEA 插件,开发效率提升 70% 以上!
静态库的制作和使用
sentinel
Mongo database
数据库系列:有什么办法对数据库的业务表进行无缝升级
Metersphere uses JS to refresh the current page
Katalon framework tests web (XX) custom keywords and upload pop-up operations
广州海关支持保障食品、农产品和中药材等民生物资稳定供港
【monkey】monkey测试入门
MySQL (II)
Bytecode proof in appliedzkp zkevm (9)
毕业季 新的开始
vsftpd服务的部署及优化
appliedzkp zkevm(10)中的Transactions Proof
linux中源码安装mysql数据库(centos)
Décompression par compression
DlhSoft Kanban Library for WPF
毕业季,给初入社会的你一些建议
[practice] appium settings app is not running after 5000ms
What is the function of ICMP Protocol and the principle of Ping of death attack?