vue+threejs创建各种线

1,224 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天,点击查看活动详情


写在前面

本文用vue+threejs创建各种线,包括二维路径、三维曲线、二维三次贝塞尔曲线、三维三次贝塞尔曲线、椭圆曲线、二维二次贝塞尔曲线、三维二次贝塞尔曲线、二维曲线。

代码说明

  1. threejs准备

准备一个id容器,用于插入渲染器节点。

引入threejs和额外需要的模块。

在mounted方法中调用initThreejs。

以下的代码都写在init方法中。

render方法用于渲染。

<template>
  <div class="item">
    <div id="THREE42"></div>
  </div>
</template>

import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";

mounted() {
    this.initThreejs();
},
initThreejs() {
    let camera, scene, renderer;

    init();
    
    function init() {
        //...
    }
    
    function render() {
        renderer.render(scene, camera);
    }
}

  1. 创建场景

创建场景并设置场景背景色为黑色(虽然默认就是黑色)

scene = new THREE.Scene();
scene.background = new THREE.Color(0x000000); // 设置场景背景颜色
  1. 创建灯光

创建一个平行光DirectionalLight,并设置平行光的方法

const light = new THREE.DirectionalLight(0xffffff); // 平行光
light.position.set(0.5, 1.0, 0.5).normalize(); // 设置平行光的方向,从(0.5, 1.0, 0.5)->target一般(0, 0, 0)
scene.add(light); // 将灯光添加到场景中
  1. 创建相机

创建一个透视相机PerspectiveCamera,并通过camera.position设置相机的位置

camera = new THREE.PerspectiveCamera(
  35,
  (window.innerWidth - 201) / window.innerHeight,
  1,
  500
); // 透视相机
camera.position.x = 36;
camera.position.y = 67; // 设置相机的位置
camera.position.z = 67;
scene.add(camera); // 将相机添加到场景中
  1. 创建渲染器

创建渲染器,并将渲染器节点插入到html中

renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.outputEncoding = THREE.sRGBEncoding;
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth - 201, window.innerHeight);
document.getElementById("THREE42").appendChild(renderer.domElement);
  1. 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);
controls.addEventListener("change", render);
controls.update();
  1. 创建坐标轴辅助线

红色代表x轴,绿色代表y轴,蓝色代表z轴

const axesHelper = new THREE.AxesHelper(5); // 红色x,绿色y,蓝色z
scene.add(axesHelper);
  1. 创建二维路径

创建的过程在代码中有清晰注释,下方图片白色部分就是创建的二维路径

const path = new THREE.Path();
path.lineTo(1, 1); // 从(0, 0)到(1, 1)
path.quadraticCurveTo(1, 5, 5, 5); // 创建一条二次曲线,以(1, 5)作为控制点,从(1, 1)画到(5, 5)。
path.lineTo(8, 5); // 从(5, 5)到(8, 5)
const linePoints = path.getPoints();
const lineGeometry = new THREE.BufferGeometry().setFromPoints(
  linePoints
); // 通过点队列设置该 BufferGeometry 的 attribute,以绘制图形。
const lineMaterial = new THREE.LineBasicMaterial({ color: 0xffffff }); // 绘制的路径为白色材质
const line = new THREE.Line(lineGeometry, lineMaterial); // 创建一条连续的线
scene.add(line); // 添加到场景中

1664505069583.png

  1. 使用Catmull-Rom算法, 从一系列的点创建一条平滑的三维曲线

THREE.CatmullRomCurve3(参数说明:三维点数组,该曲线是否闭合默认false,曲线的类型默认centripetal,曲线的张力默认0.5)

const curve = new THREE.CatmullRomCurve3([
  new THREE.Vector3(0, 10, 20),
  new THREE.Vector3(5, 15, 15),
  new THREE.Vector3(10, 10, 10),
  new THREE.Vector3(15, 5, 15),
  new THREE.Vector3(20, 10, 20),
]);
const curvePoints = curve.getPoints(50); // 50为要将曲线划分为的分段数
const curveGeometry = new THREE.BufferGeometry().setFromPoints(
  curvePoints
);
const curveMaterial = new THREE.LineBasicMaterial({ color: 0xff0000 }); // 红色材质
const curveObject = new THREE.Line(curveGeometry, curveMaterial);
scene.add(curveObject); // 添加到场景中

image.png

  1. 创建一条平滑的二维 三次贝塞尔曲线

该曲线由起点、终点和两个控制点所定义。

THREE.CubicBezierCurve(参数:起点,第一个控制点,第二个控制点,终点)

const bezierCurve = new THREE.CubicBezierCurve(
  new THREE.Vector2(-10, 0),
  new THREE.Vector2(-5, 15),
  new THREE.Vector2(20, 15),
  new THREE.Vector2(10, 0)
);
const bezierPoints = bezierCurve.getPoints(50);
const bezierGeometry = new THREE.BufferGeometry().setFromPoints(
  bezierPoints
);
const bezierMaterial = new THREE.LineBasicMaterial({ color: 0xff0000 }); // 红色材质
const bezierCurveObject = new THREE.Line(
  bezierGeometry,
  bezierMaterial
);
scene.add(bezierCurveObject); // 添加到场景中

