写在前面:
本人南京邮电大学计算机学院大三菜鸟一枚,下面写出的方法,是自己查阅各种文档摸索出来的,记录在此。各位专业大佬多多包涵!
最近项目组有一个需求,需要在一根电线周围用圆柱体包裹作为警示区,结合自己对Three.js仅有的那么一丁点了解,我有了最开始的思路。
运用 CylinderGeometry 几何体做圆柱体,属性如下:
前两个参数是半径,这个可以自己定,第三个是圆柱体高度,自然就是两点间距离呗,有了这几个参数,圆柱体也就确定下来了。
接下来,就要确定圆柱体的位置。
Three.js中的几何体都是以几何中心来确定位置的,再加上一个旋转角度,通过一系列的计算(高中数学,我还去恶补了一下。。。),最终得到了想要的效果。
但是,我在查看文档的时候,又发现里另外一种途径,也可以实现同样的效果。
线向量到圆柱
这个方法主要运用到了
new THREE.Vector3().subVectors( pointY, pointX );
参考:
Find specific point between 2 points - three.js
Three.js 线向量到圆柱
ThreeJS两个点作为起始坐标画一个立方体
最后附上代码:
// 高程越界
addSkycheck(new THREE.Vector3(0, 0, 20), new THREE.Vector3(8, 8, 15));
//添加圆柱体
function addSkycheck(start, end) {
console.log(start);
// 计算长度
let dx = Math.abs(start.x - end.x);
let dy = Math.abs(start.y - end.y);
let dz = Math.abs(start.z - end.z);
let width = Math.sqrt(
Math.pow(dx, 2) + Math.pow(dy, 2) + Math.pow(dz, 2)
);
console.log(width);
var cylinder = createCylinderByTwoPoints(start, end);
scene.add(cylinder);
//画一条直线方便观察
var geometry3 = new THREE.Geometry();
geometry3.vertices.push(start);
geometry3.vertices.push(end);
var line = new THREE.Line(
geometry3,
new THREE.LineBasicMaterial({
color: "black",
}),
THREE.LineSegments
);
scene.add(line);
// 球体
let sphereGeometry_2_1 = new THREE.SphereGeometry(1, 100, 100);
let sphereGeometry_2_2 = new THREE.SphereGeometry(1, 100, 100);
let lineSegments_2_1 = new THREE.Mesh(
sphereGeometry_2_1,
new THREE.MeshBasicMaterial({
color: "red",
side: THREE.DoubleSide,
transparent: true,
opacity: 0.2,
})
);
let lineSegments_2_2 = new THREE.Mesh(
sphereGeometry_2_2,
new THREE.MeshBasicMaterial({
color: "red",
side: THREE.DoubleSide,
transparent: true,
opacity: 0.2,
})
);
objects.push(lineSegments_2_1);
lineSegments_2_1.position.x = start.x;
lineSegments_2_1.position.y = start.y;
lineSegments_2_1.position.z = start.z;
scene.add(lineSegments_2_1);
objects.push(lineSegments_2_2);
lineSegments_2_2.position.x = end.x;
lineSegments_2_2.position.y = end.y;
lineSegments_2_2.position.z = end.z;
scene.add(lineSegments_2_2);
}
// 根据两点画圆柱
function createCylinderByTwoPoints(pointX, pointY) {
var direction = new THREE.Vector3().subVectors(pointY, pointX);
var orientation = new THREE.Matrix4();
orientation.lookAt(pointX, pointY, new THREE.Object3D().up);
orientation.multiply(
new THREE.Matrix4().set(
1,0,0, 0,
0, 0, 1, 0,
0, -1, 0, 0,
0, 0, 0, 1
)
);
var edgeGeometry = new THREE.CylinderGeometry(
1, 1, direction.length(), 100, 100
);
var material = new THREE.MeshLambertMaterial({
color: "red",
side: THREE.DoubleSide,
transparent: true,
opacity: 0.2,
});
var edge = new THREE.Mesh(edgeGeometry, material);
edge.applyMatrix4(orientation);
//两个点的中心点 position based on midpoints - there may be a better solution than this
edge.position.x = (pointY.x + pointX.x) / 2;
edge.position.y = (pointY.y + pointX.y) / 2;
edge.position.z = (pointY.z + pointX.z) / 2;
return edge;
}