three.js基础之Curve、Geometry

为了便于后面的学习封装了几个初始化的函数

import {
  WebGLRenderer,
  PerspectiveCamera,
  AmbientLight,
  SpotLight,
  PointLight,
  DirectionalLight,
  PlaneGeometry,
  BoxGeometry,
  SphereGeometry,
  CylinderGeometry,
  MeshLambertMaterial,
  MeshBasicMaterial,
  MeshStandardMaterial,
  Mesh,
} from "three";

function initRenderer(domId, width = window.innerWidth, height = window.innerHeight) {
  const renderer = new WebGLRenderer({
    canvas: document.getElementById(domId),
    antialias: true,
  });
  renderer.setClearColor(0x000000);
  renderer.setSize(width, height);
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.shadowMap.enabled = true;
  return renderer;
}

function initPerspectiveCamera(params = {}) {
  const fov = "fov" in params ? params["fov"] : 45;
  const aspect = "aspect" in params ? params["aspect"] : window.innerWidth / window.innerHeight;
  const near = "near" in params ? params["near"] : 0.1;
  const far = "far" in params ? params["far"] : 1000;

  const camera = new PerspectiveCamera(fov, aspect, near, far);
  camera.position.set(-30, 30, 30);
  camera.lookAt(0, 0, 0);
  return camera;
}

function initAmbientLight(params = {}) {
  const color = "color" in params ? params["color"] : 0xffffff;
  const intensity = "intensity" in params ? params["intensity"] : 1;

  const ambienLight = new AmbientLight(color, intensity);
  return ambienLight;
}

function initSpotLight(params = {}) {
  const color = "color" in params ? params["color"] : 0xffffff;
  const intensity = "intensity" in params ? params["intensity"] : 20;
  const distance = "distance" in params ? params["distance"] : 0;
  const angle = "angle" in params ? params["angle"] : Math.PI / 3;
  const penumbra = "penumbra" in params ? params["penumbra"] : 0;
  const decay = "decay" in params ? params["decay"] : 0.5;

  const spotLight = new SpotLight(color, intensity, distance, angle, penumbra, decay);
  spotLight.position.set(-30, 30, -30);
  spotLight.castShadow = true;
  return spotLight;
}

function initPointLight(params = {}) {
  const color = "color" in params ? params["color"] : 0xffffff;
  const intensity = "intensity" in params ? params["intensity"] : 5;
  const distance = "distance" in params ? params["distance"] : 0;
  const decay = "decay" in params ? params["decay"] : 0.5;

  const pointLight = new PointLight(color, intensity, distance, decay);
  pointLight.castShadow = true;
  pointLight.position.set(-30, 30, -30);
  return ambienLight;
}

function initDirectionalLight(params = {}) {
  const color = "color" in params ? params["color"] : 0xffffff;
  const intensity = "intensity" in params ? params["intensity"] : 5;

  const directionalLight = new DirectionalLight(color, intensity);
  directionalLight.position.set(-30, 30, -30);
  directionalLight.castShadow = true;
  return directionalLight;
}

function addPlane(params = {}) {
  const color = "color" in params ? params["color"] : 0xffffff;
  const width = "width" in params ? params["width"] : 60;
  const height = "height" in params ? params["height"] : 40;

  const planeGeometry = new PlaneGeometry(width, height);
  const planeMaterial = new MeshLambertMaterial({
    color: color,
  });
  const plane = new Mesh(planeGeometry, planeMaterial);
  plane.receiveShadow = true;
  plane.rotation.x = -0.5 * Math.PI;
  plane.position.set(0, 0, 0);
  return plane;
}

function addBox(params = {}) {
  const color = "color" in params ? params["color"] : 0xffffff;
  const width = "width" in params ? params["width"] : 5;
  const height = "height" in params ? params["height"] : 3;
  const depth = "depth" in params ? params["depth"] : 2;

  const box = new Mesh(
    new BoxGeometry(width, height, depth),
    new MeshLambertMaterial({
      color: color,
    })
  );
  box.position.set(0, 0, 0);
  box.castShadow = true;
  return box;
}

