threejs物体绕任意轴旋转的简洁算法逻辑,附代码

​​​​​​​ threejs 官方网站只提供了绕坐标轴旋转及过原点向量的欧拉旋转 ,全网随便搜包括google仅此一篇 此例子解决了绕任意直线旋转的效果,并且支持无限单独的旋转系统,代码非常精简,易用,转载请附上地址。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>绕非通过坐标轴的线的旋转复合式-easy</title>
    <link rel="stylesheet" href="../../css/base.css">
    <script src="../../lib/three.js"></script>
    <script src="../../lib/OrbitControls.js"></script>

</head>
<body>
<div id="threeJsOuter" class="webgl"></div>
<script src="../../utils/common.js"></script>

<script>
    var gemoWidth = 6
    scene.add(new THREE.AxesHelper(50))

    var geometry = new THREE.BoxGeometry(...new Array(3).fill(gemoWidth)); //声明一个缓冲几何体对象
    var cube = new THREE.Mesh(geometry, new THREE.MeshNormalMaterial({}))

    var vec1 = new THREE.Vector3(-10, 30, 20)
    var vec2 = new THREE.Vector3(20, 50, -10)

    function drawLine() {
        scene.add(new THREE.Line(new THREE.BufferGeometry().setFromPoints([vec1,vec2]), new THREE.LineBasicMaterial({
            color: "#97d789"
        })));
    }

    drawLine()

    function getPointByPlaneAndline(vec1, vec2) {
        // 创建一个射线
        var raycaster = new THREE.Raycaster(vec1, new THREE.Vector3().subVectors(vec2, vec1).normalize());

        // 创建一个平面
        var plane = new THREE.Plane(new THREE.Vector3(1, 0, 0), 0);

        // 计算射线与平面的交点
        var intersectionPoint = new THREE.Vector3();
        return raycaster.ray.intersectPlane(plane, intersectionPoint);
    }

    let planeDot = getPointByPlaneAndline(vec1, vec2)
    let group1 = new THREE.Group();
    group1.position.x = 0
    group1.position.y = planeDot.y
    group1.position.z = planeDot.z
    let gv = new THREE.Vector3().subVectors(planeDot.multiplyScalar(1.2), new THREE.Vector3(0, planeDot.y, planeDot.z));
    cube.position.x = gv.x
    cube.position.y = gv.y
    cube.position.z = gv.z
    group1.add(cube)
    scene.add(group1)

    function rotateFn(axis__) {
        var rotWorldMatrix = new THREE.Matrix4(); //创建一个4*4矩阵

        rotWorldMatrix.makeRotationAxis(axis__.normalize(), 0.6 * Math.PI / 180);

        rotWorldMatrix.multiply(group1.matrix); // pre-multiply

        group1.matrix = rotWorldMatrix;

        group1.rotation.setFromRotationMatrix(group1.matrix);
    }

    function getRender() {
        // console.log(1);
        rotateFn(new THREE.Vector3().subVectors(vec1,vec2))
    }
</script>
</body>
</html>
//common.js
var scene = new THREE.Scene();
let threeDom = document.querySelector("#threeJsOuter")
/*
*
* near — 摄像机视锥体近端面 能看到的最近距离  如果使用深色材质 设置的值太小导致 距离远的物体一直是深色或者黑色的
far — 摄像机视锥体远端面
* */
var camera = new THREE.PerspectiveCamera(45, threeDom.offsetWidth / threeDom.offsetHeight, 0.1, 1000);

camera.position.x = 100;
camera.position.y = 100;
camera.position.z = 100;
var target = new THREE.Vector3(0, 0 , 0);
camera.lookAt(target);

var renderder = new THREE.WebGLRenderer({
    antialias: true //去锯齿
    , alpha: true
});
renderder.setSize(threeDom.offsetWidth, threeDom.offsetHeight);

renderder.setClearColor("#dcdcdc");
// renderder.setClearColor(0x000000, 1.0);

let controls = null
if (THREE.OrbitControls) {
    controls = new THREE.OrbitControls(camera, renderder.domElement);
    controls.target = target;
}


function renderFn() {

    requestAnimationFrame(renderFn)
    renderder.render(scene, camera);
    controls && controls.update();
    typeof getRender === "function"&&getRender()

}

renderFn();

// renderder.render(scene, camera);

document.querySelector("#threeJsOuter").appendChild(renderder.domElement)
body {
    margin: 0;
    overflow: hidden;
}
#threeJsOuter,.webgl {
    width: 800px;
    height: 600px;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值