这个是世界坐标转平面坐标
function updateScreenPosition() {
if (sprite === undefined) {
return false;
} else {
var vector = new THREE.Vector3(sprite.matrixWorld.elements[12], sprite.matrixWorld.elements[13], sprite.matrixWorld.elements[14]);
var canvas1 = renderer.domElement;
vector.project(camera);
vector.x = Math.round((0.5 + vector.x / 2) * window.innerWidth);
vector.y = Math.round((0.5 - vector.y / 2) * window.innerHeight);
annotation.style.top = vector.y + "px";
annotation.style.left = vector.x + "px";
}
}
这是屏幕坐标转换成三维坐标
_mouse.x = ( ( event.clientX - rect.left ) / rect.width ) * 2 - 1;
_mouse.y = - ( ( event.clientY - rect.top ) / rect.height ) * 2 + 1;
其它:
var WIDTH = window.innerWidth;
var HEIGHT = window.innerHeight;
//将鼠标的屏幕坐标转换为NDC坐标
var mX = ( ev.clientX / WIDTH ) * 2 - 1;
var mY = - ( ev.clientY / HEIGHT ) * 2 + 1;
//这里定义深度值为0.5,深度值越大,意味着精度越高
var vector = new THREE.Vector3(mX, mY, 0.5 );
//将鼠标坐标转换为3D空间坐标
function updateScreenPosition() {
if (sprite === undefined) {
return false;
} else {
var vector = new THREE.Vector3(sprite.matrixWorld.elements[12], sprite.matrixWorld.elements[13], sprite.matrixWorld.elements[14]);
var canvas1 = renderer.domElement;
vector.project(camera);
vector.x = Math.round((0.5 + vector.x / 2) * window.innerWidth);
vector.y = Math.round((0.5 - vector.y / 2) * window.innerHeight);
annotation.style.top = vector.y + "px";
annotation.style.left = vector.x + "px";
}
}
这是屏幕坐标转换成三维坐标
_mouse.x = ( ( event.clientX - rect.left ) / rect.width ) * 2 - 1;
_mouse.y = - ( ( event.clientY - rect.top ) / rect.height ) * 2 + 1;
其它:
var WIDTH = window.innerWidth;
var HEIGHT = window.innerHeight;
//将鼠标的屏幕坐标转换为NDC坐标
var mX = ( ev.clientX / WIDTH ) * 2 - 1;
var mY = - ( ev.clientY / HEIGHT ) * 2 + 1;
//这里定义深度值为0.5,深度值越大,意味着精度越高
var vector = new THREE.Vector3(mX, mY, 0.5 );
//将鼠标坐标转换为3D空间坐标
vector.unproject(camera);
我发现好多人看了上面也并不知道怎么获取三维的坐标,其实是没有深度的原因;上面算的只是系数,你要根据深度(z坐标)
我是在里面加了一个平面,然后用射线,这样,根据射线投射到平面的点就是他的坐标,平面就相当于我们知道他的深度,然后根据系数算它的坐标,这只是一种思路,让你明白它们之间的关系;
我的代码:
<!DOCTYPE html> <html lang="en"> <head> <title>鼠标移动世界坐标中的物体一起移动 - 平面坐标转换成3d坐标</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> <style> body { font-family: Monospace; background-color: #000; color: #fff; margin: 0px; overflow: hidden; text-align:center; } a { position: absolute; text-align:center; top: 20px; font-size: 18px; } </style> <script src="../js/three.js"></script> <script src="../js/TrackballControls.js"></script> <script src="../js/hammer.js"></script> <a> 屏幕坐标转换成3d坐标,查了很多资料,都是只讲了一个大概; 如实现算法: mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1; mouse.y = -( event.clientY / window.innerHeight ) * 2 + 1; 但是你以为这么就可以得到世界坐标,结果发现并没有, 最后我查了很多资料,并看了democ才有所启发,我的实现方式是使用射线; 上面的计算你得到的只是系数,并不是世界坐标中的坐标,因为计算机根本就不知道你的深度,你要点击的是什么位置, 所有我用了射线;实现思路就是,你在屏幕上移动的物体的坐标,转换成世界坐标,相机的位置,和屏幕的位置(点击位置), 形成了一条射线,然后在与你想要的位置屏幕,相差交叉,就得到了世界坐标的位置; </a> <script> var container; var camera, scene, renderer; var camera_angle = 45;//设置相机的角度 var obj = null; var controls; var isRotate = false;//obj是否旋转 var roomMesh1; var raycaster; var mouse = new THREE.Vector2(100, 100), INTERSECTED; var planeMesh; function initView() { container = document.createElement('div'); document.body.appendChild(container); raycaster = new THREE.Raycaster(); // scene initScene(); initCamera(); initOrbitControls(); initLight(); initRenderer(); var materialRing1 = new THREE.MeshBasicMaterial({color: 0x0000ff}); var geometry1 = new THREE.SphereBufferGeometry(5, 32, 32); roomMesh1 = new THREE.Mesh(geometry1, materialRing1); roomMesh1.position.set(0, 0, 0); scene.add(roomMesh1); var planeMaterial = new THREE.MeshBasicMaterial({ color: 0x2194ce, opacity: 0, transparent: true, depthTest: true }); var planeGeometry = new THREE.PlaneBufferGeometry(800, 800, 1); planeMesh = new THREE.Mesh(planeGeometry, planeMaterial); planeMesh.position.set(0, 0, 0); console.log(planeMesh); // scene.add(planeMesh); animate(); } function initCamera() { camera = new THREE.PerspectiveCamera(camera_angle, window.innerWidth / window.innerHeight, 0.1, 20000); camera.position.set(400, 400, 400); camera.up.set(0, 1, 0); } function initScene() { scene = new THREE.Scene(); document.addEventListener('mousemove', onDocumentMouseMove, false); } function onDocumentMouseMove(event) { event.preventDefault(); mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1; mouse.y = -( event.clientY / window.innerHeight ) * 2 + 1; } var pointLight;//跟上相机一起的点光源,用于透明 var spotLight;//光束光 ,用于不透明 function initLight() { var ambientLight = new THREE.AmbientLight(0x505050); scene.add(ambientLight); pointLight = new THREE.PointLight(0xffffff, 1); camera.add(pointLight); scene.add(camera); } function initOrbitControls() { controls = new THREE.TrackballControls(camera); controls.rotateSpeed = 1.0; controls.zoomSpeed = 1.2; controls.panSpeed = 0.8; controls.noZoom = false; controls.noPan = false; controls.staticMoving = true; controls.dynamicDampingFactor = 0.3; // controls = new THREE.OrbitControls(camera, renderer.domElement); } function initRenderer() { renderer = new THREE.WebGLRenderer({antialias: true}); renderer.setPixelRatio(window.devicePixelRatio); renderer.shadowMap.enabled = true; renderer.shadowMap.renderSingleSided = false; /*设置设备像素比*/ renderer.setSize(window.innerWidth, window.innerHeight); renderer.shadowMapEnabled = true; renderer.shadowMap.type = THREE.PCFSoftShadowMap;//让边缘柔和起来 renderer.gammaInput = true; renderer.gammaOutput = true; container.appendChild(renderer.domElement); } /*循环*/ function animate() { render(); requestAnimationFrame(animate); } /*更新渲染*/ function render() { planeMesh.lookAt(camera.position); if (obj != null && isRotate) { obj.rotateOnAxis(new THREE.Vector3(0, 1, 0), 0.005) } controls.update(); raycaster.setFromCamera(mouse, camera); var intersects = raycaster.intersectObject(planeMesh); if (intersects.length > 0) { if (intersects[0].object) { console.log(intersects[0].object); intersects[0].object.material.color.setHex(0x0000ff); roomMesh1.position.copy(intersects[0].point); } } renderer.render(scene, camera); } </script> </head> <body onload="initView()"> </body> </html>