作者:taco
说到关于地理必然逃不开位置的关系。借用百度百科的内容来说地理学(geography),是研究地球表层空间地理要素或者地理综合体空间分布规律、时间演变过程和区域特征的一门学科。所以位置&坐标系必然逃不掉了。那么在SuperMap iClient3D for WebGL/WebGPU中包含了哪些坐标系信息呢?
可能说到笛卡尔坐标系,对于一个毕业多年的人来说,或者很少接触数学、物理理科的人来算的话会有一些陌生。但是说到直角坐标系的时候,相信大家就会想到这个从小学到大的坐标系概念。笛卡儿坐标系(Cartesian coordinates,法语:les coordonnées cartésiennes)就是直角坐标系和斜坐标系的统称。
在SuperMap iClient3D for WebGL/WebGPU 同样提供了笛卡尔直角坐标系这个最基础的坐标系。
var cartesian2 = new SuperMap3D.Cartesian2(0,0);
console.log("cartesian2===================",cartesian2);
那在使用过程中,什么情况能拿到Cartesian2的坐标呢?
在场景里其是Cartesian2,我们主要作为屏幕坐标来使用。也就是说我们获取到的屏幕坐标就是Cartesian2。我们来验证一下,首先我们添加一个监听点击事件获取屏幕坐标。
document.addEventListener("click", function(e) {
var x = e.clientX;
var y = e.clientY;
console.log("鼠标当前位置:x=" + x + ", y=" + y);
});
再通过SuperMap3D提供的点击事件获取默认拾取的坐标。
var handler = new SuperMap3D.ScreenSpaceEventHandler(scene.canvas);
//设置鼠标左键单击回调事件
handler.setInputAction(function(e) {
//获取点击位置笛卡尔坐标
console.log("拾取坐标x=", e.position.x, "y=", e.position.y);
}, SuperMap3D.ScreenSpaceEventType.LEFT_CLICK);
令人不出意外的事情出现了,他们一样。所以当我们通过接口拿到的屏幕坐标其实就是界面上的屏幕坐标。
屏幕坐标的原点与标准的笛卡尔坐标的原点还是有那么一些区别的。这里以左上角为坐标原点(0,0)而并非屏幕中心位置。向下为y轴正方形,向右为x轴正方向。右下角为屏幕分辨率的数值。
那么关于Cartesian2有哪些构建方法可以使用呢?接下来我们看下。
在该方法中默认提供了三种方式创建单位向量,同时也包含了零向量。UNIT_X、UNIT_Y、ZERO
创建X单位向量:SuperMap3D.Cartesian2.UNIT_X (1.0,0.0)
创建Y单位向量:SuperMap3D.Cartesian2.UNIT_Y (0.0,1.0)
创建零向量 :SuperMap3D.Cartesian2.ZERO (0.0,0.0)
var Cartesian2X = SuperMap3D.Cartesian2.UNIT_X;
var Cartesian2Y = SuperMap3D.Cartesian2.UNIT_Y;
var Cartesian2ZERO = SuperMap3D.Cartesian2.ZERO;
console.log("Cartesian2X", Cartesian2X, "Cartesian2Y", Cartesian2Y, "Cartesian2ZERO", Cartesian2ZERO);
该方法可以通过数组构建Cartesian2点,同时可以通过startingIndex指定数组位置创建Cartesian2点。
var array = [1.0, 2.0];
var p = SuperMap3D.Cartesian2.fromArray(array);
console.log("array=",array,"p=",p);
var array2 = [0.0, 0.0, 1.0, 2.0];
var startingIndex = 2;
var p2 = SuperMap3D.Cartesian2.fromArray(array2, startingIndex);
console.log("array2=",array2,"p2=",p2);
该方法从现有Cartesian3创建Cartesian2实例。取Cartesian3的x和y分量赋值,并去掉z分量的值。
var c3 = new SuperMap3D.Cartesian3(5, 6, 7);
var c2 = SuperMap3D.Cartesian2.fromCartesian3(c3);
console.log("Cartesian3=", c3, "Cartesian2=", c2);
该方法从现有Cartesian4创建Cartesian2实例。取Cartesian4的x和y分量赋值,并去掉z、w分量的值。
var c4 = new SuperMap3D.Cartesian4(5, 6, 7, 1);
var c2 = SuperMap3D.Cartesian2.fromCartesian4(c4);
console.log("Cartesian4=", c4, "Cartesian2=", c2);
该方法可通过x,y坐标值构建Cartesian2实例
var x = 1;
var y = 2;
var result = SuperMap3D.Cartesian2.fromElements(x, y)
console.log("x=", x, "y=", y, "result=", result);
该方法可以将各分量求绝对值。
var c2 = new SuperMap3D.Cartesian2(-3, -4);
var result = new SuperMap3D.Cartesian2();
SuperMap3D.Cartesian2.abs(c2,result)
console.log("c2===",c2,"result===",result);
该方法可以将各分量相加
var c2a = new SuperMap3D.Cartesian2(1, 2);
var c2b = new SuperMap3D.Cartesian2(12, 24);
var result = new SuperMap3D.Cartesian2();
SuperMap3D.Cartesian2.add(c2a, c2b,result)
console.log("c2a===",c2a,"c2b===",c2b,"result===",result);
该方法可以对两个矢量中各分量进行相减
var first = new SuperMap3D.Cartesian2(10, 5);
var second = new SuperMap3D.Cartesian2(10, 3);
var result = new SuperMap3D.Cartesian2();
SuperMap3D.Cartesian2.subtract(first, second, result)
console.log("first=", first, "second=", second, "result=", result);
该方法可以求得两向量之间的弧度值
var c2a = new SuperMap3D.Cartesian2(1, 0);
var c2b = new SuperMap3D.Cartesian2(0, 1);
var c2c = new SuperMap3D.Cartesian2(1, 1);
var angleab = SuperMap3D.Cartesian2.angleBetween(c2a, c2b);
var angleac = SuperMap3D.Cartesian2.angleBetween(c2a, c2c);
console.log("c2a=",c2a,"c2b=",c2b,"弧度值angleab=",angleab,"角度值",SuperMap3D.Math.toDegrees(angleab));
console.log("c2a=",c2a,"c2c=",c2c,"弧度值angleac=",angleac,"角度值",SuperMap3D.Math.toDegrees(angleac));
该方法可以求得两个向量之间的距离。距离公式参考向量距离公式运算
var c2a = new SuperMap3D.Cartesian2(1, 0);
var c2b = new SuperMap3D.Cartesian2(0, 1);
var c2c = new SuperMap3D.Cartesian2(1, 1);
var dab = SuperMap3D.Cartesian2.distance(c2a, c2b);
var dac = SuperMap3D.Cartesian2.distance(c2a, c2c);
console.log("c2a=", c2a, "c2b=", c2b, "distance_a_b=", dab);
console.log("c2a=", c2a, "c2c=", c2c, "distance_a_c=", dac);
该方法可以将各分量进行求商。
var c2a = new SuperMap3D.Cartesian2(18, 14);
var c2b = new SuperMap3D.Cartesian2(2, 7);
var result = new SuperMap3D.Cartesian2();
SuperMap3D.Cartesian2.divideComponents(c2a, c2b, result)
console.log("c2a:", c2a, "c2b:", c2b, "result:", result);
该方法可以将各分量与指定数值进行求商
var c2 = new SuperMap3D.Cartesian2(13, 14);
var scalar = 2;
var result = new SuperMap3D.Cartesian2();
SuperMap3D.Cartesian2.divideByScalar(c2, scalar, result)
console.log("c2:", c2, "scalar:", scalar, "result:", result);
对两个矢量进行点乘
var c2a = new SuperMap3D.Cartesian2(2, 4);
var c2b = new SuperMap3D.Cartesian2(2, 1);
var result = SuperMap3D.Cartesian2.dot(c2a, c2a)
console.log("c2a:", c2a, "c2b:", c2b, "result:", result);
该方法可以求得两个向量距离的平方。
var c2a = new SuperMap3D.Cartesian2(1, 0);
var c2b = new SuperMap3D.Cartesian2(0, 1);
var c2c = new SuperMap3D.Cartesian2(1, 1);
var dab = SuperMap3D.Cartesian2.distanceSquared(c2a, c2b);
var dac = SuperMap3D.Cartesian2.distanceSquared(c2a, c2c);
console.log("c2a=", c2a, "c2b=", c2b, "distanceSquared_a_b=", dab);
console.log("c2a=", c2a, "c2c=", c2c, "distanceSquared_a_c=", dac);
该方法可以对向量进行lerp插值运算 公式:Lerp(A, B, β)= (A-B)β+B
var c2a = new SuperMap3D.Cartesian2(1, 0);
var c2b = new SuperMap3D.Cartesian2(0, 1);
var result = new SuperMap3D.Cartesian2();
var t = 1;
SuperMap3D.Cartesian2.lerp(c2a, c2b, t, result);
console.log("c2a=", c2a, "c2b=", c2b, "t=", t, "result=", result);
该方法可以计算向量的大小
var c2 = new SuperMap3D.Cartesian2(-1,-1);
var length = SuperMap3D.Cartesian2.magnitude(c2)
console.log("c2=", c2, "length=", length);
该方法可以计算向量的大小的平方
var c2 = new SuperMap3D.Cartesian2(-1,-1);
var magnitudeSquared = SuperMap3D.Cartesian2.magnitudeSquared(c2)
console.log("c2=", c2, "magnitudeSquared=", magnitudeSquared);
该方法可以将向量中的各分量乘以指定值scalar
var c2 = new SuperMap3D.Cartesian2(10, 5);
var scalar = 2;
var result = new SuperMap3D.Cartesian2();
SuperMap3D.Cartesian2.multiplyByScalar(c2, scalar, result)
console.log("c2=", c2, "scalar=", scalar, "result=", result);
该方法可以将两向量中的各分量进行相乘
var first = new SuperMap3D.Cartesian2(10, 5);
var second = new SuperMap3D.Cartesian2(2, 3);
var result = new SuperMap3D.Cartesian2();
SuperMap3D.Cartesian2.multiplyComponents(first, second, result)
console.log("first=", first, "second=", second, "result=", result);
该方法可以对向量的值取反
var c2 = new SuperMap3D.Cartesian2(10, 5);
var result = new SuperMap3D.Cartesian2();
SuperMap3D.Cartesian2.negate(c2, result);
该方法可以对向量进行归一化处理
var c2 = new SuperMap3D.Cartesian2(10, 5);
var result = new SuperMap3D.Cartesian2();
SuperMap3D.Cartesian2.normalize(c2, result);
console.log("c2=", c2, "result=", result);
该方法可以复制一个Cartesia2实例。
//方法一
var c2 = new SuperMap3D.Cartesian2(100, 100);
var c2Clone = c2.clone(c2Clone);
//方法2
var result = new SuperMap3D.Cartesian2();
SuperMap3D.Cartesian2.clone(c2, result)
console.log("c2===", c2, "c2Clone===", c2Clone);
该方法用来判断两个Cartesia2示例是否相等。
我们这里创建3个示例,其中c2a 和c2c相同,与c2b不同。通过该方法可以判断是否相同。
var c2a = new SuperMap3D.Cartesian2(100, 100);
var c2b = new SuperMap3D.Cartesian2(50, 100);
var c2c = new SuperMap3D.Cartesian2(100, 100);
var b1 = c2a.equals(c2b);
var b2 = c2a.equals(c2c);
console.log("b1===",b1,"b2===",b2);
//方法2
SuperMap3D.Cartesian2.equals(c2a, c2b)
将两个Cartesian示例进行比较。判断在误差允许内是否相同。
var c2a = new SuperMap3D.Cartesian2(1, 1);
var c2b = new SuperMap3D.Cartesian2(1.01, 1.01);
var c2c = new SuperMap3D.Cartesian2(1.001, 1.001);
var b1 = c2a.equalsEpsilon(c2b,0.001)
var b2 = c2a.equalsEpsilon(c2c,0.001)
console.log("b1===",b1,"b2===",b2);
//方法2
SuperMap3D.Cartesian2.equalsEpsilon(c2a,c2b,0.001)
可以发现在误差的允许范围内,我们c2c是与c2a数据相同的。
该方法可以返回两个Cartesian2中最大的Cartesian2
var first = new SuperMap3D.Cartesian2(1, 1);
var second = new SuperMap3D.Cartesian2(2, 2);
var result = new SuperMap3D.Cartesian2();
SuperMap3D.Cartesian2.maximumByComponent(first, second, result)
console.log("first=", first, "second=", second, "result=", result);
该方法可以返回两个Cartesian2中最小的Cartesian2
var first = new SuperMap3D.Cartesian2(1, 1);
var second = new SuperMap3D.Cartesian2(2, 2);
var result = new SuperMap3D.Cartesian2();
SuperMap3D.Cartesian2.minimumByComponent(first, second, result)
console.log("first=", first, "second=", second, "result=", result);
该方法可以返回Cartesian2实例中最大的分量值
var c2 = new SuperMap3D.Cartesian2(10, 5);
var Number = SuperMap3D.Cartesian2.maximumComponent(c2);
console.log("c2=", c2, "Number=", Number);
该方法可以返回Cartesian2实例中最小的分量值
var c2 = new SuperMap3D.Cartesian2(10, 5);
var Number = SuperMap3D.Cartesian2.minimumComponent(c2);
console.log("c2=", c2, "Number=", Number);
该方法可以返回最正交的轴,相当于该向量最垂直的轴
var c2 = new SuperMap3D.Cartesian2(10, 5);
var result = new SuperMap3D.Cartesian2();
SuperMap3D.Cartesian2.mostOrthogonalAxis(c2, result)
console.log("c2=", c2, "result=", result);
该方法可以将实例对象转换为字符串类型,目前看来感觉作用不大。
var c2 = new SuperMap3D.Cartesian2(1, 1);
var c2String = c2.toString();
console.log("c2===", c2, "c2String===", c2String);
该方法可以将Cartesian2存入数组中,或存入数组指定位置
var c2 = new SuperMap3D.Cartesian2(10, 5);
var array = [];
SuperMap3D.Cartesian2.pack(c2, array)
console.log("c2=", c2, "array=", array);
// return array = [10, 5]
var array2 = [1, 1, 2, 2, 3, 5, 5];
var startingIndex = 2;
SuperMap3D.Cartesian2.pack(c2, array2, startingIndex)
console.log("c2=", c2, "array2=", array2);
// return array2 = [1, 1, 10, 5, 3, 5, 5]
该方法可以将包含多个Cartesian2实例的数组转换为普通数组
var c2a = new SuperMap3D.Cartesian2(10, 5);
var c2b = new SuperMap3D.Cartesian2(15, 7);
var c2c = new SuperMap3D.Cartesian2(20, 9);
var array = [c2a, c2b, c2c];
var result = [];
SuperMap3D.Cartesian2.packArray(array, result)
console.log("c2a=", c2a, "c2b=", c2b, "c2c=", c2c, "array=", array, "result=", result);
// return result = [10, 5, 15, 7, 20, 9]
该方法可以将数组中指定索引的数值创建Cartesian2实例
var array = [10, 5, 15, 7, 20, 9];
var startingIndex = 2;
var result = new SuperMap3D.Cartesian2();
SuperMap3D.Cartesian2.unpack(array, startingIndex, result)
console.log("result=", result);
该方法可以将普通数组转换为Cartesian2实例数组,注:数组数量必须为双数,否则会失败
var array = [10, 5, 15, 7, 20, 9];
var resultA = [];
SuperMap3D.Cartesian2.unpackArray(array, resultA)
console.log("array=",array,"resultA=", resultA);
上述关于二维笛卡尔坐标系目前就介绍到这里。关于坐标系&位置的综合应用,欢迎收看下一期!