How to obtain inverse result of d3-ease interpolation? [duplicate] - javascript

With d3.js we can achieve eased time out of normalized time t, typically in the range [0,1]
For example:
d3.easeCubic(0.25) = 0.0625
How can we reverse that, how can we find x given known y ?
d3.easeCubic(X) = 0.0625,
X ???
The answer here is cubic root, but still.
The problem is in reusability, ease function can change to d3.easeExpIn, or `d3.easeCircleOut, or any other, do you need to invent reverse functions on your own, or are they hidden anywhere ?

Firstly, your math is wrong. d3.easeCubic(0.25) will give you 0.0625:
var easy = d3.easeCubic(0.25);
console.log(easy);
<script src="https://d3js.org/d3.v4.min.js"></script>
Now, back to your question:
How can we reverse that, how can we find x given known y?
There is no native solution, but we can create our own function to find X given a known Y. The problem, of course, is that we have to invert the math for each specific easing... But, since you asked about d3.easeCubic, which is the same of d3.easeCubicInOut, let's try to create an inverted function for that particular easing.
First step, let's have a look at the source code:
export function cubicInOut(t) {
return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2;
}
You can easily see that this is the correct function, giving us the same value as the first snippet:
function cubicInOut(t) {
return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2;
}
console.log(cubicInOut(0.25))
Now, let's try to invert it.
The math here is somehow complicated, but for values less than 1, here is the function:
function inverseEaseCubic(t){
return Math.cbrt(t * 2) / 2;
}
And here is the demo. We pass 0.0625 to the function, and it returns 0.25:
function inverseEaseCubic(t){
return Math.cbrt(t * 2) / 2;
}
console.log(inverseEaseCubic(0.0625))
If you want to deal with numbers bigger than 1, this is the complete function:
function InverseEaseCubic(t){
return t <= 1 ? Math.cbrt(t * 2) / 2 : (Math.cbrt(2 * t - 2) + 2) / 2;
}
PS: In his comment, #altocumulus just reminded us that, sometimes, it's even impossible to find the value. Here is a very simple example. Suppose this function:
function exponentiation(a){
return a*a;
}
Now imagine that, when called with an unknown argument, the function returned 4. What's the argument? Can we find out? Impossible to determine, because second degree equations, like this one, have 2 roots:
console.log(exponentiation(2))//returns 4
console.log(exponentiation(-2))//also returns 4

I used the #Gerardo Furtado answer but the inverse function didn't work well so I wrote another
function cubicInOut(t) {
return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2;
}
function inverseEaseCubic(x) {
return x < .5 ? Math.cbrt(x / 4) : (2 - Math.cbrt(2 - 2 * x)) / 2;
}
console.log(inverseEaseCubic(cubicInOut(1)) === 1);
console.log(inverseEaseCubic(cubicInOut(0.6)) === 0.6);
console.log(inverseEaseCubic(cubicInOut(0.4)) === 0.4);
console.log(inverseEaseCubic(cubicInOut(0.1)) === 0.1);
console.log(inverseEaseCubic(cubicInOut(0)) === 0);

Related

How find square root n by computing the next Xi term on javascript

Write the function sqrt(A) for computing square root of positive real numbers using next numerical method xi+1 = (1/2) * (xi +(A/xi)). Where the A - input rial number;
On zero iteration next statements have been taken: x0 = A;
The error should be at least 10^-6
You could take the last value xi-1 and compare it with the new value xi instead of using a loop counter.
function sqrt(a, x = 1) { // take 1 for x(0) as start value for recursion
var y = (x + a / x) / 2; // prepare next value x(i+1)
if (x === y) { // exit condition
return x;
}
return sqrt(a, y); // tail call optimization
} // https://stackoverflow.com/q/310974/1447675
console.log(sqrt(2));
console.log(sqrt(10));
console.log(sqrt(9));
console.log(sqrt(25));
Looks like your requirement is not just finding the square root of a number. If by any chance that is your requirement, use Math.sqrt.
If your requirement is to implement a function to find the square root for educational purpose, what you need is to write a recursive function as below. Modify the code as required to support error at 10^-6
function sqrt(A, i = 0) {
if (i === 0)
return A;
let prev = sqrt(A, i - 1);
return 0.5 * (prev + (A / prev));
}
console.log(sqrt(2,1000));
console.log(sqrt(3,1000));
console.log(sqrt(9,1000));
console.log(sqrt(25,1000));

JavaScript - Factorial explanation

I wanted someone to basically help me understand what each line of code is doing and help me comment each line (if applicable) so that it can help explain to another person what it's doing. It'd be awesome if one can just give second eyes and ensure that the code is actually good - I'm trying to get my head around Factorial/Recursion, and did some research and found these solutions for this.
I was given this scenario:
For positive n, factorial is n! = n(n−1)!   (e.g. 5! = 5 * 4
* 3 * 2 * 1)*
Here's what I've found for this scenario:
// Prompt user to enter a number to calculate the factorial
var num = prompt("What number do you want to find the factorial of?");
var factorial = function(n) {
if (n == 0) {
return 1;
} else {
product = 1;
for (i = 1; i < n; i++) {
product *= i;
}
return product;
}
}
console.log(factorial(num));
Recursive
Create a recursive algorithm to calculate the factorial using every second
number as shown in examples below:
5! = 5 * 3 * 1 = 15
6! = 6 * 4 * 2 = 48
As for the cursive part, this is added onto the above code and is written in the following -
//  recursive
var factorial = function(n) {
if (n == 0) {
return 1;
} else {
return n * factorial(n - 1);
}
}
console.log(factorial(num));
Would appreciate your assistance on this - Apologies if this has already been answered, please direct me to another thread if this has been already posted. Thanks!
You don't need recursion for that:
/**
* Calculate factorial, optionally using a difference other than 1 with previous value.
* Example: factorial(6, 2) // 6*4*2 = 48
*/
var factorial = function(n, d) {
if (!d) {d = 1;}
var product = 1;
while (n > 1) {
product *= n;
n -= d;
}
return product;
};
console.log(factorial(6, 2)); // 48
console.log(factorial(6)); // 720
Note: Declare local variables inside the function with keyword 'var'. Otherwise they become globals and the second time you attempt to use a function may produce wrong results.
Usually, writing a function for Factorial is an exercise on writing recursive function. The first example code is not recursive and just an overly complicated way of calculating a factorial by multiplying the numbers iteratively so I'll skip that.
The second code is recursive, and it is following the recursive definition of factorial in your usual mathematics:
f: N => N, f(x) = x! = { x < 1 : 1, else : x (x - 1)! }
Or equivalently in JavaScript:
let fac = n => n < 1 ? 1 : n * fac(n - 1);
An expansion of an example computation would look like:
5!
5(4!)
5(4(3!))
5(4(3(2!)))
5(4(3(2(1))))
5(4(3(2(1(0!)))))
5(4(3(2(1(1)))))
120

what is animationTimingFunction in vivus.js

I was just going through the source of vivus.js and came across the followng like of code:
currentFrame = this.animTimingFunction(this.currentFrame / this.frameLength) * this.frameLength;
Now this function call can be seen HERE.
The only other place this is defined in is below:
this.animTimingFunction = options.animTimingFunction || Vivus.LINEAR;
This can be seen on the repo HERE.
Now my question is , why is this.animTimingFunction being called as a function when it actually is not a function ? can anybody explain ?
Thank you.
But it is a function as mentioned in the code comments
animTimingFunction <function> timing animation function for the complete SVG`
From the code it is one of the options that can be passed to the Vivus constructor. Predefined timing functions are defined at line 66
/**
* Timing functions
**************************************
*
* Default functions to help developers.
* It always take a number as parameter (between 0 to 1) then
* return a number (between 0 and 1)
*/
Vivus.LINEAR = function (x) {return x;};
Vivus.EASE = function (x) {return -Math.cos(x * Math.PI) / 2 + 0.5;};
Vivus.EASE_OUT = function (x) {return 1 - Math.pow(1-x, 3);};
Vivus.EASE_IN = function (x) {return Math.pow(x, 3);};
Vivus.EASE_OUT_BOUNCE = function (x) {
var base = -Math.cos(x * (0.5 * Math.PI)) + 1,
rate = Math.pow(base,1.5),
rateR = Math.pow(1 - x, 2),
progress = -Math.abs(Math.cos(rate * (2.5 * Math.PI) )) + 1;
return (1- rateR) + (progress * rateR);
};
On line 204
this.animTimingFunction = options.animTimingFunction || Vivus.LINEAR;
you can see that it either uses the passed function or when nothing is set for animTimingFunction a default function defined at Vivus.LINEAR
So you can not pass a function, pass one of the predefined functions, or pass your own timing function:
Vivus(...,{},...);
//OR
Vivus(...,{
animTimingFunction:Vivus.EASE
},...);
//OR
Vivus(...,{
animTimingFunction:Vivus.EASE_OUT
},...);
//OR
Vivus(...,{
//custom function
//input number between 0 and 1
//output number between 0 and 1
animTimingFunction:function(x){
//manipulate x as needed and return the new number
}
},...);

