创建胶囊体和甜圈圈(three.js实战8)

编程入门 行业动态 更新时间:2024-10-25 05:15:53

创建<a href=https://www.elefans.com/category/jswz/34/1697061.html style=胶囊体和甜圈圈(three.js实战8)"/>

创建胶囊体和甜圈圈(three.js实战8)

创建胶囊体和甜圈圈

  • 1. demo效果
  • 2. 实现过程
    • 2.1 实现原理
    • 2.2 绘制胶囊体
    • 2.3 绘制甜圈圈
  • 3 demo代码

1. demo效果



2. 实现过程

2.1 实现原理

完全对称的几何体可以通过一条样条曲线,扫描360度创建几何体。three.js提供的LatheGeometry类,只需要提供样条曲线的点集,就可以创建出demo中的几何体。

2.2 绘制胶囊体


上图为绘制胶囊体原理图
绘制胶囊体的样条曲线分为三部分,上半部分四分之一圆弧,中间一条直线,下半部分四分之一圆,接下来看看绘制过程

// 创建胶囊体
function createCapsule() {const radius = 4;const height = 18;// 存放样条曲线的点集const points = []//上半部分四分之一圆弧for (let i = Math.PI / 2; i > 0; i -= 0.1) {points.push(new THREE.Vector3(Math.cos(i) * radius,Math.sin(i) * radius + height / 2,0))}//中间直线for (let i = height / 2; i > -height / 2; i -= 0.1) {points.push(new THREE.Vector3(radius,i,0))}//下半部分四分之一圆弧for (let i = 0; i <= Math.PI / 2; i += 0.1) {points.push(new THREE.Vector3(Math.cos(i) * radius,-Math.sin(i) * radius - height / 2,0))}// 补充一个点,去掉底部的小洞洞points.push(new THREE.Vector3(0,-radius - height / 2,0))// 根据样条曲线创建扫描几何体const geom = new THREE.LatheGeometry(points,200,0,Math.PI * 2)// 创建材质const meshMaterial = new THREE.MeshPhongMaterial({side: THREE.DoubleSide,color: 0xfff000})const mesh = new THREE.Mesh(geom, meshMaterial)// 网格对象添加到场景中scene.add(mesh)
}

2.3 绘制甜圈圈


上图为绘制甜圈圈原理图
绘制甜圈圈的样条曲线就是一个圆,然后环绕Y轴旋转一周就可以绘制出几何体,具体如下

function createDoughnut() {const Radius = 10;const radius = 4;const height = 12;//绘制一个圆const curve = new THREE.EllipseCurve(0, 0, // ax, aYradius, radius, // xRadius, yRadius0, Math.PI * 2, // aStartAngle, aEndAnglefalse, // aClockwise0 // aRotation);const innerCirclePoints = curve.getPoints(100)// 存放样条曲线的点集const points = []innerCirclePoints.forEach(point => {point.x = point.x + Radiuspoints.push(point)})//根据样条曲线创建扫描几何体const geom = new THREE.LatheGeometry(points,200,0,Math.PI * 2)// 创建材质const meshMaterial = new THREE.MeshPhongMaterial({color: 0x318eff,side: THREE.DoubleSide})const mesh = new THREE.Mesh(geom, meshMaterial)mesh.position.x = 30//添加到场景中scene.add(mesh)
}

3 demo代码