function addSphere(params = {}) {
  const color = "color" in params ? params["color"] : 0xffffff;
  const radius = "radius" in params ? params["radius"] : 3;

  const sphere = new Mesh(
    new SphereGeometry(radius),
    new MeshLambertMaterial({
      color: color,
    })
  );
  sphere.position.set(0, 0, 0);
  sphere.castShadow = true;
  return sphere;
}

function addCylinder(params = {}) {
  const color = "color" in params ? params["color"] : 0xffffff;
  const tRadius = "tr" in params ? params["tr"] : 3;
  const bRadius = "br" in params ? params["br"] : 3;
  const height = "height" in params ? params["height"] : 10;

  const cylinder = new Mesh(
    new CylinderGeometry(tRadius, bRadius, height),
    new MeshLambertMaterial({
      color: color,
    })
  );
  cylinder.castShadow = true;
  cylinder.position.set(0, 0, 0);
  return cylinder;
}

function addMaterialObjects(scene, gui, controls, meshMaterial) {
  const groundGeom = new PlaneGeometry(100, 100, 4, 4);
  const groundMesh = new Mesh(
    groundGeom,
    new MeshBasicMaterial({
      color: 0x777777,
    })
  );
  groundMesh.rotation.x = -Math.PI / 2;
  groundMesh.position.y = -20;
  scene.add(groundMesh);

  const sphereGeometry = new SphereGeometry(14, 20, 20);
  const cubeGeometry = new BoxGeometry(15, 15, 15);
  const planeGeometry = new PlaneGeometry(14, 14, 4, 4);
  const sphere = new Mesh(sphereGeometry, meshMaterial);
  const cube = new Mesh(cubeGeometry, meshMaterial);
  const plane = new Mesh(planeGeometry, meshMaterial);
  sphere.position.set(0, 3, 2);
  cube.position.copy(sphere.position);
  plane.position.copy(sphere.position);
  scene.add(cube);

  controls.select = cube;
  gui.add(controls, "selectedMesh", ["cube", "sphere", "plane"]).onChange(function (e) {
    scene.remove(plane);
    scene.remove(cube);
    scene.remove(sphere);

    switch (e) {
      case "cube":
        scene.add(cube);
        controls.select = cube;
        break;
      case "sphere":
        scene.add(sphere);
        controls.select = sphere;
        break;
      case "plane":
        scene.add(plane);
        controls.select = plane;
        break;
    }
  });
}

export {
  initRenderer,
  initPerspectiveCamera,
  initAmbientLight,
  initSpotLight,
  initPointLight,
  initDirectionalLight,
  addPlane,
  addBox,
  addSphere,
  addCylinder,
  addMaterialObjects,
};

Curve、Shape、BufferGeometry

共用的初始化方法

<canvas id="EllipseCurve"></canvas>
<canvas id="ArcCurve"></canvas>
<canvas id="CurvePath"></canvas>
<canvas id="SplineCurve-CatmullRomCurve3"></canvas>
<canvas id="QuadraticBezierCurve-CubicBezierCurve"></canvas>
<canvas id="QuadraticBezierCurve3-CubicBezierCurve3"></canvas>
<canvas id="Shape"></canvas>
<canvas id="BufferGeometry"></canvas>
<canvas id="EdgesGeometry"></canvas>
<script type="importmap">
  {
    "imports": {
      "three": "./js/build/three.module.js",
      "three/addons/": "./js/jsm/"
    }
  }
</script>
<script type="module">
  import * as THREE from "three";import { initRenderer, initPerspectiveCamera, initAmbientLight } from "./init.js";

  function init(domId, callback) {
    const width = 300;
    const height = 200;
    const renderer = initRenderer(domId, width, height);

    const scene = new THREE.Scene();

    const camera = initPerspectiveCamera({ aspect: width / height });
    scene.add(camera);

    const ambientLight = initAmbientLight();
    scene.add(ambientLight);

    const axesHelper = new THREE.AxesHelper(150);
    scene.add(axesHelper);

    callback(scene);

    renderer.render(scene, camera);
  }
</script>

