我如何画一条线,然后在 three.js 中从它创建一个剪切平面?里面的工作示例

Posted

技术标签:

【中文标题】我如何画一条线,然后在 three.js 中从它创建一个剪切平面?里面的工作示例【英文标题】:How may I draw a line, then create a clipping plane from it in three.js? Working example inside 【发布时间】:2022-01-08 11:49:22 【问题描述】:

我如何画一条线,并从中创建一个剪切平面?里面几乎可以工作的例子。

https://decadent3d.s3.amazonaws.com/data/test.html

一切都在页面源代码中。

//你需要取消注释实际的问题行//

函数 newClipping() 允许我在始终面向相机的平面上画一条线,

我从中获取起点和终点(Vector3s)并创建一个新的 THREE.Line3

然后我使用 Line3.GetCenter() 来获取我的第三个 Vector3。

然后使用我在下面链接中在线找到的数学,我开始工作。

https://www.geeksforgeeks.org/program-to-find-equation-of-a-plane-passing-through-3-points/

但它不起作用。

这里有比这个爱好者更好的人吗???

https://www.reddit.com/r/threejs/comments/r6qh38/how_may_i_draw_a_line_and_create_a_clipping_plane/

【问题讨论】:

THREE.Plane() 有这个method 从三个共面点设置一个平面。 .getCenter() of THREE.Line3() 给你一个点,它正好位于线的两端之间,因此你在同一条线上有三个点,不确定在这种情况下你可以称它们共面。要构建一个平面,我会使用您绘制的线的两个点和相机的位置。 【参考方案1】:

下面是最后运行的代码...

//working sample

let myButton = document.getElementById('ClippingButton');

function removeClipping() 
                  
    renderer.clippingPlanes = [];
    myButton.innerText = 'Slice Models';
    myButton.addEventListener('click', function(event) drawEnabled = true; newClipping();,  once: true );

;

function newClipping() 

    myButton.innerText = 'Draw a Line';
    myButton.style.color = '#fccf03';
        
    rackballcontrol.enabled = false;
        
    var hitPlane = new THREE.Mesh(new THREE.PlaneBufferGeometry(200,200),new THREE.MeshBasicMaterial( transparent: true, opacity: 0.0 ) );
    hitPlane.quaternion.copy(camera.quaternion);
    scene.add(hitPlane);
        
    var lineGeometry = new THREE.BufferGeometry().setFromPoints([ new THREE.Vector3(), new THREE.Vector3() ]);
    var lineMaterial = new THREE.LineBasicMaterial( color: 0xffffff, side: THREE.DoubleSide );
    var newLine = new THREE.Line(lineGeometry, lineMaterial);
    scene.add( newLine );
       
    var rayCaster = new THREE.Raycaster();
    var hitPoint = new THREE.Vector3();
    var isMouseDown = false;

    renderer.domElement.addEventListener('mousedown', e => 
        if (e.button === 0) 
            var x = (e.clientX / renderer.domElement.clientWidth) * 2 - 1;
            var y = -(e.clientY / renderer.domElement.clientHeight) * 2 + 1;
            rayCaster.setFromCamera( x, y , camera);
            var intersections = rayCaster.intersectObject(hitPlane);
        if (intersections && intersections.length) 
            isMouseDown = true;
            hitPoint.copy(intersections[0].point);
            lineGeometry.setFromPoints([ hitPoint, intersections[0].point ]);
        ;
        ;
    ,  once: true );
        renderer.domElement.addEventListener('mousemove', e => 
        if (isMouseDown) 
            var x = (e.clientX / renderer.domElement.clientWidth) * 2 - 1;
            var y = -(e.clientY / renderer.domElement.clientHeight) * 2 + 1;
            rayCaster.setFromCamera( x, y , camera);
            var intersections = rayCaster.intersectObject(hitPlane);
        if (intersections && intersections.length) 
            lineGeometry.setFromPoints([ hitPoint, intersections[0].point ])
        ;
        ;
    );
    renderer.domElement.addEventListener('mouseup', e => 
        for (i = 0; i < meshArray.length; i++) 
            if(meshArray[i].visible === true)
            matArray[i].opacity = 1;
            ;
                ;
        isMouseDown = false;
        trackballcontrol.enabled = true;

        var lineArray = newLine.geometry.attributes.position.array;
        var vectA = new THREE.Vector3(lineArray[0],lineArray[1],lineArray[2]);
        var vectC = new THREE.Vector3(lineArray[3],lineArray[4],lineArray[5]);
        var globalPlane = new THREE.Plane().setFromCoplanarPoints(camera.position,vectA,vectC);
        renderer.clippingPlanes = [ globalPlane ];
        myButton.addEventListener('click', function(event)  removeClipping(); ,  once: true );
        myButton.innerText = 'Remove Slice';
        myButton.style.color = '#fc8c03';
        scene.remove(hitPlane);
        scene.remove(newLine);
    ,  once: true );
;

myButton.addEventListener('click', function(event)  newClipping(); ,  once: true );
//working sample

【讨论】:

以上是关于我如何画一条线,然后在 three.js 中从它创建一个剪切平面?里面的工作示例的主要内容,如果未能解决你的问题,请参考以下文章

HTML5 Canvas - 如何在图像背景上画一条线?

当手指在 iPhone 上移动时如何在图像顶部画一条线

如何在Three.js中为一条线的增长动画?

如何在HTML中画一条线

从两个按钮之间的手势画一条线

如何使用 fabric.js 在画布上画一条线