前言
书接上文,70岁的老同志终于开始写Cesium的坐标平移旋转了,嘿嘿😀
在上篇博客中完成了圆坐标轴、箭头坐标轴的自定义,下一步就是使模型沿着坐标轴进行平移和旋转。本篇就先说一下模型平移吧。
一、实现思路
模型有modelMatrix属性,只要将鼠标的位置偏移量转换到模型的modelMatrix上即可。首先,要搞清楚模型平移的方向,我是通过鼠标点击选择坐标轴来实现,第二步,计算鼠标的在选择的坐标方向上的偏移量,cesium中已经提供了关于矩阵点乘和相乘的方式,通过矩阵运算完成模型的平移。
一、选择平移方向
点击坐标轴后,相应的坐标轴高亮,不多废话,上代码。
var ob = scene.pick(event.position);
if(ob ===undefined)
return;
highlight.object = ob;
highlight.color = ob.primitive.appearance.material.uniforms.color;
ob.primitive.appearance.material.uniforms.color = Cesium.Color.YELLOW;
ob就是鼠标点击事件获取的信息,在上篇博客中已经为建立好的坐标轴附上了id,这就是为现在选择哪个方向的坐标轴做准备的。同时记录下此坐标轴的颜色,当平移结束后,将颜色恢复到原坐标轴的颜色。
鼠标点击之后为cesium添加鼠标移动事件。同时,需要设置cesium的球不可旋转,避免移动时产生意想不到的效果😏。
handler.setInputAction(function(event) {
var position1;
var position2;
var car1 =new Cesium.Cartesian2();
var car2 =new Cesium.Cartesian2();
scene.screenSpaceCameraController.enableRotate = false;
},Cesium.ScreenSpaceEventType.MOUSE_MOVE)
选好坐标轴后,要将坐标轴方向转换到屏幕坐标中,用cesium中的SceneTransforms.wgs84ToWindowCoordinates来进行转换。以x坐标轴为例,由于我的坐标轴是沿经纬度建立的,坐标轴上的两点我是这样表示的:
position1 = Cesium.Cartesian3.fromDegrees(lon,lat,hei);
position2=Cesium.Cartesian3.fromDegrees(lon,lat+0.0000003,hei);
car1=Cesium.SceneTransforms.wgs84ToWindowCoordinates(scene,position1,car1);
car2 = Cesium.SceneTransforms.wgs84ToWindowCoordinates(scene,position2,car2);
至于为什么是0.0000003,有兴趣的小伙伴可以研究一下坐标轴代表的单位,不做赘述了。
如果有其它方向上的平移,只需要给出这个坐标轴上的任意两点即可。可任意定义。
二、计算移动量
有了car1和car2,计算移动的起始位置在car1和car2上的分量,计算方式如下:
var x1 = car2.x-car1.x;
var y1 = car2.y-car1.y;
if (event.startPosition.x===0)
return
var cartesian = event.startPosition;
var endcartesian = event.endPosition;
var x2 = endcartesian.x-cartesian.x;
var y2 =endcartesian.y-cartesian.y;
var x = (x1*x2+y1*y2)/Cesium.Cartesian2.distance(car1,car2);
translation = new Cesium.Cartesian3(x,0,0);
translation就是沿x轴方向的移动量。平移量生成平移矩阵:
var modelMatrixN=new Cesium.Matrix4() ;//原始矩阵的逆矩阵
modelMatrixN = Cesium.Matrix4.inverse(modelMatrix,modelMatrixN);
var rotationM = new Cesium.Matrix4();//记录平移前矩阵乘逆得到笛卡尔坐标系
rotationM = Cesium.Matrix4.multiply(modelMatrixN,model.modelMatrix,rotationM);
var changeM =new Cesium.Matrix4();//平移矩阵
Cesium.Matrix4.fromTranslation(translation,changeM);
model.modelMatrix = Cesium.Matrix4.multiply(model.modelMatrix,changeM,model.modelMatrix);//笛卡尔的平移量
drowZ.modelMatrix = Cesium.Matrix4.multiply(drowZ.modelMatrix,changeM,drowZ.modelMatrix);
configXYZ(drowZ,drowX,drowY);//平移坐标轴
最后就是将坐标轴进行相应的移动:代码如下:
function configXYZ(drowZ,drowX,drowY){
var translationY = new Cesium.Matrix3();
Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(90),translationY);
drowX.modelMatrix = Cesium.Matrix4.multiplyByMatrix3(drowZ.modelMatrix,
translationY,drowX.modelMatrix);
var translationX = new Cesium.Matrix3();
Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(-90),translationX);
drowY.modelMatrix = Cesium.Matrix4.multiplyByMatrix3(drowZ.modelMatrix,
translationX,drowY.modelMatrix);
}
drowx,drowy,drowz是咱画坐标时,返回的坐标轴。
最早之前按照矩阵平移的想法做了一版复杂的,这是改进后的结果,就不往上贴了,如果有需要源码的,私我。
就这样,下篇放旋转的,拜拜!
三 、总结
无