Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Three.js中移动和更改lookAt(过山车视图)时,使摄影机沿z轴旋转_Three.js_3d_Geometry_Linear Algebra - Fatal编程技术网

在Three.js中移动和更改lookAt(过山车视图)时,使摄影机沿z轴旋转

在Three.js中移动和更改lookAt(过山车视图)时,使摄影机沿z轴旋转,three.js,3d,geometry,linear-algebra,Three.js,3d,Geometry,Linear Algebra,嗨,我有个问题,也许你能帮我 我有一个摄像头,它沿着一条路径沿着一条管子向下移动。还有一个绕着管子旋转的摄像机,它总是指向管子中的下一个点。然而,相机有时可以像过山车一样位于管子的下方或旁边。像这样 我有点a的位置和相机的位置,这是点b。我一直在看a+1点 var bpoints = this.cameraPathpoints; var apoints = this.pathPoints; this.camera.position.copy(bpoints[i]); this.camera.

嗨,我有个问题,也许你能帮我

我有一个摄像头,它沿着一条路径沿着一条管子向下移动。还有一个绕着管子旋转的摄像机,它总是指向管子中的下一个点。然而,相机有时可以像过山车一样位于管子的下方或旁边。像这样

我有点a的位置和相机的位置,这是点b。我一直在看a+1点

var bpoints = this.cameraPathpoints;
var apoints = this.pathPoints;

this.camera.position.copy(bpoints[i]);
this.camera.lookAt(apoints[i+1]);
相机始终正确地观察该点,但我希望相机在其z轴上旋转,使其始终垂直于管。我尝试进行一些计算,使相机在其z轴上旋转,使相机始终垂直于管,但我的计算仅在某些位置工作。也许有一种更简单的方法可以做到这一点。非常感谢你的帮助

var angleRadians = Math.atan2(cpv[this.cameraPos].pos.y - centePoints[this.cameraPos].pos.y, cpv[this.cameraPos].pos.x - centePoints[this.cameraPos].pos.x);

      if(angleRadians > 0 && angleRadians > Math.PI/2){
        console.log("+90",(Math.PI/2) - angleRadians);
        angleRadians = (Math.PI/2) - angleRadians;
        this.camera.rotateZ(angleRadians);
        console.log("rotated ", angleRadians * 180/Math.PI);
      }
       else if(angleRadians > 0 && angleRadians < Math.PI/2 && anglesum > 
     Math.PI/2){
        console.log("-90",(Math.PI/2) - angleRadians);
         angleRadians = (Math.PI/2) - angleRadians;
         this.camera.rotateZ(-angleRadians);
         console.log("rotated ", -angleRadians * 180/Math.PI);
       } 
        else if(angleRadians > 0 && angleRadians < Math.PI/2){
        console.log("-90",(Math.PI/2) + angleRadians);
         angleRadians = -(Math.PI/2) - (angleRadians/Math.PI/2);
         this.camera.rotateZ(angleRadians);
         console.log("rotated ", angleRadians * 180/Math.PI);
       } 
      else if(angleRadians < 0 && angleRadians < -Math.PI/2){
        console.log("--90");
        angleRadians = (Math.PI/2) + angleRadians;
        this.camera.rotateZ(-angleRadians);
        console.log("rotated ",-angleRadians * 180/Math.PI);
      }else if(angleRadians < 0 && angleRadians > -Math.PI/2){
        console.log("+-90");
        angleRadians = (Math.PI/2) - angleRadians;
        this.camera.rotateZ(-angleRadians);
        console.log("rotated ", -angleRadians * 180/Math.PI);
      }
