参考了,https://www.script-tutorials.com/webgl-with-three-js-lesson-11/
录屏用的GifCam,https://www.appinn.com/gifcam/
功能是给出一些线段,可以构造一个管道,可以分节。
稍微修改代码的arrow数组的生成方法,可以构造出弯的管道,依旧可以分节。不妨一试。
tubecreate.js
function n33(a){return [a.x, a.y, a.z];}
function v33(a){return new THREE.Vector3(a[0],a[1],a[2]);}
function mulx(a,b){return [a[1]*b[2]-a[2]*b[1], a[2]*b[0]-a[0]*b[2], a[0]*b[1]-a[1]*b[0]]}
function mul(a,b){return [a[0]*b, a[1]*b, a[2]*b];}
function add(a,b){return [a[0]+b[0], a[1]+b[1], a[2]+b[2]];}
function sub(a,b){return [a[0]-b[0], a[1]-b[1], a[2]-b[2]];}
function normalize(a){
var bb = 1/(a[0]**2 + a[1]**2 + a[2]**2)**0.5;
return mul(a,bb);}
function loadmod(scene) {
var detail_divide = 12;
var tube_seg_length = 33;
var tube_segment = 25;
var arrow=[], arrX=[], arrY=[], arrZ = [], rings = [], faces=[];
for(i=0;i<tube_segment;i++) arrow.push([i*tube_seg_length, 0,0]);
var arrX=[], arrY=[], arrZ=[];
var arrRing = [];
for(i=0;i<arrow.length-1;i++){
arrX.push(sub(arrow[i+1], arrow[i]));}
var ver1 = [1,1,1];
for(i=0;i<arrX.length;i++){
arrY.push( mul(normalize(mulx(ver1, arrX[i])), 50) );
arrZ.push( mul(normalize(mulx(arrX[i], arrY[i])), 50) );}
for(ii=0;ii<arrX.length;ii++){
for(i=0;i<detail_divide;i++){
var a=Math.sin(i*Math.PI*2/detail_divide);
var b=Math.cos(i*Math.PI*2/detail_divide);
rings.push(add(add(mul(arrY[ii],a),mul(arrZ[ii],b)), arrow[ii] ));}}
for(j=0;j<arrX.length-1;j+=2){
for(i=0;i<detail_divide-1;i++){
faces.push(add([j*detail_divide,j*detail_divide,j*detail_divide], [i+detail_divide, i+detail_divide+1, i]));
faces.push(add([j*detail_divide,j*detail_divide,j*detail_divide], [i, i+1, i+detail_divide+1]));
}
faces.push(add([j*detail_divide,j*detail_divide,j*detail_divide], [detail_divide*2-1, detail_divide, detail_divide-1]));
faces.push(add([j*detail_divide,j*detail_divide,j*detail_divide], [detail_divide-1, 0, detail_divide]));
}
var tube = new THREE.Mesh();
var material = new THREE.MeshBasicMaterial( { overdraw: 0.5, side: 2 } );
rings.forEach(function (m){
tube.geometry.vertices.push(
new THREE.Vector3(m[0], m[1], m[2]))});
faces.forEach(function (m){
tube.geometry.faces.push(
new THREE.Face3(m[0], m[1], m[2]))});
tube.material.side=2;
maininst.scene.add(tube);
}
其他依赖的部分。
a.html
<!DOCTYPE html>
<html>
<body>
<script src="js/three.min.71.js"></script>
<script src="main.js"></script>
<script src="tubecreate.js"></script>
</body>
</html>
main.js
function ra(){return Math.random();}
function rra(){var a = Math.random(); return [a,a,a];}
var protos = [];
var chara = [];
var maininst = {
scene: null, camera: null, renderer: null,
container: null, controls: null,
clock: null, stats: null,
init: function() {
this.scene = new THREE.Scene();
var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight;
var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 1, FAR = 1000;
this.camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR);
this.scene.add(this.camera);
this.camera.position.set(100,400,400);
this.camera.lookAt(new THREE.Vector3(0,0,0));
this.renderer = new THREE.WebGLRenderer({ antialias:true });
this.renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
this.renderer.setClearColor(0x101010);
this.container = document.createElement('div');
document.body.appendChild(this.container);
this.container.appendChild(this.renderer.domElement);
this.clock = new THREE.Clock();
this.scene.add( new THREE.AmbientLight(0xFFFFFF));
loadmod(this.scene);},
};
function animate() {
requestAnimationFrame(animate);
render();
update();
}
function update() {
var delta = maininst.clock.getDelta();
if(maininst.controls){
maininst.controls.update(delta);}
if(maininst.stats){
maininst.stats.update();}
THREE.AnimationHandler.update(delta*24);
}
function render() {
if (maininst.renderer) {
maininst.renderer.render(maininst.scene, maininst.camera);
}
}
function initializeLesson() {
maininst.init();
animate();
}
if (window.addEventListener)
window.addEventListener('load', initializeLesson, false);
else if (window.attachEvent)
window.attachEvent('onload', initializeLesson);
else window.onload = initializeLesson;
window.addEventListener('mousemove', onmove);
function onmove(ev){
var p =ev.clientX / 10;
maininst.camera.position.set(Math.cos(p)*400, 400, Math.sin(p)*400);
maininst.camera.lookAt(new THREE.Vector3(0,0,0));
}