今天说说three.js的几何体,常见的几何体今天就不说了,今天说一说如何画直线,圆弧线,以及高级几何体。

1. 画一条直线

画直线我们使用THREE.Geometry()对象。

//给空白几何体添加点信息,geometry会把这些点自动组合成线。
var material = new THREE.LineBasicMaterial({color: 0x00ff00});
var geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(0,0,0));
geometry.vertices.push(new THREE.Vector3(10,10,10));
geometry.vertices.push(new THREE.Vector3(0,20,0));
var line = new THREE.Line(geometry, material);

这样就在空间画出了一条折线。

2.画一条圆弧线

画圆弧线我们借助THREE.ArcCurve()对象。这个对象有点类似于d3.js中的布局(layout),它的本质就是根据参数生成一系列点坐标,他有一些方法.getPoints()从圆弧线均匀获得圆弧上面点的坐标。下面是THREE.ArcCurve()的部分源码。

THREE.ArcCurve = function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {

    THREE.EllipseCurve.call( this, aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );

};

我们可以知道有6个参数,并且继承自THREE.EllipseCurve()。加下来我们来画圆弧。

var arc = new THREE.ArcCurve(0, 0, 30, 0, Math.PI * 2, true);
var points = arc.getPoints(1000);
var ring = new THREE.Geometry();
points.forEach(v => ring.vertices.push(new THREE.Vector3(v.x,0,v.y)));
var mat = new THREE.LineBasicMaterial({color: 0x999900});
var line = new THREE.LineLoop(ring, mat);

注意points都是XY平面上面的点。最后使用THREE.LineLoop来绘制圆弧线。

3. 使用ConvexGeometry()凸包

什么是凸包?简单地说凸包就是,在空间中每三个不在一条直线的点都可以组成一个平面,如果空间中有一组点,那么会组成很多平面,如果平面不透明,我们只能看到最外层的若干个面,这个面组成的几个体就是凸包。

like this !(这个只是加了岩石纹理)

凸包使用起来非常简单

let asteroidMate = new THREE.MeshBasicMaterial();
let points = [];
let rad = Math.pow(Math.random(), 3) * ASTERIODRADIUS;
for(var j=0; j<30; j++) {
points.push(new THREE.Vector3(Math.random() * 10, Math.random() * 10, Math.random() * 10))
}
var asteroidGeom = new THREE.ConvexGeometry(points); var asterMesh = new THREE.Mesh(asteroidGeom, asteroidMate);

这就是30个点组成的随机凸包。大家可以试试用它来自定义图形或者制作随机图形。

4. LatheGeometry() 旋转体

旋转体就是将由一组点组成的线绕固定轴旋转形成的几何体,LatheGeometry有4个参数,第一个是points点数组,第二个是分段数,第三个是旋转开始角度,第四个是旋转角度。

ar points = [];
for(var i=-12; i<=10; i = i + 0.5) {
if(i < 0) {
console.log(Math.sqrt(36 - Math.pow(i + 6, 2)) * 1.2, i)
points.push(new THREE.Vector3(Math.sqrt(36 - Math.pow(i + 6, 2)) * 1.2, i))
} else if(i < 8 && i >= 0) {
console.log(Math.sqrt(16 - Math.pow(i - 4, 2)) * 1.2, i)
points.push(new THREE.Vector3(Math.sqrt(16 - Math.pow(i - 4, 2)) * 1.2, i))
} else {
console.log(Math.sqrt(1 - Math.pow(i - 9, 2)) * 1.2, i)
points.push(new THREE.Vector3(Math.sqrt(1 - Math.pow(i - 9, 2)) * 1.2, i))
}
}
var latheGeo = new THREE.LatheGeometry(points, 30, 0, Math.PI * 2);
latheMesh = createMesh(latheGeo);;

5. ExtrudeGeometry()拉伸几何体

拉伸几何体就是将一个几何体沿着Z轴拉伸形成的几何体。它的参数比较多但是不难理解。

