今天说说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. 0MQ底层队列设计

    ypipe_t has a yqueue_t. pipe_t relates two ypipe(s).pipe_t就是0MQ框架内使用的底层队列. yqueue_t的设计目的. yqueue_t 的 ...

  2. .NET高级特性-Emit(1)

    在这个大数据/云计算/人工智能研发普及的时代,Python的崛起以及Javascript的前后端的侵略,程序员与企业似乎越来越青睐动态语言所带来的便捷性与高效性,即使静态语言在性能,错误检查等方面的优 ...

  3. MyBatis 数值类型 where 条件配置的坑

    复现异常 我们先通过案例复现该类异常,测试项目地址:https://gitee.com/yin_jw/demo/tree/master/mybatis-demo/springboot-mybatis- ...

  4. Docker从入门到实践(4-1)

    使用 Docker 镜像 在之前的介绍中,我们知道镜像是 Docker 的三大组件之一. Docker 运行容器前需要本地存在对应的镜像,如果本地不存在该镜像,Docker 会从镜像仓库下载该镜像. ...

  5. c#、ASP.NET core 基础模块之一:linq(原创)

    最近做数据查询,发现linq 真的比我 印象中  要强大的多,实用的多,所以 我决定  要与linq  来一场  深入交流, 因为linq的基础用法 可以百度一大摞,我就记录点不一样的,结合我做项目使 ...

  6. Spring Boot2 系列教程(二十七)Nginx 极简扫盲入门

    上篇文章和大家聊了 Spring Session 实现 Session 共享的问题,有的小伙伴看了后表示对 Nginx 还是很懵,因此有了这篇文章,算是一个 Nginx 扫盲入门吧! 基本介绍 Ngi ...

  7. 菜鸟系列Fabric源码学习 — peer节点启动

    Fabric 1.4 源码分析peer节点启动 peer模块采用cobra库来实现cli命令. Cobra提供简单的接口来创建强大的现代化CLI接口,比如git与go工具.Cobra同时也是一个程序, ...

  8. 如何搭建Docker私有仓库

    私有仓库 有时候使用 Docker Hub 这样的公共仓库可能不方便,用户可以创建一个本地仓库供私人使用. 本节介绍如何使用本地仓库. docker-registry 是官方提供的工具,可以用于构建私 ...

  9. Selenium+Java(六)Selenium 强制等待、显式等待、隐实等待

    前言 在实际测试过程中,由于网速或性能方面的原因,打开相应的网页后或在网页上做了相应的操作,网页上的元素可能不会马上加载出来,这个时候需要在定位元素前等待一下,等元素加载出来后再进行定位,根据实际使用 ...

  10. pyenv virtualenv和virtualwrapper

    pyenv pyenv最大的优势是:可以在”全局”管理不同版本的Python, 可以随时配置当前的使用的Python版本,并对其他使用Python解释器的程序生效.当系统安装多个版本的Python,使 ...