学习threejs,使用LatheGeometry旋转体(榫卯体)几何体
👨⚕️ 主页: gis分享者
👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅!
👨⚕️ 收录于专栏:threejs gis工程师
文章目录
- 一、🍀前言
- 1.1 ☘️THREE.LatheGeometry
- 1.1.1 ☘️代码示例
- 1.1.2 ☘️构造函数
- 1.1.3 ☘️属性
- 1.1.4 ☘️方法
- 二、🍀使用LatheGeometry旋转体(榫卯体)几何体
- 1. ☘️实现思路
- 2. ☘️代码样例
一、🍀前言
本文详细介绍如何基于threejs在三维场景中使用LatheGeometry旋转体(榫卯体)几何体,亲测可用。希望能帮助到您。一起学习,加油!加油!
1.1 ☘️THREE.LatheGeometry
THREE.LatheGeometry创建具有轴对称性的网格,比如花瓶。车削绕着Y轴来进行旋转。
1.1.1 ☘️代码示例
代码示例
const points = [];
for ( let i = 0; i < 10; i ++ ) {
points.push( new THREE.Vector2( Math.sin( i * 0.2 ) * 10 + 5, ( i - 5 ) * 2 ) );
}
const geometry = new THREE.LatheGeometry( points );
const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
const lathe = new THREE.Mesh( geometry, material );
scene.add( lathe );
1.1.2 ☘️构造函数
LatheGeometry(points : Array, segments : Integer, phiStart : Float, phiLength : Float)
points — 一个Vector2对象数组。每个点的X坐标必须大于0。 Default is an array with (0,-0.5), (0.5,0) and (0,0.5) which creates a simple diamond shape.
segments — 要生成的车削几何体圆周分段的数量,默认值是12。
phiStart — 以弧度表示的起始角度,默认值为0。
phiLength — 车削部分的弧度(0-2PI)范围,2PI将是一个完全闭合的、完整的车削几何体,小于2PI是部分的车削。默认值是2PI。
基于参数创建一个LatheGeometry。
1.1.3 ☘️属性
共有属性请参见其基类BufferGeometry。
.parameters : Object : Color
一个包含着构造函数中每个参数的对象。在对象实例化之后,对该属性的任何修改都不会改变这个几何体。
1.1.4 ☘️方法
共有方法请参见其基类BufferGeometry。
二、🍀使用LatheGeometry旋转体(榫卯体)几何体
1. ☘️实现思路
- 1、初始化renderer渲染器。
- 2、初始化Scene三维场景scene。
- 3、初始化camera相机,定义相机位置 camera.position.set,设置相机方向camera.lookAt。
- 4、加载几何模型:定义createMesh方法,使用MeshNormalMaterial网格法向材质和MeshBasicMaterial基础材质,生成mesh网格对象。定义generatePoints方法生成LatheGeometry旋转体数据latheGeometry,方法内调用createMesh方法创建旋转体网格对象latheMesh,场景scene添加latheMesh。加入gui控制,控制分段数、起始角度、车削部分的弧度。具体代码参考下面代码样例。
- 5、加入stats监控器,监控帧数信息。
2. ☘️代码样例
<!DOCTYPE html>
<html>
<head>
<title>学习threejs,使用LatheGeometry旋转体(榫卯体)几何体</title>
<script type="text/javascript" src="../libs/three.js"></script>
<script type="text/javascript" src="../libs/stats.js"></script>
<script type="text/javascript" src="../libs/dat.gui.js"></script>
<style>
body {
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<div id="Stats-output">
</div>
<!-- Div which will hold the Output -->
<div id="WebGL-output">
</div>
<!-- Js 代码块 -->
<script type="text/javascript">
// 初始化
function init() {
var stats = initStats();
// 创建三维场景
var scene = new THREE.Scene();
// 创建透视相机
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
// 创建渲染器
var webGLRenderer = new THREE.WebGLRenderer();
webGLRenderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0));
webGLRenderer.setSize(window.innerWidth, window.innerHeight);
webGLRenderer.shadowMapEnabled = true;
// 设置相机位置和方向
camera.position.x = -30;
camera.position.y = 40;
camera.position.z = 50;
camera.lookAt(new THREE.Vector3(10, 0, 0));
// 渲染器绑定html要素
document.getElementById("WebGL-output").appendChild(webGLRenderer.domElement);
var step = 0;
var spGroup;
// 旋转体网格对象
var latheMesh;
generatePoints(12, 2, 2 * Math.PI);
// gui控制设置
var controls = new function () {
this.segments = 12;
this.phiStart = 0;
this.phiLength = 2 * Math.PI;
this.redraw = function () {
scene.remove(spGroup);
scene.remove(latheMesh);
generatePoints(controls.segments, controls.phiStart, controls.phiLength);
};
};
var gui = new dat.GUI();
gui.add(controls, 'segments', 0, 50).step(1).onChange(controls.redraw);
gui.add(controls, 'phiStart', 0, 2 * Math.PI).onChange(controls.redraw);
gui.add(controls, 'phiLength', 0, 2 * Math.PI).onChange(controls.redraw);
render();
function generatePoints(segments, phiStart, phiLength) {
var points = [];
var height = 5;
var count = 30;
for (var i = 0; i < count; i++) {
points.push(new THREE.Vector3((Math.sin(i * 0.2) + Math.cos(i * 0.3)) * height + 12, 0, ( i - count ) + count / 2));
}
spGroup = new THREE.Object3D();
var material = new THREE.MeshBasicMaterial({color: 0xff0000, transparent: false});
points.forEach(function (point) {
var spGeom = new THREE.SphereGeometry(0.2);
var spMesh = new THREE.Mesh(spGeom, material);
spMesh.position.copy(point);
spGroup.add(spMesh);
});
// add the points as a group to the scene
scene.add(spGroup);
// 创建旋转几何体
var latheGeometry = new THREE.LatheGeometry(points, segments, phiStart, phiLength);
latheMesh = createMesh(latheGeometry);
scene.add(latheMesh);
}
function createMesh(geom) {
// var meshMaterial = new THREE.MeshBasicMaterial({color:0x00ff00, transparent:true, opacity:0.6});
var meshMaterial = new THREE.MeshNormalMaterial();
meshMaterial.side = THREE.DoubleSide;
var wireFrameMat = new THREE.MeshBasicMaterial();
wireFrameMat.wireframe = true;
// 创建网格对象
var mesh = THREE.SceneUtils.createMultiMaterialObject(geom, [meshMaterial, wireFrameMat]);
return mesh;
}
function render() {
stats.update();
spGroup.rotation.x = step;
latheMesh.rotation.x = step += 0.01;
requestAnimationFrame(render);
webGLRenderer.render(scene, camera);
}
function initStats() {
var stats = new Stats();
stats.setMode(0);
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '0px';
stats.domElement.style.top = '0px';
document.getElementById("Stats-output").appendChild(stats.domElement);
return stats;
}
}
window.onload = init;
</script>
</body>
</html>
效果如下: