多边形轮廓创建封闭图形

56 阅读1分钟

实现效果:

9F269652-E96A-4C0B-A954-D940D8F7675B.png

实现思路:

每个面的组成都是有若干个三角形组成,最少两个,那我们可以通过绘制两个三角形组成一个面

1、先定义基本的点坐标集合

2、进行点连接绘制成面

3、循环遍历N个面围成多边形

代码实现:

// 该文件为modal.js
import * as THREE from "three";
const group = new THREE.Group();

const points = [0, 0, 60, 0, 60, 80, 40, 120, -20, 80, 0, 0];

const h = 20;

// 每个面都是由至少两个三角形组成,可通过上面的点坐标
const pointsArr = [];
for (let i = 0; i < points.length - 2; i += 2) {
  pointsArr.push(
    points[i],
    points[i + 1],
    0,
    points[i + 2],
    points[i + 3],
    0,
    points[i + 2],
    points[i + 3],
    h
  );
  pointsArr.push(
    points[i],
    points[i + 1],
    0,
    points[i + 2],
    points[i + 3],
    h,
    points[i],
    points[i + 1],
    h
  );
}
const geometry = new THREE.BufferGeometry();
geometry.attributes.position = new THREE.BufferAttribute(
  new Float32Array(pointsArr),
  3
);
const material = new THREE.MeshBasicMaterial({
  color: 0x00ffff,
  side: THREE.DoubleSide,
  wireframe: true, // 是否显示组成(三角形)
});

const mesh = new THREE.Mesh(geometry, material);

group.add(mesh);

export { group };

基础配置代码

import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
import { dLight, bLight, amLight } from "./frame.js";  // 光源设置文件
import { group } from "./modal.js";

const scene = new THREE.Scene();

scene.add(dLight, bLight, amLight);
scene.add(group);

const camera = new THREE.PerspectiveCamera(
  60,
  window.innerWidth / window.innerHeight,
  1,
  2000
);

camera.position.set(0, -182, 228);
camera.lookAt(20, 60, 10);

const renderer = new THREE.WebGLRenderer({
  antialias: true,
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.render(scene, camera);
document.body.appendChild(renderer.domElement);

function animation() {
  renderer.render(scene, camera);
  requestAnimationFrame(animation);
}
animation();

const controls = new OrbitControls(camera, renderer.domElement);

controls.addEventListener("change", () => {
  renderer.render(scene, camera);
});

controls.target.set(20, 60, 10);
controls.update();

window.onresize = () => {
  renderer.setSize(window.innerWidth, window.innerHeight);
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
};

export { camera, renderer, scene };