如何使用Three.js构造圆角矩形立方体

一、构造圆角矩形

方法一:使用canvas自带绘制曲线方法

canvas中曲线的绘制可以通过三种自带的方法:

  • 圆弧:arc
  • 二次贝塞尔曲线:quadraticCurveTo(x2, y2, x3, y3) // 操作点与终点
  • 贝塞尔曲线:bezierCurveTo(x1,y1,x2,y2,x,y) // 操作点1、操作点2与终点
// 例:绘制圆角矩形
const shape = new THREE.Shape()
shape.moveTo(-50, -40)
shape.quadraticCurveTo(-50, -50, -40, -50)
shape.lineTo(40, -50)
shape.quadraticCurveTo(50, -50, 50, -40)
shape.lineTo(50, 40)
shape.quadraticCurveTo(50, 50, 40, 50)
shape.lineTo(-40, 50)
shape.quadraticCurveTo(-50, 50, -50, 40)
shape.lineTo(-50, -40)

💡 该方法的缺点在于无法控制曲线上的点数,因此也无法控制矩形的面片数。在圆角较多的情况下会导致面片数激增。

方法二:使用计算出来的点位绘制曲线

由于计算机绘制曲线,实际上是通过获取曲线上的点进行连接获得的,点越多曲线越平滑,效果越好。因此我们通过该原理自行计算曲线上的点位。

// height 矩形长 width 矩形宽 radius 圆角半径 length 圆角段数
function drawShape(height, width, radius, length) {
	const shape = new THREE.Shape()
	shape.moveTo(0, width - radius)
	shape.lineTo(0, radius)
	for (let i = 1; i <= length; i++) {
		let a = Math.sin((Math.PI / length / 2) * i) * radius
		let b = Math.cos((Math.PI / length / 2) * i) * radius
		shape.lineTo(radius - b, radius - a)
	}
	shape.lineTo(height - radius, 0)
	for (let i = 1; i <= length; i++) {
		let a = Math.sin((Math.PI / length / 2) * i) * radius
		let b = Math.cos((Math.PI / length / 2) * i) * radius
		shape.lineTo(height - radius + a, radius - b)
	}
	shape.lineTo(height, width - radius)
	for (let i = 1; i <= length; i++) {
		let a = Math.sin((Math.PI / length / 2) * i) * radius
		let b = Math.cos((Math.PI / length / 2) * i) * radius
		shape.lineTo(height - radius + b, width - radius + a)
	}
	shape.lineTo(radius, width)
	for (let i = 1; i <= length; i++) {
		let a = Math.sin((Math.PI / length / 2) * i) * radius
		let b = Math.cos((Math.PI / length / 2) * i) * radius
		shape.lineTo(radius - a, width - radius + b)
	}
	return shape
}

通过这种方法我们可以自由的增加或减少面片数,以更少的面片数达到理想的效果。

const geometry = new THREE.ShapeGeometry(shape)
const material = new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true })
// 可以通过 wireframe 属性观察面片数
let mesh = new THREE.Mesh(geometry, material)
scene.add(mesh)

二、挤压生成立方体

使用Three.js库中的挤压缓冲几何体(ExtrudeGeometry)生成立方体。

const curve = new THREE.CatmullRomCurve3([new THREE.Vector3(0,0,0),new THREE.Vector3(0,0,1)])
const extrudeSettings = {
	steps: 1, // 细分的点的数量(值越小面片数越少)
	bevelEnabled: false, // 是否斜角
	extrudePath: curve // 挤压路径
}
const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings)
const material = new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true })
const mesh = new THREE.Mesh(geometry, material)
scene.add(mesh)

