赞
踩
项目中有遇到这个问题,在这里记录一下
threejs没有提供类似函数,可以使用第三方库 three-line-2d
,three.meshline
。这库怎么使用我也没试过,后来才找到的。当时使用自己的方法处理了, 怎么使用可以看npm官网。
https://www.npmjs.com/package/three-line-2d
https://www.npmjs.com/package/three.meshline
线转面,只需要计算出线上的点在扩散后的位置即可,每个点会生成2个点,再将点连起来形成Shape。
只是简单处理了一下,不能拐弯处实现圆滑效果,直接上代码。
/** * 线拉伸成平面 * @param { {x: number, y: number}[] } points 点 * @param { number } radius 拉伸半径(宽度) * @returns { THREE.Vector2[] } */ export function createShapeFromPoints(points, radius = 1) { let left = []; let right = []; for (let i = 0, len = points.length; i < len; i++) { let prev = points[i - 1] || {}; let curr = points[i]; let next = points[i + 1] || {}; let v1 = [curr.x - prev.x, curr.y - prev.y]; let v2 = [next.x - curr.x, next.y - curr.y]; if (!prev.x && prev.x !== 0) { v1 = [...v2]; } else if (!next.x && next.x !== 0) { v2 = [...v1]; } let modelV1 = Math.sqrt(v1[0] ** 2 + v1[1] ** 2); let modelV2 = Math.sqrt(v2[0] ** 2 + v2[1] ** 2); // 单位向量 v1 = [v1[0] / modelV1, v1[1] / modelV1]; v2 = [v2[0] / modelV2, v2[1] / modelV2]; // 方向和的单位向量 let vector = [v1[0] + v2[0], v1[1] + v2[1]]; let modelVector = Math.sqrt(vector[0] ** 2 + vector[1] ** 2); vector = [vector[0] / modelVector, vector[1] / modelVector]; // 扩散点的方向和转角处的角度偏移 let Lvector = rotateVector(vector, -Math.PI / 2); let Rvector = rotateVector(vector, Math.PI / 2); let deflection = vectorAngleCosHalf(v1, v2); left.push( new THREE.Vector2( curr.x + Lvector[0] * (radius / deflection), curr.y + Lvector[1] * (radius / deflection) ) ); right.unshift( new THREE.Vector2( curr.x + Rvector[0] * (radius / deflection), curr.y + Rvector[1] * (radius / deflection) ) ); prev = curr; } return left.concat(right); } /** * 向量夹角的cos值 * @param { [number, number] } a * @param { [number, number] } b * @returns */ export function vectorAngleCos(a, b) { return ( (a[0] * b[0] + a[1] * b[1]) / (Math.sqrt(a[0] ** 2 + a[1] ** 2) * Math.sqrt(b[0] ** 2 + b[1] ** 2)) ); } /** * 向量夹角的一半的cos值 * @param { [number, number] } a * @param { [number, number] } b * @returns */ export function vectorAngleCosHalf(a, b) { return Math.sqrt((1 + vectorAngleCos(a, b)) / 2); } /** * 将点绕原点旋转 * @param { [number, number] } param0 * @param { number } angle * @returns { [number, number] } */ export function rotateVector([x1, y1], angle) { let x2 = x1 * Math.cos(angle) - y1 * Math.sin(angle); let y2 = y1 * Math.cos(angle) + x1 * Math.sin(angle); return [x2, y2]; }
使用
let line = [ { x: 0, y: 0 }, { x: 20, y: 40 }, { x: 40, y: 10 }, { x: 100, y: 100 }, ]; let points = createShapeFromPoints(line, 2); let shape = new THREE.Shape(points); let geometry = new THREE.ShapeGeometry(shape); let material = new THREE.LineBasicMaterial({ color: 0x7d5fff, transparent: true, opacity: 0.9, }); let line = new THREE.Mesh(geometry, material);
ok, 这样就得到line的Mesh了。
蓝色为原来的线,黑色是计算后的到的多边形points
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。