JavaScript Get Percentage

I am having a issue trying to work out the remaining percentage between 2 numbers.
I have worked out how to get the current percentage by using the following function:
function GetPercentage(x,y){
return ((x /y) * 100).toFixed(0);
}
The part I need help with is to get the remaining percentage.
For Example:
Lets say the maximum is 31 and I have a value of 1, how can I return the value 97%
Using my function above if I use GetPercentage(1,31) it would return 3.
However, I need help with the function to return 97.
I have tried using the following but doesn't seem to work.. I am guessing my Math isn't correct and hoping someone can correct me.
alert(GetPercentage(1,31) + "%" + " used. " + availablePercentage(5,31) + "% still available"); // trying to make it say: 3% used. 97% still available
function GetPercentage(x,y){
return ((x / y) * 100).toFixed(0);
}
function availablePercentage(x,y){
return ((y-x)/100).toFixed(0);
}
It sounds like you need to subtract the number you're computing from 100.
function availablePercentage(x,y){
return 100 - GetPercentage(x, y);
}
I believe a suitable formula for what you are looking for is
((y - x) / y) * 100
so for the inputs x = 1 and y = 31 you would get
((31 - 1) / 31) * 100
(30 / 31) * 100
96.77
I'm going to guess that you mean, given there are 31 things to do and I have done 1 what is the % that remain to do?
You need to subtract from 1 ( and multiply by 100 if you want percent from 0-100)
eg
function todoPercent(numTodo, numDone){
return (1-numDONE/numTodo)*100;
}

