Three.js学习10:几何体(1)-平面几何体

2024-02-19 03:44

本文主要是介绍Three.js学习10:几何体(1)-平面几何体,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 -----------------------------华丽的分割线---------------------

相关代码均已上传到 gitee 中:myThree: 学习 Three.js ,努力加油~!

Gitee 静态演示地址:Three JS 演示页面

 -----------------------------华丽的分割线---------------------

一、几何体 Geometry

Three.js 中物体都是由网格(mesh)构成的。一个网格物体(mesh)是由几何体 Geometry 和材质 material 组成。

几何体 Geometry 定义了网格的材质 material 定义了网格的

Three.js 中提供了一系列绘制几何体的类,如 BoxGeometry、SphereGeometry,PlaneGeometry、CircleGeometry、CylinderGeometry 等,使用这些类可以快速创建对应的几何体。

如果要做更复杂的几何体,可以使用几何体基类 BufferGeometry,它是 Three.js 的核心类之一。

网络上一些教程提到每个几何体都有一个 buffer 缓冲几何体与之对应,如 BoxGeometry 对应有 BoxBufferGeometry 之类。这些之前版本的Three.js 有,在目前的 Three.js 版本(r161 版)中,XXBufferGeometry 已经被取消。

Three.js 的几何体的面都是由三角形组成的。因此,很多内置几何体可以设置对应三角的个数(segment,份数,段数)以修改几何体的形状。

二、Three.js 内置几何体

Three.js 目前(r161 版)内置了 21 个几何体,以及 5 个附加几何体,分别是:

  • 二维几何体

      - CircleGeometry:圆形几何体
      - PlaneGeometry:平面几何体
      - RingGeometry:平面圆环几何体
      - ShapeGeometry:任意平面形状几何体
  • 常用三维几何体

      - BoxGeometry:立方体
      - SphereGeometry:球体
      - CylinderGeometry:圆柱体
      - TorusGeometry:立体圆环
      - CapsuleGeometry:胶囊体
      - ConeGeometry:圆锥体
  • 其他几何体

      - TetrahedronGeometry:四面几何体
      - OctahedronGeometry:八面几何体
      - DodecahedronGeometry:十二面几何体
      - IcosahedronGeometry:二十面几何体
      - PolyhedronGeometry:多面几何体
      - ExtrudeGeometry:挤压缓冲几何体
      - LatheGeometry:车削几何体
      - TorusKnotGeometry:环形扭结几何体
      - TubeGeometry:管道几何体
  • 辅助几何体

      - EdgesGeometry:边缘几何体。可以作为一个辅助对象来查看geometry的边缘。
      - WireframeGeometry:网格几何体。可以被用作一个辅助对象来查看geometry的线框。
  • 附加几何体。必须添加附加组件才能使用。

      - ConvexGeometry:凸包几何体
      - DecalGeometry:贴花几何体
      - ParametricGeometry:参数化几何体
      - TextGeometry:文本几何体
      - SDFGeometryGenerator:SDF几何体生成器

本文主要讨论二维平面几何体。

三、二维几何体

1. CircleGeometry:圆形几何体

CircleGeometry 是欧式几何的一个简单形状,它由围绕着一个中心点的三角分段的数量所构造,由给定的半径来延展。它可以创造圆形规则多边形

构造函数:

 CircleGeometry(radius : Float, segments : Integer, thetaStart : Float, thetaLength : Float)
属性是否必填描述
radius圆半径,默认1。
segments定义创建圆所用面的数量,最小为3,默认为32,数量越多圆越光滑。
thetaStart第一个分段的起始角度,默认为0。(钟面3点钟的位置)
thetaLength圆形扇区的中心角,通常被称为“θ”(西塔)。默认值是 2*Pi,这使其成为一个完整的圆。

代码示例:

const geometry = new THREE.CircleGeometry( 2, 32, Math.PI/4, Math.PI );
const material = new THREE.MeshBasicMaterial( { color: 0xff3300 
} );
const circle = new THREE.Mesh( geometry, material );
scene.add( circle );

  • 渲染两面

不过,Three.js 默认渲染几何体只渲染前面(FrontSide),旋转相机,会发现背面(BackSide)什么都看不到。Three.js 这么做可以节约系统资源,提高渲染效率。

