I have the following data points that represent the boundaries of a constellation.
let boundaries = [
{
ra: 344.46530375,
dec: 35.1682358
},
{
ra: 344.34285125,
dec: 53.1680298
},
{
ra: 351.45289375,
dec: 53.1870041
},
...
]
Irrelevant, but these have been extracted from IAU quoted values.
However. Between each of these points I need what is known as the "great circle distance" - or the orthodromic distance, between point i and point i+1. To do that, we can interpolate between point i and point i+1 at a given precision, x.
I have written the following function which can perform this operation (it's worth noting that is done in Equatorial Coordinates - not Cartesian - so the Mathematics is slightly more complex, but not massively so).
The function for interpolate between two points is as follows (written in Typescript ES6 for prosperity and safety):
/**
* getInterpolatedEquatorialCoordinates()
*
* @description This function takes in a start and end
* @param start EquatorialCoordinate
* @param end EquatorialCoordinate
* @param precision number
* @output returns the interpolated array of []EquatorialCoordinate points:
*/
export const getInterpolatedEquatorialCoordinates = (
start: EquatorialCoordinate,
end: EquatorialCoordinate,
precision: number
): Array<EquatorialCoordinate> => {
// The interpolated points array to return:
const points: Array<EquatorialCoordinate> = []
// Obtain the difference between the end coordinate's Right Ascension, RA, and the start coordinate's RA:
let nra = ((end.ra - start.ra)) % 360
if (nra > 180) nra = nra - 360
if (nra < -180) nra = nra + 360
// Obtain the "gradient" rate of change of RA:
const dra: number = nra / precision
// Obtain the difference between the end coordinate's Declination, dec, and the start coordinate's dec:
const ndec = ((end.dec - start.dec))
// Obtain the "gradient" rate of change of dec:
const ddec: number = ndec / precision
let i = 0
// Obtain the interpolated EquatorialCoordinate points for each step:
while (i < precision) {
i++
points.push({
ra: start.ra + (dra * i),
dec: start.dec + (ddec * i)
})
}
return points
}
I have run this through a test suit, between the first two points of the above boundaries, to obtain it's validity Mathematically:
test('getInterpolatedEquatorialCoordinates', function () {
const start = {
ra: 344.46530375,
dec: 35.1682358
}
const end = {
ra: 344.34285125,
dec: 53.1680298
}
const minRA = Math.min(start.ra, end.ra)
const minDec = Math.min(start.dec, end.dec)
const maxRA = Math.max(start.ra, end.ra)
const maxDec = Math.max(start.ra, end.ra)
const precision = 10
const points = getInterpolatedEquatorialCoordinates(start, end, precision)
const isRAAboveLowerThreshold = (
p: EquatorialCoordinate
) => p.ra >= minRA
const isRABelowUpperThreshold = (
p: EquatorialCoordinate
) => p.ra <= maxRA
const isDecAboveLowerThreshold = (
p: EquatorialCoordinate
) => p.dec >= minDec
const isDecBelowUpperThreshold = (
p: EquatorialCoordinate
) => p.dec <= maxDec
expect(points.length).toBeGreaterThan(0)
expect(points.length).toBe(precision)
expect(points.every(isRAAboveLowerThreshold)).toBe(true)
expect(points.every(isRABelowUpperThreshold)).toBe(true)
expect(points.every(isDecAboveLowerThreshold)).toBe(true)
expect(points.every(isDecBelowUpperThreshold)).toBe(true)
})
The interpolated outputted points are as follows:
[
{ ra: 344.4530585, dec: 36.968215199999996 },
{ ra: 344.44081324999996, dec: 38.7681946 },
{ ra: 344.428568, dec: 40.568174 },
{ ra: 344.41632275, dec: 42.3681534 },
{ ra: 344.40407749999997, dec: 44.168132799999995 },
{ ra: 344.39183225, dec: 45.9681122 },
{ ra: 344.379587, dec: 47.7680916 },
{ ra: 344.36734175000004, dec: 49.568071 },
{ ra: 344.3550965, dec: 51.3680504 },
{ ra: 344.34285125, dec: 53.1680298 }
]
This seems to work for any precision to a good degree of accuracy that I am happy with, it also works regardless of which "direction" we're going.
Question:
What I want to do now is to apply this to the above boundaries array, for every point, returning a new array of all of the points combined as one ...
What would be the best way to achieve this? I've tried using the Array.prototype.map method, but to zero success ...
The desired output is as follows for the following "boundaries":
let boundaries = [
{
ra: 344.46530375,
dec: 35.1682358
},
{
ra: 344.34285125,
dec: 53.1680298
},
...
]
let desiredOutput = [
{
ra: 344.46530375,
dec: 35.1682358
}, // Original Index 0
// Start Interpolated Intermediary Values
{
ra: 344.4530585,
dec: 36.968215199999996
},
{
ra: 344.44081324999996,
dec: 38.7681946
},
{
ra: 344.428568,
dec: 40.568174
},
{
ra: 344.41632275,
dec: 42.3681534
},
{
ra: 344.40407749999997,
dec: 44.168132799999995
},
{
ra: 344.39183225,
dec: 45.9681122
},
{
ra: 344.379587,
dec: 47.7680916
},
{
ra: 344.36734175000004,
dec: 49.568071
},
{
ra: 344.3550965,
dec: 51.3680504
},
{
ra: 344.34285125,
dec: 53.1680298
},
// End Interpolated Intermediary Values
{
ra: 344.34285125,
dec: 53.1680298
}, // Original Index 1
...
]