EllipseCurve

  init("EllipseCurve", (scene) => {
    // 椭圆曲线, 参数:椭圆的中心的X坐标、椭圆的中心的Y坐标、X轴向上椭圆的半径、Y轴向上椭圆的半径、以弧度来表示从正X轴算起曲线开始的角度、
    // 以弧度来表示从正X轴算起曲线终止的角度、椭圆是否按照顺时针方向来绘制
    const ellipse = new THREE.EllipseCurve(0, 0, 5, 3, 0, 2 * Math.PI, false);
    const pointsArr = ellipse.getPoints(20); //分段数20,返回21个顶点
    const pointsArr2 = ellipse.getSpacedPoints(20); //按照曲线长度等间距返回顶点数据

    const geometry = new THREE.BufferGeometry();
    geometry.setFromPoints(pointsArr); //读取坐标数据赋值给几何体顶点
    const geometry2 = new THREE.BufferGeometry();
    geometry2.setFromPoints(pointsArr2);
    const lineMaterial = new THREE.LineBasicMaterial({
      color: 0xffffff,
    });
    const line = new THREE.Line(geometry, lineMaterial); // 线模型
    line.position.set(0, -5, 0);
    const line2 = new THREE.Line(geometry2, lineMaterial);
    line2.position.set(0, 5, 0);
    scene.add(line);
    scene.add(line2);

    const pointsMaterial = new THREE.PointsMaterial({
      color: 0xffffff,
      size: 1,
    });
    const points = new THREE.Points(geometry, pointsMaterial); // 点模型
    const points2 = new THREE.Points(geometry2, pointsMaterial);
    points.position.set(15, -5, 0);
    points2.position.set(15, 5, 0);
    scene.add(points);
    scene.add(points2);
  });

ArcCurve

 init("ArcCurve", (scene) => {
    // 弧线, 参数:弧线的中心的X坐标、弧线的中心的Y坐标、弧线的半径、以弧度来表示从正X轴算起曲线开始的角度、
    // 以弧度来表示从正X轴算起曲线终止的角度、弧线是否按照顺时针方向来绘制
    const arc = new THREE.ArcCurve(0, 0, 5, 0, 1.5 * Math.PI, false);
    const pointsArr = arc.getPoints(10);
    const geometry = new THREE.BufferGeometry();
    geometry.setFromPoints(pointsArr);
    const material = new THREE.LineBasicMaterial({
      color: 0xffffff,
    });
    const line = new THREE.Line(geometry, material);
    scene.add(line);
  });

CurvePath

  init("CurvePath", (scene) => {
    const R = 2;
    const H = 10;
    const line1 = new THREE.LineCurve(new THREE.Vector2(R, H), new THREE.Vector2(R, 0));
    const arc = new THREE.ArcCurve(0, 0, R, 0, Math.PI, true);
    const line2 = new THREE.LineCurve(new THREE.Vector2(-R, 0), new THREE.Vector2(-R, H));
    //组合曲线
    const curvePath = new THREE.CurvePath();
    curvePath.curves.push(line1, arc, line2);
    const pointsArr = curvePath.getPoints(20);
    const geometry = new THREE.BufferGeometry();
    geometry.setFromPoints(pointsArr);
    const material = new THREE.LineBasicMaterial({
      color: 0xffffff,
    });
    const line = new THREE.Line(geometry, material);
    line.position.set(0, 0, 0);
    scene.add(line);
  });

SplineCurve、CatmullRomCurve3

 init("SplineCurve-CatmullRomCurve3", (scene) => {
    const arr_2 = [new THREE.Vector2(-5, 0), new THREE.Vector2(0, 3), new THREE.Vector2(5, 0)];
    // 二维样条曲线,从一系列的点中创建一个平滑的二维样条曲线
    const curve_2 = new THREE.SplineCurve(arr_2);
    const pointsArr_2 = curve_2.getPoints(20);
    const geometry_2 = new THREE.BufferGeometry();
    geometry_2.setFromPoints(pointsArr_2);
    const material = new THREE.LineBasicMaterial({
      color: 0x99ffff,
    });
    const line_2 = new THREE.Line(geometry_2, material);
    line_2.position.set(0, 5, 0);
    scene.add(line_2);

    const arr_3 = [new THREE.Vector3(-5, 0, 0), new THREE.Vector3(0, 3, 0), new THREE.Vector3(5, 0, 0), new THREE.Vector3(0, 0, 8), new THREE.Vector3(0, 0, 0)];
    // 三维样条曲线,从一系列的点创建一条平滑的三维样条曲线。
    const curve_3 = new THREE.CatmullRomCurve3(arr_3);
    const pointsArr_3 = curve_3.getPoints(20);
    const geometry_3 = new THREE.BufferGeometry();
    geometry_3.setFromPoints(pointsArr_3);
    const line_3 = new THREE.Line(geometry_3, material);
    line_3.position.set(0, -5, 0);
    scene.add(line_3);
  });

