Points in an array being interpolated

I am currently working with data points that define 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
    },
    ...
]

Although these values have been obtained from IAU quoted sources, my task is to calculate the "great circle distance" or orthodromic distance between each pair of consecutive points i and i+1. This involves interpolating between point i and point i+1 at a specified precision x.

To achieve this, I have developed a function specifically designed for this interpolation operation in Equatorial Coordinates. The function is written in Typescript ES6 as follows:

/**
 * 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

  // Calculate the 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))

  // Calculate the rate of change of dec:
  const ddec: number = ndec / precision
  
  // Interpolated calculation for each step:
  let i = 0
  while (i < precision) {
    i++
    points.push({
      ra: start.ra + (dra * i),
      dec: start.dec + (ddec * i)
    })
  }

  return points
}

In order to validate the mathematical accuracy of this function, I conducted tests using the first two points from the 'boundaries' array:

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)

  // Assertions for validation
})

The resulting interpolated points are detailed below:

[
      { ra: 344.4530585, dec: 36.968215199999996 },
      { ra: 344.44081324999996, dec: 38.7681946 },
      ...
]

Question:

My next objective is to apply the interpolation process to all points in the 'boundaries' array, combining them into one cohesive array. What method would be best suited for achieving this? Although I attempted to utilize the Array.prototype.map method, I encountered difficulties...

The desired output format should resemble the following structure based on the initial 'boundaries' array:

let boundaries = [
    {
      ra: 344.46530375,
      dec: 35.1682358
    },
    ...
]

let desiredOutput = [
  {
    ra: 344.46530375,
    dec: 35.1682358
  }, 
  // Intermediate interpolated values
  {
    ra: ...,
    dec: ...
  },
  ...
]

Answer №1

I believe that implementing Array.reduce() would be the most effective approach in this scenario.

Consider creating a function that accepts an array of boundaries and a precision value to generate the desired EquatorialCoordinate array:

const fillInBoundryPoints = (boundaries: EquatorialCoordinate[], precision: number) => {
  return boundaries.reduce((acc, cur, i, arr) => {
    if (i < arr.length - 1) {
      acc.push(cur)
      acc.push(...getInterpolatedEquatorialCoordinates(cur, arr[i + 1], precision))
    }
    return acc
  }, [] as EquatorialCoordinate[])
}

This function can then be utilized as follows:

const precision = 10

const boundaries: EquatorialCoordinate[] = [
  {
    ra: 344.46530375,
    dec: 35.1682358
  },
  {
    ra: 344.34285125,
    dec: 53.1680298
  }
]

const desiredOutput = fillInBoundryPoints(boundaries, precision)

The generated output would be:

[
  { ra: 344.46530375, dec: 35.1682358 },
  { 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 }
]

Answer №2

Instead of utilizing the map function, it is recommended to use the reduce function in this particular situation

boundaries.reduce((accumulator, currentPoint, index, array) => {
  if (index > 0 ) {
    accumulator.push(getInterpolatedEquatorialCoordinates(array[index-1], currentPoint, precision))
  }
  return accumulator;
}, [])

IMPORTANT: When using the map function, you will need to look ahead for the previous value instead of retrieving it directly like with reduce. This might result in an undefined value at the end that needs to be removed by slicing.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Learn how to customize button styles in ExtJS with the pressedCls configuration option

Is there a way to change the color when a button is pressed? I tried using the pressedCls config but it didn't work. How can I fix this issue or is there another method to set the CSS when a button is pressed? Thank you so much! Javascript: Ext.crea ...

What is the method for displaying a div adjacent to a password input field?

I am attempting to display a password verification box next to an input field. The current logic is functioning properly, but the box containing all password requirements is not appearing in the correct position. Instead of being positioned adjacent to the ...

Steer clear of utilizing the "any" type in your Express.js application built with

I have a node/express/typescript method that looks like this: // eslint-disable-next-line export const errorConverter = (err: any, req: any, res: any, next: any) => { let error = err if (!(error instanceof ApiError)) { const statusCode = e ...

Updating an object with AngularJS

Let's consider the code snippet below: var absenceType = {name: 'hello'}; this.newAbsenceType = angular.copy(absenceType); After making changes to this.newAbsenceType, you want to apply these changes to the original object. I have explore ...

I seem to be missing some properties in the request body schema. Why am I receiving an incomplete model for

Seeking assistance in grasping the working of models in loopback4. Here's a model I defined: @model() export class ProductViewConfig extends BaseConfig { @property({ type: 'string', id: true, generated: true, }) _id?: strin ...

Using the foreach Loop in Javascript and AngularJs

Having trouble with a foreach loop because you're not sure of the column name to access specific data? Here's a solution to display all columns along with their corresponding data: angular.forEach(data, function(value, key) { console.log( &a ...

Troubleshooting a problem with selecting options in Jquery

Looking for assistance with a jquery script. I have a select dropdown that fetches a list of options via Ajax. When a user clicks on an option, if a certain variable equals 1, an HTML div is added. If the variable changes to another value, the HTML div dis ...

Stop angular schema form's destroyStrategy from deleting any data

After upgrading my Angular app from version 0.8.2 to 0.8.3 of Angular Schema Form (ASF), a significant bug emerged. The application features multi-page forms that utilize prev/next buttons for navigation. A condition is implemented to display only relevan ...

ConfirmUsername is immutable | TypeScript paired with Jest and Enzyme

Currently, I am experimenting with Jest and Enzyme on my React-TS project to test a small utility function. While working on a JS file within the project, I encountered the following error: "validateUsername" is read-only. Here is the code for the utilit ...

Inability to assign a value to an @input within an Angular project

I recently started using Angular and I'm currently trying to declare an input. Specifically, I need the input to be a number rather than a string in an object within an array. However, I'm encountering difficulties and I can't figure out wha ...

Having difficulty installing the yarn package from GitHub

I'm attempting to install a GitHub package using yarn. I've tried this process many times before, but I have not been successful with this particular repository: https://github.com/coolwanglu/pdf2htmlEX I have already attempted the following w ...

top technique for chaining promises in a sequence

At the moment, I have several functions that return promises like the example below: function action_one(){ return new Promise((resolve, reject)->{ ... }); } I am looking for a way to wait for one promise to finish before moving on to t ...

How can I retrieve data from local storage based on a specific key value using a query?

In order to optimize the storage of data for my app, I have successfully stored a large amount in local storage. Now, I am faced with the task of fetching data in an array but only selecting key/values that are specifically chosen, rather than all or jus ...

Using TypeORM: Implementing a @JoinTable with three columns

Seeking assistance with TypeORM and the @JoinTable and @RelationId Decorators. Any help answering my question, providing a hint, or ideally solving my issue would be greatly appreciated. I am utilizing NestJS with TypeORM to create a private API for shari ...

Angular time-based polling with conditions

My current situation involves polling a rest API every 1 second to get a result: interval(1000) .pipe( startWith(0), switchMap(() => this.itemService.getItems(shopId)) ) .subscribe(response => { console.log(r ...

What is the best way to create a variable in a React component that requires asynchronously loaded data in order to be functional?

While I have a good understanding of passing data from one component to another using this.props, I am encountering difficulty in asynchronously fetching and storing values, such as from a database, that need to be accessed throughout the component. The ch ...

Using JavaScript to display a selection of objects from an array: showcasing x out of x items

What is the most efficient method for sorting or querying an array of objects using JavaScript? For example, how can I retrieve only the first two objects, followed by the next two, or obtain 5 objects starting from the 5th position? Which specific functi ...

Is there a way to access an Excel file with JavaScript without relying on the ActiveX control?

Is there a way to access an Excel document using JavaScript code without relying on an ActiveX control object such as shown below: var myApp = new ActiveXObject("Excel.Application"); myApp.workbooks.open("test.xls"); ...

Making an AJAX request in Javascript to retrieve multiple values using the HTTP method 'GET' from a URL

xmlhttp.open("POST","BAConsultRecordsAJAX.php?q="+str,true); Could this be achieved? xmlhttp.open("GET","BAConsultRecordsAJAX.php?q="+str+"j="+str2,true); I need to have values stored in both q and j fields. ...

Guide: Enhancing Query Context within jQuery Instances Spanning Across Iframes

In my current project, I am facing a challenge with using a jQuery instance across iframes. It's been causing me quite a bit of frustration. Here's the situation: I have an existing web application that loads jQuery (which is aliased as $jq) in ...