Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I want to learn how to use Vectors with 3D.

Here is a strange Error I have encountered today.

Instead of stopping exactly on the other Cube, I get this: enter image description here

When I change the IF to (cube.position.y < 0.1) OR change the speed to 0.01, it lands on the other cube. Seems 0.1 is the Magic Number.. But why?
Why does 0.9 and 0.8 seem fine, but then it Jumps into lengthy numbers? This looks more like ThreeJS is moving the Cube inaccurately, rather then JavaScript being unable to move an Object 0.1 sizes.

Such a beginner problem, but this is baffling to me..

Why does this happen? And how can I change it?

Is this where I "normalise" the Vector?

share|improve this question
1  
This isn't really gamedev related. Also this might be worthwhile to read: stackoverflow.com/questions/2100490/… –  bummzack Jun 8 '13 at 14:33
add comment

closed as off topic by bummzack, Byte56, Sean Middleditch, Laurent Couvidou, Josh Petrie Jun 12 '13 at 15:14

Questions on Game Development Stack Exchange are expected to relate to game development within the scope defined by the community. Consider editing the question or leaving comments for improvement if you believe the question can be reworded to fit within the scope. Read more about reopening questions here.If this question can be reworded to fit the rules in the help center, please edit the question.

2 Answers

As Ivan Kucklr says, floating point values are binary and decimal values such as 0.1 may not be represented exactly. This is true across languages, and is not Javascript specific or Three.js specific. It's fine some of the time, but often bites you worse when repeatedly adding or subtracting like your program does.

In your program, you're waiting for cube2.position.y to reach 0. When it's > 0 you subtract 0.1. But what's happening is that it's reaching some number very close to 0, but not exactly 0. Sometimes it'll overshoot a little; sometimes it'll undershoot. In this case it's undershooting slightly which means you end up running your loop one extra time.

Instead of checking whether it's reached 0, you can check whether it's reached close to 0. The easiest thing in this particular case is to test if (cube2.position.y > 0.00001). More generally, if you want to know whether a == b, you can instead use abs(a - b) < epsilon where epsilon is some small number relative to the expected size of a and b; instead of a > b you can use (a - b) > epsilon.

Read more on this page, which goes through an example of 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 != 0.1 * 10, just like your program, but then shows some more advanced ways to compare.

share|improve this answer
add comment

You can not "trust" floating point values. First, 0.1 can not be represented in binary system. It is periodical and it should be approximated by finite mantissa.

So, imagine this program on decimal computer:

var i = 1;
while( i>0 ) i -= 1/3;
console.log(i);           // prints -0.3333333332

1/3 will be approximated as 0.33333333, so values of "i" will be

 1.0000000000
 0.6666666667
 0.3333333334
 0.0000000001
-0.3333333332
share|improve this answer
add comment

Not the answer you're looking for? Browse other questions tagged or ask your own question.