QuadraticBezierCurve、CubicBezierCurve

init("QuadraticBezierCurve-CubicBezierCurve", (scene) => {
    const p1 = new THREE.Vector2(-5, 0);
    const p2 = new THREE.Vector2(-2, 5);
    const p3 = new THREE.Vector2(2, 3);
    const p4 = new THREE.Vector2(5, 0);
    // 二维二次贝赛尔曲线, 由起点、终点和一个控制点所定义
    const curve_2 = new THREE.QuadraticBezierCurve(p1, p2, p4);
    const pointsArr_2 = curve_2.getPoints(50);
    const geometry_2 = new THREE.BufferGeometry();
    geometry_2.setFromPoints(pointsArr_2);
    const material = new THREE.LineBasicMaterial({
      color: 0x22ff00,
    });
    const line_2 = new THREE.Line(geometry_2, material);
    line_2.position.set(0, 5, 0);
    scene.add(line_2);

    // 二维三次贝赛尔曲线,由起点、终点和两个控制点所定义
    const curve_3 = new THREE.CubicBezierCurve(p1, p2, p3, p4);
    const pointsArr_3 = curve_3.getPoints(50);
    const geometry_3 = new THREE.BufferGeometry();
    geometry_3.setFromPoints(pointsArr_3);
    const material1 = new THREE.LineBasicMaterial({
      color: 0xffff00,
    });
    const line_3 = new THREE.Line(geometry_3, material1);
    line_3.position.set(0, -5, 0);
    scene.add(line_3);
  });

 

QuadraticBezierCurve3、CubicBezierCurve3

 init("QuadraticBezierCurve3-CubicBezierCurve3", (scene) => {
    const p1 = new THREE.Vector3(-8, 0, 0);
    const p2 = new THREE.Vector3(-4, 5, 0);
    const p3 = new THREE.Vector3(5, 5, 0);
    const p4 = new THREE.Vector3(8, 0, 5);
    // 三维二次贝赛尔曲线, 由起点、终点和一个控制点所定义
    const curve_2 = new THREE.QuadraticBezierCurve3(p1, p2, p4);
    const pointsArr_2 = curve_2.getPoints(50);
    const geometry_2 = new THREE.BufferGeometry();
    geometry_2.setFromPoints(pointsArr_2);
    const material = new THREE.LineBasicMaterial({
      color: 0x22ffff,
    });
    const line_2 = new THREE.Line(geometry_2, material);
    line_2.position.set(0, 5, 0);
    scene.add(line_2);

    // 三维三次贝赛尔曲线,由起点、终点和两个控制点所定义
    const curve_3 = new THREE.CubicBezierCurve3(p1, p2, p3, p4);
    const pointsArr_3 = curve_3.getPoints(50);
    const geometry_3 = new THREE.BufferGeometry();
    geometry_3.setFromPoints(pointsArr_3);
    const line_3 = new THREE.Line(geometry_3, material);
    line_3.position.set(0, -5, 0);
    scene.add(line_3);
  });