image.png

  1. 创建一条平滑的三维 三次贝塞尔曲线

该曲线由起点、终点和两个控制点所定义。

CubicBezierCurve3(参数说明:起点,第一个控制点,第二个控制点,终点)

const bezierCurve3 = new THREE.CubicBezierCurve3(
  new THREE.Vector3(-10, 0, 20),
  new THREE.Vector3(-5, 15, 20),
  new THREE.Vector3(20, 15, 20),
  new THREE.Vector3(10, 0, 20)
);
const points = bezierCurve3.getPoints(50);
const geometry = new THREE.BufferGeometry().setFromPoints(points);
const material = new THREE.LineBasicMaterial({ color: 0xff0000 }); // 红色材质
const bezierCurve3Object = new THREE.Line(geometry, material);
scene.add(bezierCurve3Object); // 添加到场景中

image.png

  1. 创建椭圆曲线

THREE.EllipseCurve(参数:椭圆的中心的X坐标,椭圆的中心的Y坐标,X轴向上椭圆的半径,Y轴向上椭圆的半径,从正X轴算起曲线开始的角度,从正X轴算起曲线终止的角度,是否按照顺时针方向来绘制,椭圆从X轴正方向逆时针的旋转角度)

const ellipseCurve = new THREE.EllipseCurve(
  0,
  10, // ax, aY
  20,
  10, // xRadius, yRadius
  0,
  2 * Math.PI, // aStartAngle, aEndAngle
  false, // aClockwise
  0 // aRotation
);
const ellipsePoints = ellipseCurve.getPoints(50);
const ellipseGeometry = new THREE.BufferGeometry().setFromPoints(
  ellipsePoints
);
const ellipseMaterial = new THREE.LineBasicMaterial({
  color: 0x00ff00,
}); // 绿色材质
const ellipse = new THREE.Line(ellipseGeometry, ellipseMaterial);
scene.add(ellipse); // 添加到场景中

image.png

  1. 创建一条平滑的二维 二次贝塞尔曲线

该曲线由起点、终点和一个控制点所定义

THREE.QuadraticBezierCurve(参数说明:起点,控制点,终点)

const quadraticBezierCurve = new THREE.QuadraticBezierCurve(
  new THREE.Vector2(-10, 0),
  new THREE.Vector2(20, 15),
  new THREE.Vector2(10, 0)
);
const quadraticBezierPoints = quadraticBezierCurve.getPoints(50);
const quadraticBezierGeometry =
  new THREE.BufferGeometry().setFromPoints(quadraticBezierPoints);
const quadraticBezierMaterial = new THREE.LineBasicMaterial({
  color: 0x0000ff,
}); // 蓝色材质
const quadraticBezierCurveObject = new THREE.Line(
  quadraticBezierGeometry,
  quadraticBezierMaterial
);
scene.add(quadraticBezierCurveObject); // 添加到场景中

image.png 14. 创建一条平滑的三维 二次贝塞尔曲线

该曲线由起点、终点和一个控制点所定义

THREE.QuadraticBezierCurve3(参数说明:起点,控制点,终点)

const quadraticBezierCurve3 = new THREE.QuadraticBezierCurve3(
  new THREE.Vector3(-10, 0, 20),
  new THREE.Vector3(20, 15, 20),
  new THREE.Vector3(10, 0, 20)
);
const quadraticBezier3points = quadraticBezierCurve3.getPoints(50);
const quadraticBezier3Geometry =
  new THREE.BufferGeometry().setFromPoints(quadraticBezier3points);
const quadraticBezier3Material = new THREE.LineBasicMaterial({
  color: 0x0000ff,
}); // 蓝色材质
const quadraticBezierCurve3Object = new THREE.Line(
  quadraticBezier3Geometry,
  quadraticBezier3Material
);
scene.add(quadraticBezierCurve3Object); // 添加到场景中

image.png

  1. 从一系列的点中,创建一个平滑的二维样条曲线

SplineCurve(定义曲线的Vector2点的数组)

const splineCurve = new THREE.SplineCurve([
  new THREE.Vector2(0, 10),
  new THREE.Vector2(5, 15),
  new THREE.Vector2(10, 10),
  new THREE.Vector2(15, 5),
  new THREE.Vector2(20, 10),
]);
const splinePoints = splineCurve.getPoints(50);
const splineGeometry = new THREE.BufferGeometry().setFromPoints(
  splinePoints
);
const splineMaterial = new THREE.LineBasicMaterial({ color: 0xffff00 });
const splineObject = new THREE.Line(splineGeometry, splineMaterial);
scene.add(splineObject); // 添加到场景中

image.png

写在最后

以上就是所有的代码和说明。