var material = new THREE.MeshNormalMaterial();
var shapeGeomery = new THREE.Shape();
shape.moveTo(-10, -10);
shape.lineTo(10, -10);
shape.lineTo(10, 10);
shape.lineTo(-10,10);
shape.lineTo(-10, -10);
var geometry = new THREE.ExtrudeGeometry(shapeGeomery, {
amount: 2, //拉伸的深度
bevelThickness: 2, //斜角的深度
bevelSize: 3, //斜角的高度
bevelSegments: 30, //斜角分段数
bevelEnabled: true, //开启斜角
curveSegments: 12, //拉伸的段数
steps: 1 //沿深度方向的段数
})
var shape = new THREE.Mesh(geometry, material);

这里注意几点,
1.ExtrudeGeometry()的第一个参数是一个shape对象,
2.区分一下这三个分段数,bevelSegments是斜角的分段,它影响斜角的光滑程度,curveSegments是拉伸曲线的段数,steps是沿深度方向的段数。

6.TubeGeometry()沿曲线拉伸

这个方法很简单,就是验证曲线拉伸成一根管,简单的东西直接上代码

var points = [];
for (var i = 0; i < controls.numberOfPoints; i++) {
var randomX = -20 + Math.round(Math.random() * 50);
var randomY = -15 + Math.round(Math.random() * 40);
var randomZ = -20 + Math.round(Math.random() * 40); points.push(new THREE.Vector3(randomX, randomY, randomZ));
}
var tubeGeometry = new THREE.TubeGeometry(new THREE.SplineCurve3(points), 64, 3, 16, false);
var meshMaterial = new THREE.MeshBasicMaterial({color: 0x00ff00, transparent: true, opacity: 0.2});
var tubeMesh = new THREE.Mesh(tubeGeometry, meshMaterial)

这里只需注意TubeGeometry()的第一个参数是一个SplineCurve3对象,需要将三维点数组用SplineCurve3处理成三维曲线。

7.ParametricGeometry()基于等式的几何体

这个东西类似于高数中的参数方程,通过三阶等式来创建空间曲面,使用ParametricGeometry()的时候,我特意使用了v69版本和v104两个版本,使用方法是不同的。下面我们从代码中寻找区别。

// v69
var oldVersion = function (u, v) {
var x = u * 50 - 25;
var z = v * 50 - 25;
var y = Math.sin(u * 50 - 25) + Math.sin(v * 50 - 25) + Math.pow((Math.pow((u - 0.5), 2) + Math.pow((v - 0.5), 2)) * 10, 2) - 10;
return new THREE.Vector3(x, y, z);
};
var geometry = new THREE.ParametricGeometry(oldVersion, 120, 120)
var newVersion = function (u, v, target) {
var x = u * 50 - 25;
var z = v * 50 - 25;
var y = Math.sin(u * 50 - 25) + Math.sin(v * 50 - 25) + Math.pow((Math.pow((u - 0.5), 2) + Math.pow((v - 0.5), 2)) * 10, 2) - 10;
target.set(x,y,z);
};
var geometry = new THREE.ParametricGeometry(newVersion, 120, 120)

可以看出方法中传递了第三个参数,这里使用set方法做了优化,(所以说每当出现新的js标准后,都出新生一些框架或者出现新版本)。相信喜欢数学的小伙伴都会非常喜欢这个几何体。下面随便展示一个demo

### 8. 组合网格
未完待续。。。(这将是一个非常有意思的几何体)
### 9. Geometry()实现自定义面
未完待续。。。(同样可以很发散)

更多demo请移步至原文

转载请注明原文地址 http://www.bettersmile.cn 郭志强的博客