Shape

  init("Shape", (scene) => {
    // 平面多边形轮廓
    const shape = new THREE.Shape([new THREE.Vector2(-2, -2), new THREE.Vector2(-2, 2), new THREE.Vector2(2, 2), new THREE.Vector2(2, -2)]);
    const geometry = new THREE.ShapeGeometry(shape);
    const material = new THREE.MeshBasicMaterial({
      color: 0xffffff,
    });
    const mesh = new THREE.Mesh(geometry, material);
    scene.add(mesh);

    // 平面轮廓  arc
    const shape1 = new THREE.Shape();
    shape1.moveTo(0, 0);
    shape1.lineTo(3, 0); // 绘制直线线段
    shape1.arc(0, 0, 5, 0, Math.PI / 2); //圆心坐标是相对于当前currentPoint,而不是坐标原点
    shape1.lineTo(0, 5);
    const geometry1 = new THREE.ShapeGeometry(shape1);
    const material1 = new THREE.MeshBasicMaterial({
      color: 0xff0000,
      side: THREE.DoubleSide,
    });
    const mesh1 = new THREE.Mesh(geometry1, material1);
    mesh1.position.set(0, 10, 0);
    scene.add(mesh1);

    // 平面轮廓  absarc
    const shape2 = new THREE.Shape();
    shape1.moveTo(0, 0);
    shape2.lineTo(10, 0);
    shape2.absarc(10, 0, 5, 0, Math.PI / 2); // absarc圆心坐标不受到currentPoint影响,以坐标原点作为参考
    shape2.lineTo(0, 5);
    const path2_1 = new THREE.Path(); // 圆孔
    path2_1.absarc(2.5, 2.5, 2);
    const path2_2 = new THREE.Path(); // 圆孔
    path2_2.absarc(8, 2.5, 2);
    shape2.holes.push(path2_1, path2_2); //内孔轮廓分别放入holes属性中
    const geometry2 = new THREE.ShapeGeometry(shape2);
    const material2 = new THREE.MeshBasicMaterial({
      color: 0x0000ff,
      side: THREE.DoubleSide,
    });
    const mesh2 = new THREE.Mesh(geometry2, material2);
    mesh2.position.set(0, -10, 0);
    scene.add(mesh2);
  });

BufferGeometry


  init("BufferGeometry", (scene) => {
    const material = new THREE.LineBasicMaterial({
      color: 0xffffff,
    });

    const geometry1 = new THREE.BufferGeometry();
    const R = 2;
    const N = 5;
    const sp = (2 * Math.PI) / N;
    const arr = [];
    const cx = 2;
    const cy = 2;
    for (let i = 0; i < N; i++) {
      const angle = sp * i;
      const x = cx + R * Math.cos(angle);
      const y = cy + R * Math.sin(angle);
      arr.push(x, 0, y);
    }
    const vertices1 = new Float32Array(arr);
    const attribue1 = new THREE.BufferAttribute(vertices1, 3);
    geometry1.attributes.position = attribue1;
    const line1 = new THREE.LineLoop(geometry1, material);
    scene.add(line1);

    const geometry2 = new THREE.BufferGeometry();
    // 三维向量表示的坐标值
    const pointsArr2 = [new THREE.Vector3(0, 0, 0), new THREE.Vector3(0, 3, 0), new THREE.Vector3(0, 3, 3), new THREE.Vector3(0, 0, 3)];
    geometry2.setFromPoints(pointsArr2);
    const line2 = new THREE.LineLoop(geometry2, material);
    scene.add(line2);

    const geometry3 = new THREE.BufferGeometry();
    // 二维向量表示的坐标值
    const pointsArr3 = [new THREE.Vector2(0, 0), new THREE.Vector2(5, 0), new THREE.Vector2(5, 5), new THREE.Vector2(0, 5)];
    geometry3.setFromPoints(pointsArr3);
    const line3 = new THREE.LineLoop(geometry3, material);
    scene.add(line3);
  });

EdgesGeometry

init("EdgesGeometry", (scene) => {
    // 平面轮廓  absarc
    const shape = new THREE.Shape();
    shape.lineTo(10, 0);
    shape.absarc(10, 0, 5, 0, Math.PI / 2);
    shape.lineTo(0, 5);
    const path1 = new THREE.Path(); // 圆孔
    path1.absarc(2, 2, 2);
    const path2 = new THREE.Path(); // 圆孔
    path2.absarc(8, 2, 2);
    shape.holes.push(path1, path2); //内孔轮廓分别放入holes属性中
    const geometry = new THREE.ExtrudeGeometry(shape, {
      depth: 2, //拉伸长度
      bevelEnabled: false, //禁止倒角
      curveSegments: 50,
    });
    const material = new THREE.MeshBasicMaterial({
      color: 0xffffff,
      side: THREE.DoubleSide,
    });
    const mesh = new THREE.Mesh(geometry, material);
    // 模型边界线EdgesGeometry
    const edges = new THREE.EdgesGeometry(geometry);
    const edgesMaterial = new THREE.LineBasicMaterial({
      color: 0x00ffff,
    });
    const line = new THREE.LineSegments(edges, edgesMaterial);
    mesh.add(line);
    scene.add(mesh);
  });

