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;
}