【问题标题】:THREE.JS Place a plane along given line and an vectorTHREE.JS 沿给定线放置一个平面和一个向量
【发布时间】:2019-06-19 20:20:43
【问题描述】:

我在 3D 空间中有一条任意线和垂直向量,所以两者都可以形成一个平面。见插图。

任务是沿着这条线放置已存在的位面,因此位面的脸 将被看到(渲染),请参见第二个插图。

需要有关如何操作的指南。提前致谢。

【问题讨论】:

  • (1) 这是家庭作业吗? (2) 请出示您的代码和您尝试过的内容。
  • 不,我太老了,不能做作业,但你说得对,很快就会上传代码。
  • @VVK:查看您的网站后回答了您的问题。印象深刻。

标签: vector three.js quaternions normals plane


【解决方案1】:

您可以在这里找到工作示例:https://jsfiddle.net/mmalex/ert1Lwy9/

解决方案的关键点是通过.lookAt 旋转平面并具有明确定义的矢量.up,看看它在我的绘图上是如何工作的。

// line is defined by p0-p1
var p0 = new THREE.Vector3(-1, 2, 1);
var p1 = new THREE.Vector3(2, -1, -1);

// any random point outside the line will define plane orientation
var p2 = p1.clone().add(new THREE.Vector3(0.4, 0.8, 0.53));

var material2 = new THREE.LineBasicMaterial({
    color: 0x0000ff
});

// draw the line for visual reference
var geometry = new THREE.Geometry();
geometry.vertices.push(
    p0,
    p1,
    p2
);
var line = new THREE.Line(geometry, material2);
scene.add(line);

// get direction of line p0-p1
var direction = p1.clone().sub(p0).normalize();

// project p2 on line p0-p1
var line0 = new THREE.Line3(p0, p1);
var proj = new THREE.Vector3();
line0.closestPointToPoint(p2, true, proj);

// get plane side direction
var localUp = p2.clone().sub(proj).normalize();

// draw the projection, just nice to have
var axesHelper = new THREE.AxesHelper(0.1);
axesHelper.position.copy(proj);
scene.add(axesHelper);

// calc plane normal vector (how we want plane to direct)
var n = new THREE.Vector3();
n.crossVectors(proj.clone().sub(p0), proj.clone().sub(p2));

// preparation is complete, create a plane now
const planeL = 2.15;
const planeW = 1.75;

var geometry = new THREE.PlaneGeometry(planeL, planeW, 32);
var material3 = new THREE.MeshBasicMaterial({
    color: 0xa9cc00,
    side: THREE.DoubleSide
});
var plane = new THREE.Mesh(geometry, material3);

// now align the plane to the p0-p1 in direction p2
plane.position.copy(p0); //put plane by its center on p0
plane.up.copy(localUp); //adjust .up for future .lookAt call
plane.lookAt(p0.clone().add(n)); //rotate plane

// now just offset plane by half width and half height
plane.position.add(localUp.clone().multiplyScalar(planeW / 2));
plane.position.add(direction.clone().multiplyScalar(planeL / 2));

// done!
scene.add(plane);

【讨论】:

  • 感谢您的出色贡献。
  • 我尝试了示例代码,但浏览器中没有任何显示,我需要做什么才能使其工作?