Geometry

<canvas id="geometry"></canvas>
<script type="importmap">
  {
    "imports": {
      "three": "./js/build/three.module.js",
      "three/addons/": "./js/jsm/"
    }
  }
</script>
<script type="module">
  import * as THREE from "three";
  import { TrackballControls } from "three/addons/controls/TrackballControls.js";
  import { createMultiMaterialObject } from "three/addons/utils/SceneUtils.js";
  import { ConvexGeometry } from "three/addons/geometries/ConvexGeometry.js";
  import { ParametricGeometry } from "three/addons/geometries/ParametricGeometry.js";
  import { ParametricGeometries } from "three/addons/geometries/ParametricGeometries.js";
  import { initRenderer, initPerspectiveCamera, initAmbientLight, initSpotLight, addPlane } from "./init.js";

  function init() {
    const renderer = initRenderer("geometry");

    const scene = new THREE.Scene();

    const camera = initPerspectiveCamera();
    scene.add(camera);

    const ambientLight = initAmbientLight();
    scene.add(ambientLight);

    const spotLight = initSpotLight();
    scene.add(spotLight);

    const axesHelper = new THREE.AxesHelper(150);
    scene.add(axesHelper);

    const plane = addPlane({ width: 100, height: 80 });
    plane.position.set(10, 0, 10);
    scene.add(plane);

    addGeometries(scene);

    const trackballControls = new TrackballControls(camera, renderer.domElement);
    const clock = new THREE.Clock();

    render();

    function render() {
      trackballControls.update(clock.getDelta());

      requestAnimationFrame(render);
      renderer.render(scene, camera);
    }

    function addGeometries(scene) {
      const geoms = [];

      //平面缓冲几何体,参数:平面沿着 X 轴的宽度,平面沿着 Y 轴的高度
      const planeGeometry = new THREE.PlaneGeometry(5, 3);
      planeGeometry.rotateX(-Math.PI / 2);
      geoms.push(planeGeometry);

      //圆形缓冲几何体,参数:圆形的半径
      const circleGeometry = new THREE.CircleGeometry(3);
      circleGeometry.rotateX(-Math.PI / 2);
      geoms.push(circleGeometry);

      // 形状缓冲几何体
      const pointsArr = [new THREE.Vector2(0, 0), new THREE.Vector2(3, 0), new THREE.Vector2(1, 2)];
      const shape = new THREE.Shape(pointsArr);
      geoms.push(new THREE.ShapeGeometry(shape));

      // 立方缓冲几何体,参数:X 轴上面的宽度、Y 轴上面的高度、Z 轴上面的深度
      geoms.push(new THREE.BoxGeometry(2, 2, 2));

      // 八面缓冲几何体,参数:八面体的半径
      geoms.push(new THREE.OctahedronGeometry(3));

      // 二十面缓冲几何体,参数:二十面体的半径
      geoms.push(new THREE.IcosahedronGeometry(3));

      // 四面缓冲几何体,参数:四面体的半径
      geoms.push(new THREE.TetrahedronGeometry(3));

      // 圆锥缓冲几何体,参数: 圆锥底部的半径、圆锥的高度
      geoms.push(new THREE.ConeGeometry(3, 2));

      // 球缓冲几何体,参数:球体半径
      geoms.push(new THREE.SphereGeometry(2));

      // 圆环缓冲几何体,参数:环面的半径(从环面的中心到管道横截面的中心)、管道的半径、管道横截面的分段数、管道的分段数
      geoms.push(new THREE.TorusGeometry(3, 1, 10, 10));

      // 圆环缓冲扭结几何体,参数:圆环的半径、管道的半径、管道的分段数量、横截面分段数量
      geoms.push(new THREE.TorusKnotGeometry(3, 0.5, 50, 20));

      // 圆柱缓冲几何体,参数:圆柱的顶部半径、圆柱的底部半径、圆柱的高度
      geoms.push(new THREE.CylinderGeometry(1, 4, 4));

      //胶囊缓冲几何体,参数:胶囊半径、中间区域的长度
      geoms.push(new THREE.CapsuleGeometry(1, 2));

      const pts = [];
      const detail = 0.1;
      const radius = 3;
      for (let angle = 0.0; angle < Math.PI; angle += detail) {
        pts.push(new THREE.Vector3(Math.cos(angle) * radius, 0, Math.sin(angle) * radius));
      }
      // 车削缓冲几何体
      geoms.push(new THREE.LatheGeometry(pts, 10));

      const p1 = new THREE.Vector3(0, 0, 2);
      const p2 = new THREE.Vector3(0, 0, 1);
      const p3 = new THREE.Vector3(0, 0, 0);
      const p4 = new THREE.Vector3(1, 0, 0);
      const p5 = new THREE.Vector3(2, 0, 0);
      const line1 = new THREE.LineCurve3(p1, p2);
      const curve = new THREE.QuadraticBezierCurve3(p2, p3, p4);
      const line2 = new THREE.LineCurve3(p4, p5);
      const curvePath = new THREE.CurvePath();
      curvePath.curves.push(line1, curve, line2);
      //管道几何体,参数:路径、沿着轨迹细分数、管道半径、管道截面圆细分数
      geoms.push(new THREE.TubeGeometry(curvePath, 3, 1, 5));

      const pointsArr1 = [new THREE.Vector2(-5, -5), new THREE.Vector2(-5, 5), new THREE.Vector2(5, 5), new THREE.Vector2(5, -5)];
      const shape1 = new THREE.Shape(pointsArr1);
      // 挤压缓冲几何体,参数:形状、参数对象
      geoms.push(new THREE.ExtrudeGeometry(shape1, { depth: 2 }));

      const shape2 = new THREE.Shape([new THREE.Vector2(0, 0), new THREE.Vector2(0, 3), new THREE.Vector2(3, 3), new THREE.Vector2(3, 0)]);
      const curve2 = new THREE.CatmullRomCurve3([new THREE.Vector3(-1, -2, -1), new THREE.Vector3(3, 0, 0), new THREE.Vector3(1, 4, 4), new THREE.Vector3(-2, 0, 5)]);
      // 挤压缓冲几何体
      const geometry = new THREE.ExtrudeGeometry(shape2, {
        extrudePath: curve2,
        steps: 100,
      });
      geoms.push(geometry);

      const points = [
        new THREE.Vector3(2, 2, 2),
        new THREE.Vector3(2, 2, -2),
        new THREE.Vector3(-2, 2, -2),
        new THREE.Vector3(-2, 2, 2),
        new THREE.Vector3(2, -2, 2),
        new THREE.Vector3(2, -2, -2),
        new THREE.Vector3(-2, -2, -2),
        new THREE.Vector3(-2, -2, 2),
      ];
      // 凸包几何体,可被用于为传入的一组点生成凸包
      geoms.push(new ConvexGeometry(points));

      // 参数化缓冲几何体,生成由参数表示其表面的几何体。
      geoms.push(new ParametricGeometry(ParametricGeometries.mobius3d, 20, 10));

      let j = 0;
      for (let i = 0; i < geoms.length; i++) {
        const materials = [
          new THREE.MeshLambertMaterial({
            color: Math.random() * 0xffffff,
          }),
          new THREE.MeshBasicMaterial({
            color: 0x000000,
            wireframe: true,
          }),
        ];

        //多种材质
        const mesh = createMultiMaterialObject(geoms[i], materials);
        mesh.traverse(function (e) {
          e.castShadow = true;
        });

        mesh.position.x = -24 + (i % 4) * 12;
        mesh.position.y = 4;
        mesh.position.z = -8 + j * 12;

        if ((i + 1) % 4 == 0) j++;
        scene.add(mesh);
      }
    }
  }

  init();
</script>

 

posted @ 2024-04-05 16:36  carol2014  阅读(51)  评论(0编辑  收藏  举报