134  
查询码:00001153
Three.js绘制点、线、面
来源:https://www.cnblogs.com/shenjie0507/p/9073370.html
作者: 朱凡 于 2020年03月19日 发布在分类 / FM组 / FM_App 下,并于 2020年03月19日 编辑
geometry camera 线条 颜色 renderer position function three.vector3 材质 vertices

Three.js绘制点、线、面

一、综述

  在计算机世界里,3D世界是由点组成,两个点能够组成一条直线,三个不在一条直线上的点就能够组成一个三角形面,无数三角形面就能够组成各种形状的物体,如下图:

  我们通常把这种网格模型叫做Mesh模型。给物体贴上皮肤,或者专业点就叫做纹理,那么这个物体就活灵活现了。最后无数的物体就组成了我们的3D世界。

二、两点连成直线

在Three.js中用一个向量来表示点:

var point1 = new THREE.Vecotr3(4,8,9);

另外也可以使用set方法,代码如下:

var point1 = new THREE.Vector3(); point1.set(4,8,9);

1.画一条彩色的线代码

<! 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(); var material = new THREE.LineBasicMaterial( { vertexColors: true } ); var color1 = new THREE.Color( 0x444444 ), color2 = new THREE.Color( 0xFF0000 ); // 线的材质可以由2点的颜色决定 var p1 = new THREE.Vector3( - 100 , 0 , 100 ); var p2 = new THREE.Vector3( 100 , 0 , - 100 ); geometry.vertices.push(p1); geometry.vertices.push(p2); geometry.colors.push( color1, color2 ); var line = new THREE.Line( geometry, material, THREE.LinePieces ); 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 >

2.画线

  两点确定一条直线,要画一条直线,思路是:

  • 定义一个几何体geometry用来存放两端点的坐标和颜色
  • 定义线条材质
  • 创建线条并加入到场景中

3.代码解析

定义点的坐标和颜色

var color1 = new THREE.Color( 0x444444 ), color2 = new THREE.Color( 0xFF0000 ); var p1 = new THREE.Vector3( -100, 0, 100 ); var p2 = new THREE.Vector3( 100, 0, -100 );

声明几何体并存放点和顶点颜色

var geometry = new THREE.Geometry(); geometry.vertices.push(p1); geometry.vertices.push(p2); geometry.colors.push( color1, color2 );

  几何体里面有一个vertices变量,可以用来存放点。

  geometry中colors表示顶点的颜色,必须材质中vertexColors等于THREE.VertexColors 时,颜色才有效,如果vertexColors等于THREE.NoColors时,颜色就没有效果了。那么就会去取材质中color的值 。

定义线条材质

var material = new THREE.LineBasicMaterial( { vertexColors: true } );

  使用THREE.LineBasicMaterial类型来定义线条材质,它接受一个集合作为参数,其原型如下:

  LineBasicMaterial( parameters )

  Parameters是一个定义材质外观的对象,它包含多个属性来定义材质,这些属性是:

  • Color:线条的颜色,用16进制来表示,默认的颜色是白色。
  • Linewidth:线条的宽度,默认时候1个单位宽度。
  • Linecap:线条两端的外观,默认是圆角端点,当线条较粗的时候才看得出效果,如果线条很细,那么你几乎看不出效果了。
  • Linejoin:两个线条的连接点处的外观,默认是“round”,表示圆角。
  • VertexColors:定义线条材质是否使用顶点颜色,这是一个boolean值。意思是,线条各部分的颜色会根据顶点的颜色来进行插值。
  • Fog:定义材质的颜色是否受全局雾效的影响。

创建线条并加入场景

var line = new THREE.Line( geometry, material, THREE.LinePieces ); scene.add(line);

  第一个参数是几何体geometry,里面包含了2个顶点和顶点的颜色。第二个参数是线条的材质,或者是线条的属性,表示线条以哪种方式取色。第三个参数是一组点的连接方式。

  然后,将这条线加入到场景中,代码如下:

  scene.add(line);

  这样,场景中就会出现刚才的那条线段了。

4.线条深入理解

  点由THREE.Vector3表示,Threejs中没有提供单独画点的函数,它必须被放到一个THREE.Geometry形状中,这个结构中包含一个数组vertices,这个vertices就是存放无数的点(THREE.Vector3)的数组。

三、网格面

1.右手坐标系

  Threejs使用的是右手坐标系。x轴正方向向右,y轴正方向向上,z轴由屏幕从里向外。

2.画坐标平面

<! 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 >

3.代码解析

  定义几何体并加入两个点。

var geometry = new THREE.Geometry(); geometry.vertices.push( new THREE.Vector3( - 500, 0, 0 ) ); geometry.vertices.push( new THREE.Vector3( 500, 0, 0 ) );

  这两个点决定了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 ); }

4.补充

  相机的position,是相机的位置。如果把人头比作相机,那么就是人头的中心的位置。

  up是头顶的方向。

  lookat是眼睛,看的方向,或者说是眼睛的聚焦点。

  最后要说明的是 up 和lookat这两个方向必须垂直,无论怎么设置,他们必须互相垂直。不然相机看到的结果无法预知。

  另外,相机没有朝向的说法,只有lookat,就是它看到的那一个聚焦点,就像眼睛看到的聚焦点一样。



 推荐知识

 历史版本

修改日期 修改人 备注
2020-03-19 18:14:21[当前版本] 朱凡 创建版本

 附件

附件类型

JPGJPG GIFGIF

知识分享平台 -V 4.8.7 -wcp