Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

145
Views
Find minimum and maximum numbers of Math.sin()

Imagine that there is a pendulum swinging from -1 to 1:

enter image description here

This pendulum is equivalent to SINE. Imagine also that this pendulum is swinging quite fast in an update loop of 60fps.

This might be my code:

let angle = 0

function update() {
    angle += .1

    pendulum.angle = Math.sin(angle)

    requestAnimationFrame(update)
}

update()

That's all fine. What I want is to detect the point at which this pendulum is closest to -1 or 1. One may think you could just write:

if (pendulum.angle == -1 || pendulum.angle == 1) {
    console.log('pendulum is at it\'s maximum')
}

However, it doesn't quite work like that: If the pendulum's speed was moving quite fast, it may miss -1 or 1 completely! Another seemingly possible solution is to detect if the pendulum is within a certain range and if so, raise the message:

if (pendulum.angle < -0.9 || pendulum.angle > 0.9) {
    console.log('pendulum is at it\'s maximum')
}

...But what if the speed was going really, really fast? What if it missed those ranges?

The angle's getting bigger is being restricted to the programs framerate - so the faster it spins, the more space it skips.

This leads to the question: What formula could I use to find out how large the range should be - based on it's speed?

Any help would be appreciated.

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

Compute the current value's sin as well as that of the preceding and subsequent values. If your sin value is closer to -1 or 1 than that of the preceding and subsequent values, you're the closest, do your logging.

function update() {
    lastanglemag = Math.abs(Math.sin(angle));  // Get the preadjustment magnitude

    angle += .1

    pendulum.angle = Math.sin(angle)

    currentanglemag = Math.abs(pendulum.angle)  // Get current magnitude

    // If current magnitude is larger than both neighbors, we're at a maximum
    if (currentanglemag > lastanglemag && currentanglemag > Math.abs(Math.sin(angle + 0.1))) {
        console.log("pendulum is at its maximum")
    }

    requestAnimationFrame(update)
}

update()

Optimizations to only compute one new sin per update (the one for the next angle), caching the other values, to reduce 2-3 sin calls per update to just one are left as an exercise for the reader (I didn't want to introduce any additional persistent state and the associated complexity, and in practice, for anything based on a GUI, the cost of 1-2 extra sin computations is meaningless; the user can't see a delay measured in nanoseconds anyway).

about 4 years ago · Juan Pablo Isaza Report

0

Using that d/dx sin(x) = cos(x), one could simplify the other answer to

function update() {
    lastangle_d = Math.cos(angle);     // Get the preadjustment derivative

    angle += .1

    pendulum.angle = Math.sin(angle);

    currentangle_d = Math.cos(angle);  // Get current derivative

    // If signum of current and previous derivatives differ, we've passed a maximum
    if (Math.sign(lastangle_d) !== Math.sign(currentangle_d)) {
        console.log("pendulum is at its maximum")
    }

    requestAnimationFrame(update);
}

update();

If someone really wants to hack, if (lastangle_d*currentangle_d < 0) could do that too.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!