要看到背面,需要给材质(material)设置属性 side 值为 THREE.DoubleSide

const material = new THREE.MeshBasicMaterial( { color: 0xff3300,side: THREE.DoubleSide 
});
  •  获取参数

通过 geometry.parameters 属性,可以获取构造函数里的各个参数。但是,当 Geometry 被实例化后,修改此属性并不会修改物体形状。如:

const geometry = new THREE.CircleGeometry( 2, 16, Math.PI/4, Math.PI );
// 修改属性值,不会修改Geometry形状
geometry.parameters.radius = 4;

只有销毁原来的 Geometry,重新创建一个 Geometry 。如,利用 GUI 控制一个立方体 box(部分代码)。

// 物体
const geometry = new THREE.BoxGeometry(1,1,1);
const material = new THREE.MeshBasicMaterial({color:"#ff3300"
});
const box = new THREE.Mesh( geometry, material );
scene.add( box );// gui 控制
const params = {boxParam:{color:"#ff3300",width:1,height:1,depth:1}
}
// box控制
const folderBox = gui.addFolder("立方体控制");
folderBox.add(  params.boxParam,"width",1,10).onChange(function(value){box.geometry.dispose();box.geometry = new THREE.BoxGeometry( value ,params.boxParam.height, params.boxParam.depth);
});
folderBox.add(  params.boxParam,"height",1,10).onChange(function(value){box.geometry.dispose();box.geometry = new THREE.BoxGeometry( params.boxParam.width ,value, params.boxParam.depth);
});
  • 利用 GUI 调试几何体参数

此处以圆形几何体调试为例,其它几何体的参数调试大同小异。

HTML:

<script type="importmap">{"imports":{"three":"./js/three.module.min.js","addons/":"./js/jsm/","dat":"./js/gui/dat.gui.module.js"}}
</script>
<script type="module" src="js/myjs.js"></script>

 JS:

import * as THREE from "three";
import { OrbitControls } from "addons/controls/OrbitControls.js";
import * as dat from "dat";let winH = window.innerHeight;
let winW = window.innerWidth;
let bili = winW / winH ;
// 场景
const scene = new THREE.Scene();
scene.background = new THREE.Color("#cccccc");// grid
const gridHelper = new THREE.GridHelper(10,10);
scene.add( gridHelper);// 相机
const camera = new THREE.PerspectiveCamera(50, bili, 1, 1000);
camera.position.set(0,5,5);
camera.lookAt(scene.position);// 物体
const geometry = new THREE.CircleGeometry( 2, 16, Math.PI/4, Math.PI );
const material = new THREE.MeshBasicMaterial( { color: 0xff3300,side: THREE.DoubleSide 
} );
const circle = new THREE.Mesh( geometry, material );// 线框
const wireframe = new THREE.WireframeGeometry( geometry );
const line = new THREE.Line( wireframe );
line.material.depthTest = false;
line.material.opacity = 0.7;
line.material.transparent = true;
line.material.color = new THREE.Color("#ffff00");const mesh = new THREE.Mesh();   // 创建空物体
mesh.add(circle);        // 给空物体添加子物体
mesh.add(line);          // 添加线框
scene.add( mesh );       // 在场景中添加物体console.info(mesh);// GUI
const data = {radius:geometry.parameters.radius,segments:geometry.parameters.segments,thetaStart:geometry.parameters.thetaStart,thetaLength:geometry.parameters.thetaLength
}
function updateGroupGeometry( mesh, geometry ) {mesh.children[0].geometry.dispose();mesh.children[0].geometry = geometry;mesh.children[1].geometry.dispose();mesh.children[1].geometry = new THREE.WireframeGeometry( geometry );
}
function changeGUI(){updateGroupGeometry( mesh,new THREE.CircleGeometry(data.radius, data.segments, data.thetaStart, data.thetaLength));
}
const gui = new dat.GUI();
const folder = gui.addFolder("CircleGeometry");
folder.add(data, "radius",1,10,1).onChange(changeGUI);
folder.add(data, "segments",3,64,1).onChange(changeGUI);
folder.add(data, "thetaStart",0,Math.PI*2).onChange(changeGUI);
folder.add(data, "thetaLength",0,Math.PI*2).onChange(changeGUI);
folder.open();
// 渲染器
const renderer  = new THREE.WebGLRenderer();
renderer.setSize( winW, winH );
document.body.appendChild( renderer.domElement );
renderer.render( scene, camera );// 轨道控制器
const controls = new OrbitControls( camera, renderer.domElement );
controls.update();// 动画
function animateFun(){controls.update();   // 现在动画里更新控制器// 渲染renderer.render( scene, camera);requestAnimationFrame(animateFun);
}
animateFun();
// 响应式
window.onresize = function(){winH = window.innerHeight;winW = window.innerWidth;renderer.setSize( winW, winH );camera.aspect = winW/winH;camera.updateProjectionMatrix();renderer.render( scene, camera );
}

