지표면의 Alt / Az 좌표에서 (x, y, z) wrt 지구 중심으로 변환 하시겠습니까?
나는 지구 표면에 위치한 안테나가 고도와 방위각을 통해 우주에서 물체를 가리키는 방법을 알고 있습니다.
뾰족한 개체를 3D보기로 표시하고 싶습니다. 이해할 수있는 한 (x, y, z) 형식 (Cartesian3 개체?)의 위치가 필요합니다.
하지만 정확히 어떤 과정을 따라야할지 정확히 이해할 수 없습니다.
실험을 위해 CesiumJS 라이브러리 를 사용 하는 이 예제를 사용 하고 있습니다 . addMultiplePoints () 함수 안에 다음 줄을 추가하여 표면에 한 점을 추가했습니다.
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(290.6, -35.78),
point: {
color: Cesium.Color.RED,
pixelSize: 18,
},
label: {
text: "MLG",
font: "14px Helvetica",
pixelOffset: new Cesium.Cartesian2(0.0, 20),
},
description : "MLG"
});
이제이 지점에 특정 위치가있는 지점을 추가해야합니다 (예 : Alt = 30, Az = 0).
나는 이것을 시도하고있다 ... 그러나 아무 일도 일어나지 않는다; 실제로이 코드에는 좌표의 원점이 없습니다.
H2pointing = {"alt" : 30, "az" : 0};
clock = 90 - H2pointing.az;
cone = 90 - H2pointing.alt;
H2spherical = new Cesium.Spherical(clock, cone, 10);
console.log(clock);
console.log(cone);
console.log(H2spherical);
H2cartesian = Cesium.Cartesian3.fromSpherical(H2spherical, null);
viewer.entities.add({
position: H2cartesian,
point: {
color: Cesium.Color.BLUE,
pixelSize: 18,
},
label: {
text: "Hayabusa2",
font: "14px Helvetica",
pixelOffset: new Cesium.Cartesian2(0.0, 20),
},
description : "Hayabusa2"
});
따라서 내 계산이 옳다고 가정하면 (그렇습니까?)이 지점을 이전 지점의 중심에 어떻게 배치합니까?
다른 방법을 사용할 수 있습니다.
Cesium.Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result)
Roll = 0을 지정하면 고도와 방위각에 해당하는 값을 얻어야합니다.
하지만이 경우에도이 변환을 포인트에 적용하는 방법은 무엇입니까?
headingPitchRollToFixedFrame 제공된 타원체의 고정 된 참조 프레임에 대해 제공된 원점을 중심으로하는 헤딩 피치 롤 각도에서 계산 된 축이있는 참조 프레임에서 4x4 변환 행렬을 계산합니다. 방향은 양의 각도가 동쪽으로 증가하는 지역 북쪽 방향에서 회전하는 것입니다. 피치는 로컬 동북 평면에서의 회전입니다. 양의 피치 각도는 평면 위에 있습니다. 음의 피치 각도는 평면 아래에 있습니다. 롤은 로컬 동쪽 축을 기준으로 적용되는 첫 번째 회전입니다.
답변
원점에서 새 점을 계산하려면 원점에서 해당 점까지의 거리도 필요합니다. 여기서는 사용 가능한 거리 값이 있다고 가정했습니다.
옵션은 원점과 벡터에서 목표 지점을 계산하는 함수를 만드는 것입니다.
function CalcPosFromAltAzDist(startPoint, vectorPointing) {
var ellipsoid = Cesium.Ellipsoid.WGS84;
var ENU = new Cesium.Matrix4();
Cesium.Transforms.eastNorthUpToFixedFrame(startPoint,ellipsoid,ENU);
var myX = vectorPointing.dist * Math.cos(vectorPointing.alt * Math.PI / 180) * Math.sin(vectorPointing.az * Math.PI / 180);
var myY = vectorPointing.dist * Math.cos(vectorPointing.alt * Math.PI / 180) * Math.cos(vectorPointing.az * Math.PI / 180);
var myZ = vectorPointing.dist * Math.sin(vectorPointing.alt * Math.PI / 180);
var offset = new Cesium.Cartesian3(myX,myY,myZ);
var finalPoint = Cesium.Matrix4.multiplyByPoint(ENU, offset, new Cesium.Cartesian3());
return finalPoint;
}
이 방법 eastNorthUpToFixedFrame
을 사용하여 원점의 로컬 ENU 프레임에서 변환 행렬을 계산하고이를 데카르트 오프셋과 함께 사용하여 최종 점을 계산했습니다.
그런 다음 포인트를 추가 할 때 해당 함수를 호출 할 수 있습니다.
function addMultiplePoints() {
Sandcastle.declare(addMultiplePoints);
var origin = Cesium.Cartesian3.fromDegrees(290.6, -35.78);
viewer.entities.add({
position: origin,
point: {
color: Cesium.Color.RED,
pixelSize: 18,
},
label: {
text: "MLG",
font: "14px Helvetica",
pixelOffset: new Cesium.Cartesian2(0.0, 20),
},
description : "MLG"
});
var H2pointing = {"alt" : 30, "az" : 0, "dist" : 150};
viewer.entities.add({
position: new CalcPosFromAltAzDist(origin, H2pointing),
point: {
color: Cesium.Color.BLUE,
pixelSize: 18,
},
label: {
text: "Hayabusa2",
font: "14px Helvetica",
pixelOffset: new Cesium.Cartesian2(0.0, 20),
},
description : "Hayabusa2"
});
}
@FSimardGIS를 기반으로 다른 독자가 솔루션 구현 방법을 더 잘 이해할 수 있도록 많은 주석이 포함 된 작은 코드 스 니펫을 준비했습니다.
function CalcPosFromAltAzDist(center, vectorPointing) {
// Extract single data from input:
var Altitude = vectorPointing.alt * Math.PI / 180;
var Azimuth = vectorPointing.az * Math.PI / 180;
var Length = vectorPointing.dist;
// Calculate cartesian coordinate of a point on a generic sphere
// of radius = length and centered on (0,0,0):
var genericX = Length * Math.cos(Altitude) * Math.sin(Azimuth);
var genericY = Length * Math.cos(Altitude) * Math.cos(Azimuth);
var genericZ = Length * Math.sin(Altitude);
// Assign the coordinates to a Cartesian3 object:
var floatingPoint = new Cesium.Cartesian3(genericX, genericY, genericZ);
// Setup function to turn generic coordinates into
// referenced coordinates:
var toENU = Cesium.Transforms.eastNorthUpToFixedFrame(center);
// Put the point into a reference system (East-North-Up):
var referencedPoint = Cesium.Matrix4.multiplyByPoint(toENU, floatingPoint, new Cesium.Cartesian3());
return referencedPoint;
}
호출 예 :
// Position on surface in degrees and meters:
var origin = Cesium.Cartesian3.fromDegrees(lon, lat, alt);
// Location to point at:
var pointing = {"alt" : alt, "az" : az, "dist" : 7000000000};
// Calculate position of pointed location w.r.t
// a specified point (origin):
var pos = new CalcPosFromAltAzDist(origin, pointing);
새 기준 좌표계에서 지정된 위치의 위치가 계산되면 기준 좌표계의 원점에서 점까지 화살표를 그릴 수도 있습니다.
var pointer = viewer.entities.add({
name: "Arrow",
polyline: {
positions: [
origin,
pos,
],
width: 1,
arcType: Cesium.ArcType.NONE, // straight line, not arc
},
});
샌드캐슬의 전체 예제 : 링크