【解决方案2】:

		var camera, scene, renderer, controls;
			var labelX, labelY, labelY;
            
            var loader = new THREE.FontLoader();

            loader.load("https://raw.githubusercontent.com/mrdoob/three.js/dev/examples/fonts/helvetiker_regular.typeface.json", function (font_) {

                init(font_);

            });

			function init(font_) {
                
				camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 1, 1000 );
				camera.position.set(256, 512, 512);
                camera.lookAt(new THREE.Vector3(0, 0, 0));  
				scene = new THREE.Scene();

				renderer = new THREE.WebGLRenderer( { antialias: true } );
				renderer.setPixelRatio( window.devicePixelRatio );
				renderer.setSize( window.innerWidth, window.innerHeight );
                renderer.setClearColor( 0xDEDEDE, 1.0 );
				document.body.appendChild( renderer.domElement );
                
                controls = new THREE.OrbitControls(camera, renderer.domElement);
                controls.enableDamping = true;
                controls.enablePan = true;
                controls.dampingFactor = 0.25;
 

                controls.mouseButtons = {
                LEFT: THREE.MOUSE.LEFT,
                MIDDLE: THREE.MOUSE.MIDDLE,
                RIGHT: THREE.MOUSE.RIGHT
                };
                
                var	material = new THREE.LineBasicMaterial( { color: 0x000000 } );
                
                var geometry = new THREE.Geometry();
                geometry.vertices.push(new THREE.Vector3(-196, 0, 0));
                geometry.vertices.push(new THREE.Vector3(196, 0, 0));
                var xLine = new THREE.Line(geometry, material);
                scene.add(xLine);
                
                var geometry = new THREE.Geometry();
                geometry.vertices.push(new THREE.Vector3(0, -196, 0));
                geometry.vertices.push(new THREE.Vector3(0, 196, 0));
                var yLine = new THREE.Line(geometry, material);
                scene.add(yLine);
                
                var geometry = new THREE.Geometry();
                geometry.vertices.push(new THREE.Vector3(0, 0, -196));
                geometry.vertices.push(new THREE.Vector3(0, 0, 196));
                var zLine = new THREE.Line(geometry, material);
                scene.add(zLine);
  
                var textMaterial = new THREE.MeshBasicMaterial({ color: 0x000000 });
                
                var textX = new THREE.TextGeometry("label_x", {

                    font: font_,
                    size: 6,
                    height: 0.1,
                    curveSegments: 12,
                    bevelEnabled: false,

                });
                
                labelX = new THREE.Mesh(textX, textMaterial);
                labelX.position.set(180, 0, -6);
                labelX.geometry.center();
                labelX.rotateX(-Math.PI/2)
                scene.add(labelX);
                
                var textY = new THREE.TextGeometry("label_y", {

                    font: font_,
                    size: 6,
                    height: 0.1,
                    curveSegments: 12,
                    bevelEnabled: false,

                });
                
                labelY = new THREE.Mesh(textY, textMaterial);
                labelY.position.set(6, 180, 0);
                labelY.geometry.center();
                labelY.rotateZ(Math.PI/2)
                scene.add(labelY);
                
                var textZ = new THREE.TextGeometry("label_z", {

                    font: font_,
                    size: 6,
                    height: 0.1,
                    curveSegments: 12,
                    bevelEnabled: false,

                });
                
                labelZ = new THREE.Mesh(textZ, textMaterial);
                labelZ.position.set(-6, 0, -180);
                labelZ.geometry.center();
                labelZ.rotateY(Math.PI/2)
                labelZ.rotateX(-Math.PI/2)
                scene.add(labelZ);
      
				window.addEventListener( 'resize', onWindowResize, false );
                
                animate();
                
			}
            
			function onWindowResize() {
                
				camera.aspect = window.innerWidth / window.innerHeight;
				camera.updateProjectionMatrix();
				renderer.setSize( window.innerWidth, window.innerHeight );
                
			}
            
			function animate() {
                   
                if(camera.position.y < 0){

                    labelX.rotation.set(Math.PI/2, 0, 0);
                    labelZ.rotation.set(0, Math.PI/2, 0);
                    labelZ.rotateX(Math.PI/2);


                }else{

                    labelX.rotation.set(-Math.PI/2, 0, 0);
                    labelZ.rotation.set(0, Math.PI/2, 0);
                    labelZ.rotateX(-Math.PI/2);

                }


                if(camera.position.z < 0){

                    labelY.rotation.set(0, -Math.PI, -Math.PI/2);

                }else{

                    labelY.rotation.set(0, 0, Math.PI/2);

                }

                controls.update();
				requestAnimationFrame( animate );
				renderer.render( scene, camera );
                
			}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/98/three.min.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/controls/OrbitControls.js"></script>

实际上,我正在尝试这样做。

【讨论】:

  • 我对这个问题也有一些可行的解决方案,三个.js 线性尺寸,顶部有 2D html 文本标签 - jsfiddle.net/mmalex/j35p1fw8 标签被精确定位和对齐。此外,尺寸“跳跃”以呈现当前相机 PoV 的最易读文本。
  • 通常,对于这种情况,我在顶部使用画布 HUD。 vkuchinov.github.io/Interactive3DModel
猜你喜欢
  • 1970-01-01
  • 2013-01-18
  • 2016-07-07
  • 1970-01-01
  • 1970-01-01
  • 2017-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多