How to stop loop,when it find the correct answer?

I'm trying to make a projectile calculator, so it really need to change the way to calculate again & again until it is done.
but now i'm facing with a problem..again :(
var Height = Number(document.getElementById("Height").value);
var Velocity = Number(document.getElementById("Velocity").value);
var Range = Number(document.getElementById("Range").value);
var First = ((((Math.SQRT2 * Velocity) + (Math.sqrt(19.6) * Velocity * Height)) * Math.cos(0.785398163)) / 9.8);
document.getElementById("First").innerHTML = First;
if(First < Range)
document.getElementById("show").innerHTML = "Need more velocity to success on this range";
else
{
for(var i = -1.570796327; [>>>****HELP****<<<] ; i+0.000000001)
{
((((Velocity * Math.sin(i)) + Math.sqrt(Velocity * Math.sin(i) * Velocity * Math.sin(i) - 19.6 * Height))) / 9.8) * Velocity * Math.cos(i))
}
}
ALL of this code is make for finding a correct angle for projectile shooting, and I use "i" for angle
Please look on [**HELP**] that's the problem...I want to stop this loop after my calculation is equal to "Range" but I really have no idea to do that :(
After I got the correct "i" how can i print it to show the answer?
or anyways to make this code better or faster calculation?
Ty for every help :)
You could use break to exit the loop if you reached the expected value/range. You may also check if your result is near your range within +/- a value because you probably won't get the exact same values as you defined for Range.
for(var i = -1.570796327; i < MaxValue ; i+0.000000001)
{
result = ((((Velocity * Math.sin(i)) + Math.sqrt(Velocity * Math.sin(i) * Velocity * Math.sin(i) - 19.6 * Height))) / 9.8) * Velocity * Math.cos(i));
if(result >= Range) break;
}
Use this where you want to break
if "condition fullfilled inside for-loop"
return false;
To print it why not use:
console.log(i);
In jquery and js, if you are using loops (for, while, $.each) than return true will be equal to continue in PHP, and return false will be equal to break. Since you are using simple for loop, than there is enough to use return false to break this loop.

Categories

Resources