This was driving me mad for some time, today I manged to reproduce this problem, so one of the causes is division by 0.
e.g.
var end:Number = 1024/0,
size:Number = 1000,
a:Array = [];
for (var i:int=0;i<end;i++){
a.push(size);
}
After dividing by 0 (I don't know how its possible, but anyway) value end becomes Infinity and sneaks into the loop, so flash player stops execution of the script with exclamation mark.
I discovered that when one of the components in flex, after state changes in layout, passed on its width of 0 as one of the parameters to construct the loop. How to avoid this behavior of flex component?
This is expected behavior in most, if not all, languages. I just tested AS3, Javascript, and PHP. AS3 and JS give you Infinity and PHP gives you false (PHP's go-to handler for if there is a low-level error). You should avoid dividing by 0 at all costs because it simply is not possible. Most languages do not want to prevent a user from dividing by 0, since Infinity is an actual value and the correct value of dividing by 0, which is why they allow it.
Your error is because you are using Infinity as your loop check, which will never be reached in your loop.
Instead, use a conditional to handle the possibility of the value being 0. So something like:
function calculateRatio(x:Number, y:Number):Number {
if (y == 0) {
return 1; // or whatever to indicate an error
}
return x / y;
}
or
function calculateRatio(x:Number, y:Number):Number {
return x / (y == 0 ? 1 : y); // the value is still calculated, just makes sure y is not 0 at all times
}
Just make sure any time you perform division, you never divide by 0. In your case, your loop is running an infinite number of times. Flash is single-threaded and will actually freeze completely while any script execution is happening. Generally, this happens so quickly that the end-user doesn't notice it but in your case, it will freeze until the end of time. Fortunately, Flash will end script execution at 15s or 30s, depending on runtime version so it should error out at some point.
Division by 0 is not a problem as such here, 0 is passed as a parameter, as a result of other operations at run-time, and I can not be sure, that 0 will not be passed as parameter.
What's boggling my mind is that division by 0 should be flagged in the first place, but it isn't. Then gets result of infinity, ok from mathematical point of view, but then I get infinite loop. I would normally expect that executing the script longer than e.g. 15 sec. throw an error and the script stops, but instead what I have is exclamation sign without any information for the developer, and that sucks..
Related
I am writing a formula which to use as a decay multiplier on a given value.
The problem is the following : I have a window of processing - days lets say 10, this window is computed every day anew. I need to decay a certain parameter with a factor reflecting the days that an id is present. Currently what I do is (previousWinSize-(start of the current window-start of the previous window))/previousWinSize
In this case if my previous window size is 10 and the difference in the days of processing is two (10-2)/10 which gives me 0.8 to multiply my variable by and respectively decay .2 of it.
However if I have a 3 day window and again 2 days of difference (3-2)/3 I get value close to 0 which cuts more than I would like to.
I am looking for a formula that would scale better when the numbers are small and would not produce a huge decay factor.
Thank you in advance.
I recommend making use of a sigmoid function e.g.
You can take the output of your function i.e. returns a number between 0 and 1 based on the difference of days of processing and feed it into the sigmoid. If you set up the a (slope) and b (inflection point) parameters properly you can for example, ensure that the lowest decay multiplier you get is ~0.5 when your original equation returns a number close to 0.
I've graphed the example I stated above here:
https://www.desmos.com/calculator/nqemuexjhg
(This is based on: https://www.desmos.com/calculator/rna4aqta0c)
I think you do have two edge cases with this method though. When your equation returns 0 the sigmoid isn't exactly going to give you 0.5 (which you may not even want to begin with), you'll end up getting something that's close to 0.5. In this scenario what you may start to see is your values drifting if you keep applying the sigmoid. The same is true for when your equation returns 1. After putting it through the sigmoid you won't get 1, you'll get something close to 1.
What I think I'd do in such a scenario is have some sort of check before the sigmoid gets applied
e.g.
if(x == 0)
y = 0;
else if(x == 1)
y = 1;
else
y = sigmoid(x);
Sources / Possible further reading:
https://en.wikipedia.org/wiki/Sigmoid_function
I can't seem to find an answer for this anywhere online, but this for loop, although seemingly valid, creates an infinite loop because actionscript does not seem to recognize 0.1, 0.2, 0.3, and so on. This for loop will just trace 0, 0, 0, and so on infinitely.
Can anyone tell me why actionscript does this, and is there a way to get to precise decimal number increments in actionscript?
for(var i:int = 0; i<1; i = i + 0.1)
{
trace(i);
}
The initial problem, as reported in Hobo Sapiens's comment, is that you have declared i as int, but want it to store fractions. However, even after you have fixed that, you are likely to encounter rounding error issues. Adding up a floating point approximation to 0.1 is not a good way of getting the closest possible approximation to 0.9, or the exact value of 1.0.
There are generally two solutions:
Use a decimal data type. I have not been able to find a decimal arithmetic package for Actionscript, but that does not mean there isn't one.
Use an integer that represents a scaled version of the value you want. In the case of your loop, you would increment i by one on each iteration, and limit it to less than ten. You would then use a Number conversion of i, divided by ten, inside the loop. That results in using the closest floating point number to 0, 0.1, 0.2 etc. inside the loop.
Can't comment yet, so I'll post it as an answer:
There are definitely cases where increments by a float value are useful. And if it was absolutely wrong, why would it then be possible at all?
What akmozo suggested is a good way to do it, instead of doing the increment i = i + 0.1 you can do i = Number((i+0.1).toFixed(decimalSpacesYouWant)). This will return a number without the usual rounding problems. It gets especially useful with very small values (converging towards zero) which tend to flip into Infinity or NaN at some point.
I want to rapidly fade out an oscillator in order to remove the pop/hiss I get from simply stoping it. Chris Wilson proposed the technique to set setTargetAtTime on the gain.
Now I don't quite grasp its last parameter 'timeConstant':
What's its unit? Seconds?
What do I have to put in there to get to the target-value in 1ms?
That Chris Wilson guy, such a trouble. :)
setTargetAtTime is an exponential falloff. The parameter is a time constant:
"timeConstant is the time it takes a first-order linear continuous time-invariant system to reach the value 1 - 1/e (around 63.2%) given a step input response (transition from 0 to 1 value)."
So, for every "timeconstant" length of time, the level will drop by a bit over 2/3rds (presuming the gain was 1, and you're setting a target of 0. At some point, the falloff becomes so close to zero, it's below the noise threshold, and you don't need to worry about this. It won't ever "get to the target value" - it successively approximates it, although of course at some point the difference falls below the precision you can represent in a float.
I'd suggest experimenting a bit, but here's a quick guess to get you started:
// only setting this up as a var to multiply it later - you can hardcode.
// initial value is 1 millisecond - experiment with this value if it's not fading
// quickly enough.
var timeConstant = 0.001;
gain = ctx.createGain();
// connect up the node in place here
gain.gain.setTargetAtTime(0, ctx.currentTime, timeConstant);
// by my quick math, 8x TC should take you to around 2.5% of the original level
// - more than enough to smooth the envelope off.
myBufferSourceNode.stop( ctx.currentTime + (8 * timeConstant) );
though I realize this might not be technically correct ( given the exponential nature of the time constant ) but i've been using this formula to "convert" from seconds to "time constant"
function secondsToTimeConstant( sec ){
return ( sec * 2 ) / 10;
}
...this was just via trial and error, but it more or less has been working out for me
I'm having a bit of trouble making sense of some of the tutorials for this online, thus why I'm asking here. (Using ActionScript 3, Adobe AIR, and Flash Professional CS5.5)
I have a very heavy function in my AS3 document class that I need to run asynchronously, so it doesn't stop the code on the MovieClip itself (don't ask me why, it just needs to be that way.)
So, simply put, how do I run this document class function (StartNow) asynchronously? The code can be placed in the document class or on the movieclip, I don't care where. It seems to be a relatively simple and common practice, but all my research is digging up nothing.
Thanks!
If your target is Flash player 11.4, there are Worker objects which can be assigned such a heavy function. I had no FP11, and eventually made a procedural generator that lasted more than 300 seconds per iteration in total. I had to use a state-based approach, paired with an enter frame listener. In my c ase, the entire complex generation process was split into logical chunks that were small enough to be completed within a reasonable timespan, and had a variable tracking the current generation phase. So, when another frame called the generation function, it read last completed step from that variable, performed one extra step with its set of data, stored the new value and exited for the frame. This, as is, is not a pure asynchronous process, but a pseudo-multitasking approach, this can suit you if your function that makes your SWF lag is splittable.
In Flash there is no such thing as run a function asynchronously, you have to do it yourself, unless you want to use Workers (like Vesper said). Workers gives you a separate process. Otherwise, you have to break your calculation into parts. This is how you do it:
Imaging 'trace' is a very heavy operation. It's not, but just to illustrate. This simple for-loop is runned on a frame, and causes a lower framerate, since it's all calculated before the frame actually renders.
for(var i:int = 0; i < 1000; i ++)
{
trace(i); // heavy calculation here
}
So you have to break the calculation into parts, and break it to be able to run the calculation over time.
To do that, you have to create a function which just takes a part of the loop every time:
calculatePart(0, 1000, 20);
function calculatePart(startIndex:int, endIndex:int, amountPerRun:int)
{
for(var i:int = startIndex; (i < startIndex + amountPerRun) || (i < endIndex); i ++)
{
trace(i); // heavy calculation here
}
if (i < endIndex)
{
calculatePart(i, endIndex, amountPerRun);
}
}
This is actually the same function as the simple for-loop in the first code, it also outputs 1000 traces. It is prepared to run in parts, but this isn't async yet. We can now change the function easily, so the function operates over time.
I use the setTimeout for this. You can also use a ENTER_FRAME event-listener or the Timer class for this, but for the sake of this example I try to keep it clear.
calculatePart(0, 1000, 20, 100);
function calculatePart(startIndex:int, endIndex:int, amountPerRun:int, timeBeforeNextRun:Number)
{
for(var i:int = startIndex; (i < startIndex + amountPerRun) && (i < endIndex); i ++)
{
trace(i); // heavy calculation here
}
if (i < endIndex)
{
setTimeout(calculatePart, timeBeforeNextRun, i, endIndex, amountPerRun, timeBeforeNextRun);
}
}
As you can see, I've added a timeBeforeNextRun parameter. If you run the example, you can see it takes 100 milliseconds before 20 traces are outputted.
If you set it very low, the calculation will be tried to be done very fast, however you cannot gain extra speed just by trying to do more in less time of course. You have to play with the time and amount variables, you can test which one actually gives better performance (or less lag).
// more time between a run, less calculations per run
calculatePart(0, 1000, 30, 10);
// more calculations per run, more time between a run
calculatePart(0, 1000, 100, 30);
Hope this helps.
If you want to use a smarter calculation of the time, I found this utility class very helpful, which measures how much time the calculation actually took, and alter the time itself.
What does the term "STEP" means in bullet physics?
What does the function stepSimulation() and its parameters mean?
I have read the documentation but i could not get hold of anything.
Any valid explanation would be of great help.
I know I'm late, but I thought the accepted answer was only marginally better than the documentation's description.
timeStep: The amount of seconds, not milliseconds, passed since the last call to stepSimulation.
maxSubSteps: Should generally stay at one so Bullet interpolates current values on its own. A value of zero implies a variable tick rate, meaning Bullet advances the simulation exactly timeStep seconds instead of interpolating. This feature is buggy and not recommended. A value greater than one must always satisfy the equation timeStep < maxSubSteps * fixedTimeStep or you're losing time in the simulation.
fixedTimeStep: Inversely proportional to the simulation's resolution. Resolution increases as this value decreases. Keep in mind that a higher resolution means it takes more CPU.
btDynamicsWorld::stepSimulation(
btScalar timeStep,
int maxSubSteps=1,
btScalar fixedTimeStep=btScalar(1.)/btScalar(60.));
timeStep - time passed after last simulation.
Internally simulation is done for some internal constant steps. fixedTimeStep
fixedTimeStep ~~~ 0.01666666 = 1/60
if timeStep is 0.1 then it will include 6 (timeStep / fixedTimeStep) internal simulations.
To make glider movements BulletPhysics interpolate final step results according reminder after division (timeStep / fixedTimeStep)
timeStep - the amount of time in seconds to step the simulation by. Typically you're going to be passing it the time since you last called it.
maxSubSteps - the maximum number of steps that Bullet is allowed to take each time you call it.
fixedTimeStep - regulates resolution of the simulation. If your balls penetrates your walls instead of colliding with them try to decrease it.
Here i would like to address the issue in Proxy's answer about special meaning of value 1 for maxSubSteps. There is only one special value, that is 0 and you most likely don't want to use it because then simulation will go with non-constant time step. All other values are the same. Let's have a look at the actual code:
if (maxSubSteps)
{
m_localTime += timeStep;
...
if (m_localTime >= fixedTimeStep)
{
numSimulationSubSteps = int(m_localTime / fixedTimeStep);
m_localTime -= numSimulationSubSteps * fixedTimeStep;
}
}
...
if (numSimulationSubSteps)
{
//clamp the number of substeps, to prevent simulation grinding spiralling down to a halt
int clampedSimulationSteps = (numSimulationSubSteps > maxSubSteps) ? maxSubSteps : numSimulationSubSteps;
...
for (int i = 0; i < clampedSimulationSteps; i++)
{
internalSingleStepSimulation(fixedTimeStep);
synchronizeMotionStates();
}
}
So, there is nothing special about maxSubSteps equal to 1. You should really abide this formula timeStep < maxSubSteps * fixedTimeStep if you don't want to lose time.