var angelradians=Math.atan2(cpv[this.cameraPos].pos.y-centePoints[this.cameraPos].pos.y,cpv[this.cameraPos].pos.x-centePoints[this.cameraPos].pos.x);
if(角度弧度>0和角度弧度>数学PI/2){
console.log(“+90”,(数学PI/2)-角度弧度);
角度弧度=(Math.PI/2)-角度弧度;
这个.camera.rotateZ(角度弧度);
console.log(“旋转”,角度弧度*180/Math.PI);
}
如果(角度弧度>0和角度弧度
数学(PI/2){
console.log(“-90”,(数学PI/2)-角度弧度);
角度弧度=(Math.PI/2)-角度弧度;
此.camera.rotateZ(-angleRadians);
console.log(“旋转”,角度弧度*180/Math.PI);
} 
else if(角度弧度>0和角度弧度-Math.PI/2){
控制台日志(“+-90”);
角度弧度=(Math.PI/2)-角度弧度;
此.camera.rotateZ(-angleRadians);
console.log(“旋转”,角度弧度*180/Math.PI);
}

与其做数学运算,不如让相机成为其他
三个对象的子对象。Object3D
并对该对象使用
lookAt
。设置相机相对于该对象的位置和旋转

下面的对象称为
挂载
。它沿着路径(管的中心)向下移动。相机是
挂载
的子组件。管子的半径为1个单位,因此将camera.position.y设置为1.5将使其位于管子外部
lookAt
使非摄影机对象向下看正Z,但摄影机向下看负Z,因此我们将摄影机旋转180度

例如:

“严格使用”;
/*全球三*/
函数main(){
const canvas=document.querySelector(“#c”);
const renderer=new THREE.WebGLRenderer({canvas:canvas});
const scene=new THREE.scene();
scene.background=新的三种颜色(0xaaaa);
常数fov=40;
const aspect=2;//画布默认值
常数近=0.1;
常数far=1000;
常量摄影机=新的三个透视摄影机(视野、方位、近距离、远距离);
camera.position.y=1.5;//2个单元位于底座上方
camera.rotation.y=Math.PI;//挂载将在positiveZ上移动
const mount=new THREE.Object3D();
安装。添加(摄像头);
场景。添加(挂载);
{
常量颜色=0xFFFFFF;
常数强度=1;
恒定光=新的三个方向光(颜色、强度);
灯。位置。设置(-1,2,4);
场景。添加(灯光);
}
{
常量颜色=0xFFFFFF;
常数强度=1;
恒定光=新的三个方向光(颜色、强度);
光。位置。设置(1,-2,-4);
场景。添加(灯光);
}
const curve=新的三条.Curves.GrannyKnot();
常数管段=200;
常数半径=1;
常数半径段=6;
const closed=true;
const tube=新的3.5倍几何体(
曲线、管段、半径、半径段、闭合);
const texture=new THREE.DataTexture(新的Uint8Array([128,255,255,128]),
2,2,3.亮度格式);
texture.needsUpdate=true;
texture.magFilter=3.NearestFilter;
texture.wrapps=3.repeat wrapping;
texture.wrapT=3.0;
纹理。重复。设置(100,4);
const material=新的3.0网格材质({
贴图:纹理,
颜色:“#8CF”,
对,,
});
常量网格=新的三个网格(管、材料);
场景。添加(网格);
const target=new THREE.Vector3();
函数resizeRenderToDisplaySize(渲染器){
const canvas=renderer.domeElement;
const width=canvas.clientWidth;
常数高度=canvas.clientHeight;
const needResize=canvas.width!==width | | canvas.height!==height;
如果(需要调整大小){
设置大小(宽度、高度、假);
}
返回需要调整大小;
}
函数渲染(时间){
时间*=0.001;
if(ResizeRenderToDisplaySize(渲染器)){
const canvas=renderer.domeElement;
camera.aspect=canvas.clientWidth/canvas.clientHeight;
camera.updateProjectMatrix();
}
常数t=时间*0.1%1;
曲线点(t,安装位置);
曲线.getPointAt((t+0.01)%1,目标);
坐骑,注视(目标);
渲染器。渲染(场景、摄影机);
请求动画帧(渲染);
}
请求动画帧(渲染);
}
main()
body{margin:0;}
画布{宽度:100vw;高度:100vh;显示:块;}

看看如何更改
摄像机。向上
矢量默认情况下,它是
(0,1,0)
,这意味着“向上”沿Y轴