<!DOCTYPE html><html><head><title>Example latheGeometry</title><script type="text/javascript" src="../three/build/three.js"></script><script type="text/javascript" src="../three/examples/js/controls/OrbitControls.js"></script><script type="text/javascript" src="../three/examples/js/libs/stats.min.js"></script><style>body {margin: 0;overflow: hidden;}</style>
</head><body><div id="Stats-output"></div><div id="WebGL-output"></div><script type="text/javascript">let stats, controls;let camera, scene, renderer;function initScene() {scene = new THREE.Scene();//用一张图加载为纹理作为场景背景scene.background = new THREE.TextureLoader().load("../assets/textures/starry-deep-outer-space-galaxy.jpg")}function initCamera() {camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 1, 20000);camera.position.set(20, 50, 100);}function initLight() {//添加环境光var ambientLight = new THREE.AmbientLight(0xffffff);scene.add(ambientLight);var spotLight = new THREE.SpotLight(0xffffff);spotLight.position.set(25, 30, 50);spotLight.castShadow = true;scene.add(spotLight);}function initModel() {createCapsule();createDoughnut();}// 创建胶囊体function createCapsule() {const radius = 4;const height = 18;// 存放样条曲线的点集const points = []//上半部分四分之一圆弧for (let i = Math.PI / 2; i > 0; i -= 0.1) {points.push(new THREE.Vector3(Math.cos(i) * radius,Math.sin(i) * radius + height / 2,0))}//中间直线for (let i = height / 2; i > -height / 2; i -= 0.1) {points.push(new THREE.Vector3(radius,i,0))}//下半部分四分之一圆弧for (let i = 0; i <= Math.PI / 2; i += 0.1) {points.push(new THREE.Vector3(Math.cos(i) * radius,-Math.sin(i) * radius - height / 2,0))}// 补充一个点,去掉底部的小洞洞points.push(new THREE.Vector3(0,-radius - height / 2,0))// 根据样条曲线创建扫描几何体const geom = new THREE.LatheGeometry(points,200,0,Math.PI * 2)// 创建材质const meshMaterial = new THREE.MeshPhongMaterial({side: THREE.DoubleSide,color: 0xfff000})const mesh = new THREE.Mesh(geom, meshMaterial)// 网格对象添加到场景中scene.add(mesh)}function createDoughnut() {const Radius = 10;const radius = 4;const height = 12;//绘制一个圆const curve = new THREE.EllipseCurve(0, 0, // ax, aYradius, radius, // xRadius, yRadius0, Math.PI * 2, // aStartAngle, aEndAnglefalse, // aClockwise0 // aRotation);const innerCirclePoints = curve.getPoints(100)// 存放样条曲线的点集const points = []innerCirclePoints.forEach(point => {point.x = point.x + Radiuspoints.push(point)})//根据样条曲线创建扫描几何体const geom = new THREE.LatheGeometry(points,200,0,Math.PI * 2)// 创建材质const meshMaterial = new THREE.MeshPhongMaterial({color: 0x318eff,side: THREE.DoubleSide})const mesh = new THREE.Mesh(geom, meshMaterial)mesh.position.x = 30//添加到场景中scene.add(mesh)}function initRender() {renderer = new THREE.WebGLRenderer({antialias: true,alpha: true})//renderer.shadowMap.enabled = true // 显示阴影renderer.setPixelRatio(window.devicePixelRatio);renderer.setSize(window.innerWidth, window.innerHeight);renderer.setClearColor(0x0f2d48); //设置背景色renderer.toneMapping = THREE.ACESFilmicToneMapping;document.getElementById("WebGL-output").appendChild(renderer.domElement);}//初始化轨道控制器function initControls() {clock = new THREE.Clock() // 创建THREE.Clock对象,用于计算上次调用经过的时间controls = new THREE.OrbitControls(camera, renderer.domElement)//controls.autoRotate = true // 是否自动旋转}function initStats() {stats = new Stats();stats.setMode(0); // 0: fps, 1: msdocument.getElementById("Stats-output").appendChild(stats.domElement);}function render() {updateFun()requestAnimationFrame(render);renderer.render(scene, camera);}function updateFun() {stats.update();const delta = clock.getDelta() // 获取自上次调用的时间差controls.update(delta) // 相机更新}//初始化function init() {initScene();initCamera();initLight();initRender();initStats();initControls();initModel();render();}window.onload = init;</script>
</body></html>

更多推荐

创建胶囊体和甜圈圈(three.js实战8)

本文发布于:2024-03-08 06:57:43,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1720133.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:胶囊   圈圈   实战   js

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!