💡 此处的curve可用任意曲线方法构造,如果不能使用CatmullRomCurve3方法,也可使用完整代码中使用的LineCurve3方法。

 三、完整代码

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Title</title>
    <style type="text/css">
      html,
      body {
        margin: 0;
        height: 100%;
      }

      canvas {
        display: block;
      }
    </style>
  </head>
  <body onload="draw();"></body>
  <script src="http://www.yanhuangxueyuan.com/3D/example/three.js"></script>
  <script src="http://www.yanhuangxueyuan.com/versions/threejsR92/build/three.js"></script>
  <script>
    var renderer
    function initRender() {
      renderer = new THREE.WebGLRenderer({ antialias: true })
      renderer.setSize(window.innerWidth, window.innerHeight)
      document.body.appendChild(renderer.domElement)
    }

    var camera
    function initCamera() {
      camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000)
      camera.position.set(70, 100, 100)
      camera.lookAt(new THREE.Vector3(0, 0, 0))
    }

    var scene
    function initScene() {
      scene = new THREE.Scene()
    }

    var light
    function initLight() {
      scene.add(new THREE.AmbientLight(0x444444))
      light = new THREE.SpotLight(0xffffff)
      light.position.set(60, 30, 0)
      scene.add(light)
    }

    function initModel() {
      //辅助工具
      var helper = new THREE.AxesHelper(100)
      scene.add(helper)

      const shape = drawShape(50, 30, 10, 5)
      const curve = new THREE.LineCurve3(new THREE.Vector3(0, 0, 0), new THREE.Vector3(0, 4, 0))
      const extrudeSettings = {
        bevelEnabled: false,
        extrudePath: curve
      }

      const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings)
      const material = new THREE.MeshPhongMaterial({ color: 0xff0000, wireframe: false })
      const mesh = new THREE.Mesh(geometry, material)
      scene.add(mesh)
    }
    function drawShape(height, width, radius, length) {
      const shape = new THREE.Shape()
      shape.moveTo(0, width - radius)
      shape.lineTo(0, radius)
      for (let i = 1; i <= length; i++) {
        let a = Math.sin((Math.PI / length / 2) * i) * radius
        let b = Math.cos((Math.PI / length / 2) * i) * radius
        shape.lineTo(radius - b, radius - a)
      }
      shape.lineTo(height - radius, 0)
      for (let i = 1; i <= length; i++) {
        let a = Math.sin((Math.PI / length / 2) * i) * radius
        let b = Math.cos((Math.PI / length / 2) * i) * radius
        shape.lineTo(height - radius + a, radius - b)
      }
      shape.lineTo(height, width - radius)
      for (let i = 1; i <= length; i++) {
        let a = Math.sin((Math.PI / length / 2) * i) * radius
        let b = Math.cos((Math.PI / length / 2) * i) * radius
        shape.lineTo(height - radius + b, width - radius + a)
      }
      shape.lineTo(radius, width)
      for (let i = 1; i <= length; i++) {
        let a = Math.sin((Math.PI / length / 2) * i) * radius
        let b = Math.cos((Math.PI / length / 2) * i) * radius
        shape.lineTo(radius - a, width - radius + b)
      }
      return shape
    }
    function render() {
      renderer.render(scene, camera)
    }

    function animate() {
      //更新控制器
      render()
      requestAnimationFrame(animate)
    }

    function draw() {
      initRender()
      initScene()
      initCamera()
      initLight()
      initModel()
      animate()
    }
  </script>
</html>

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
three.js是一个用于创建3D图形的JavaScript库。它提供了丰富的功能和工具,可以轻松地在Web浏览器中创建交互式的3D场景和动画效果。 渐变圆边立方体是指一个立方体,其边缘呈现出渐变的圆形效果。在three.js中,可以通过以下步骤来创建渐变圆边立方体: 1. 创建一个立方体的几何体(BoxGeometry)并设置其大小和位置。 2. 创建一个渐变材质(MeshBasicMaterial)并设置其颜色属性为渐变色。 3. 将几何体和材质结合起来创建一个网格(Mesh)对象。 4. 将网格对象添加到场景中。 5. 创建一个渲染器(WebGLRenderer)并将其连接到HTML文档中的一个元素上。 6. 在每一帧中更新场景和相机,并使用渲染器进行渲染。 下面是一个示例代码,展示了如何使用three.js创建一个渐变圆边立方体: ```javascript // 创建场景 var scene = new THREE.Scene(); // 创建相机 var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.z = 5; // 创建渲染器 var renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 创建立方体几何体 var geometry = new THREE.BoxGeometry(1, 1, 1); // 创建渐变材质 var material = new THREE.MeshBasicMaterial({ color: new THREE.Color(0xff0000), // 起始颜色 vertexColors: THREE.VertexColors // 使用顶点颜色 }); // 设置顶点颜色 geometry.faces.forEach(function(face) { var color = new THREE.Color(Math.random(), Math.random(), Math.random()); face.vertexColors.push(color, color, color); }); // 创建立方体网格 var cube = new THREE.Mesh(geometry, material); // 将立方体添加到场景中 scene.add(cube); // 渲染函数 function render() { requestAnimationFrame(render); // 旋转立方体 cube.rotation.x += 0.01; cube.rotation.y += 0.01; // 渲染场景和相机 renderer.render(scene, camera); } // 开始渲染 render(); ``` 这是一个基本的示例,你可以根据自己的需求进行修改和扩展。希望对你有所帮助!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值