2. PlaneGeometry:平面几何体

用于生成平面几何体。

构造函数:

 PlaneGeometry(width : Float, height : Float, widthSegments : Integer, heightSegments : Integer)
属性是否必填描述
width平面沿着 X 轴的宽度。默认值是 1
height平面沿着 Y 轴的高度。默认值是 1
widthSegments(可选)平面的宽度分段数,默认值是 1
heightSegments(可选)平面的高度分段数,默认值是 1

代码示例:

const geometry = new THREE.PlaneGeometry( 5, 5 );
const material = new THREE.MeshBasicMaterial( {color: 0xff3300,side: THREE.DoubleSide 
} );
const plane = new THREE.Mesh( geometry, material );
scene.add( plane );

3. RingGeometry:平面圆环几何体

用于生成二维圆环。

构造函数:

 RingGeometry(innerRadius : Float, outerRadius : Float, thetaSegments : Integer, phiSegments : Integer, thetaStart : Float, thetaLength : Float)
属性是否必填描述
innerRadius内部半径,默认值为 0.5
outerRadius外部半径,默认值是 1
thetaSegments圆环的分段数。这个值越大,圆环就越圆。最小值为 3,默认值为 32
phiSegments圆环半径的分段数字。最小值为1,默认值是 1
thetaStart起始角度,默认值为0。
thetaLength圆心角,默认值为 Math.PI * 2

示例代码:

const geometry = new THREE.RingGeometry(1,2,32 );
const material = new THREE.MeshBasicMaterial( { color: 0xff3300,side: THREE.DoubleSide 
} );
const mesh = new THREE.Mesh( geometry, material );

4. ShapeGeometry:任意形状几何体

从一个或多个路径形状中创建一个单面几何体。

构造函数:

 ShapeGeometry(shapes : Array, curveSegments : Integer)
属性是否必填描述
shapes一个单独的shape,或者一个包含形状的Array。默认是一个三角形。
curveSegments每一个形状的分段数,默认值为 12

这里的 shape 形状,是指 Three.js 里定义的 Shape 对象。其基于Three.js 的 Path 类,该类定义了二维路径,提供了一些类似2D Canvas API的方法来创建或者构造二维路径。

具体参见 Three.js 官方文档。

示例代码:

const x = 0, y = 0;const heartShape = new THREE.Shape();heartShape.moveTo( x + 0.5, y + 0.5 );
heartShape.bezierCurveTo( x + 0.5, y + 0.5, x + 0.4, y, x, y );
heartShape.bezierCurveTo( x - 0.6, y, x - 0.6, y + 0.7,x - 0.6, y + 0.7 );
heartShape.bezierCurveTo( x - 0.6, y + 1.1, x - 0.3, y + 1.54, x + 0.5, y + 1.9 );
heartShape.bezierCurveTo( x + 1.2, y + 1.54, x + 1.6, y + 1.1, x + 1.6, y + 0.7 );
heartShape.bezierCurveTo( x + 1.6, y + 0.7, x + 1.6, y, x + 1, y );
heartShape.bezierCurveTo( x + 0.7, y, x + 0.5, y + 0.5, x + 0.5, y + 0.5 );const geometry = new THREE.ShapeGeometry( heartShape );
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const mesh = new THREE.Mesh( geometry, material ) ;
scene.add( mesh );

 

这篇关于Three.js学习10:几何体(1)-平面几何体的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/723390

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

JS常用组件收集

收集了一些平时遇到的前端比较优秀的组件,方便以后开发的时候查找!!! 函数工具: Lodash 页面固定: stickUp、jQuery.Pin 轮播: unslider、swiper 开关: switch 复选框: icheck 气泡: grumble 隐藏元素: Headroom

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识