初探three.js几何体的更多相关文章

  1. 初探three.js几何体-Geometry

    three.js几何体我们还没有说完,这一节我们说一说THREE.Geometry(),简单几何体都是继承了这个对象,使用它会相对麻烦一些,但是可操作性非常高,今天我们使用它制作一个自定义几何体-五角 ...

  2. 初探原生js根据json数据动态创建table

    初探原生js根据json数据动态创建table 小生以实习生的职位进入了一家非纯软件的公司做asp.net开发,大半个月下来发现公司里居然没有前端工程师,这令我很诧异,跟着公司做项目,发现前端后台没有 ...

  3. 初探three.js

    相信大多数选择前端的小伙伴都有一个设计师的梦,今天我来说一说three.js.three.js是一款运行在浏览器中的 3D 引擎,你可以用它创建各种三维场景,包括了摄影机.光影.材质等各种对象.学习了 ...

  4. three.js 几何体(二)

    上一篇简单的介绍了几何体的构造体参数,这一篇郭先生就更加详细的说一说(十分简单的几何体我就不说了). 1. ShapeGeometry形状几何体 形状几何体方便我们从一个或多个路径形状中创建一个单面多 ...

  5. 初探 Ext JS 6 (sencha touch/ext升级版)

    Sencha Touch 现在已全面升级至Ext Js 6,那么我们如何使用他们呢? 首先去官网下载最新的sdk和帮助文档 sdk下载地址:https://www.sencha.com/product ...

  6. 初探grunt.js

    package.js { "name": "ttd_v3", "version": "0.1.0", "aut ...

  7. 初探flow.js

    第一部分:前言 我们知道JS是弱类型语言,在声明变量时不论是什么类型的变量我们都用var即可,所以js是非常灵活的,但是同时问题就是弱类型语言有可能会出错,比如在调用函数时,且往往在运行起来时才可以检 ...

  8. 前端初学者——初探Modernizr.js Modernizr.js笔记

    什么是Modernizr? Modernizr 是一个用来检测浏览器功能支持情况的 JavaScript 库. 目前,通过检验浏览器对一系列测试的处理情况,Modernizr 可以检测18项 CSS3 ...

  9. 初探node.js

    一.定义及优势 定义:Node.js是一个基于 Chrome V8 引擎 的 JavaScript 运行时,它以事件驱动为基础实现了非阻塞模型. 优势:由于Web场景下的大多数任务(静态资源读取.数据 ...

随机推荐

  1. ArcGIS API For Javascript :双屏(多屏)地图联动的方法

    在遇到地图对比的应用场景下,我们需要双屏地图或者多屏地图来满足我们的业务需求. 解决思路:首先生成两份(多份)地图,然后通过监听地图缩放拖拽,用地图四至将不同的地图对象做绑定,实现多地图联动. 前端部 ...

  2. Apache Hudi 介绍与应用

    Apache Hudi Apache Hudi 在基于 HDFS/S3 数据存储之上,提供了两种流原语: 插入更新 增量拉取 一般来说,我们会将大量数据存储到HDFS/S3,新数据增量写入,而旧数据鲜 ...

  3. Json模块和Pickle模块的使用

    在对数据进行序列化和反序列化是常见的数据操作,Python提供了两个模块方便开发者实现数据的序列化操作,即 json 模块和 pickle 模块.这两个模块主要区别如下: json 是一个文本序列化格 ...

  4. 使用idea来部署git项目

    使用idea来部署git项目 一).将项目交由git管理 VCS ---->import into Version Cntorl ------>create Git Repository ...

  5. [ch02-02] 非线性反向传播

    系列博客,原文在笔者所维护的github上:https://aka.ms/beginnerAI, 点击star加星不要吝啬,星越多笔者越努力. 2.2 非线性反向传播 2.2.1 提出问题 在上面的线 ...

  6. node中mysql和短信使用方法(3)

    一.mysql的使用 使用mysql首先得有数据库并且表里面有数据,我创建了数据库newsql,里面Tables有表company等等. company有id,name,other等字段 1.导入my ...

  7. 音视频入门-14-JPEG文件格式详解

    * 音视频入门文章目录 * JPEG 文件格式解析 JPEG 文件使用的数据存储方式有多种.最常用的格式称为 JPEG 文件交换格式(JPEG File Interchange Format,JFIF ...

  8. OAuth 2.0 概念及授权流程梳理

    本文可以转载,但请注明出处https://www.cnblogs.com/hellxz/p/oauth2_process.html OAuth2 的概念 OAuth是一个关于授权的开放网络标准,OAu ...

  9. hadoop全分布式的搭建

    修改主机名:vim /etc/sysconfig/network 1 修改 hadoop-env.sh 2 修改core-site.xml /hadoop/tmpdir: 产生 namenode中fs ...

  10. mysql 插入string类型变量时候,需要注意的问题,妈的,害我想了好几个小时!!

    很多人在用php+MySQL做网站往数据库插入数据时发现如下错误: 注册失败!Unknown column '1a' in 'field list' 结果发现用数字提交是没有问题的,其他如char型就 ...