当前位置: 首页 > news >正文

学习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>

效果如下:
在这里插入图片描述

相关文章:

  • texstudio: 编辑器显示行号+给PDF增加行号
  • 大数据实时分析:ClickHouse、Doris、TiDB 对比分析
  • 力扣-数组-34 在排序数组中查找元素的第一个和最后一个位置
  • 代码随想录|二叉树|07二叉树周末总结
  • 使用 Miniforge3 管理 Python 环境的详细指南(基于最新实践和时效性信息,截至 2025 年)
  • ArcGIS Pro 行政区划数据处理:拆分与提取方法详解
  • 修改桌面图标——操作系统程序图标(Windows 10)
  • 2024年广州市智能网联汽车创新实践年度报告
  • 583. 两个字符串的删除操作
  • 【数据库系统概论】第十一章 并发控制
  • dockor
  • 速通C语言——(分支和循环)
  • conda 安装软件报错 Found conflicts! Looking for incompatible packages.
  • 快速使用PPASR V3版不能语音识别框架
  • Docker Compose国内镜像一键部署dify
  • 【前端面试题】Vu3常见的面试题
  • 【网络】poll 与epoll(原理、工作模式LT、ET)
  • Windows 图形显示驱动开发-WDDM 3.2-可调性改进
  • [论文阅读]Trustworthiness in Retrieval-Augmented Generation Systems: A Survey
  • 【实战ES】实战 Elasticsearch:快速上手与深度实践-7.3.2使用GraphQL封装查询接口
  • 谜语的强制力:弗洛伊德与俄狄浦斯
  • 4月深圳新房、二手房成交同比均上涨,“5月有望延续积极向好的发展态势”
  • 是谁提议特朗普向好莱坞征税?
  • 86岁书画家、美术教育家、吴昌硕嫡裔曾孙吴民先离世
  • 五一假期,长三角铁路张家港、台州等多个车站客发量创新高
  • 美政府称不再对哈佛大学提供联邦资助