Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Dark GDK / Positioning Problem

Author
Message
Michael P
18
Years of Service
User Offline
Joined: 6th Mar 2006
Location: London (UK)
Posted: 18th Feb 2008 18:50 Edited at: 18th Feb 2008 18:53
In some code I was writing, I noticed that object/camera positions seemed to end up a little off where they should be. To work out why, I wrote the following code:



The code above is supposed to:
-Work out the distance between the cube and the camera.
-When the up key is pressed, move the camera towards the cube.
-The distance to move is defined by: 'the distance between the cube and the camera' divided by 'fPresses'. So, if fPresses is 2 then it should take 2 presses of the up key for the camera to reach the cube.

When dealing with floats with lots of decimal places, the position that is moved to seems to be slightly wrong. Taking into account truncation (that occurs when using dbPrint), after 2 presses the new position should be:
-X = 150.142
-Y = 150.123
-Z = 150.123

However, according to what is printed; the new positions are actually:
-X = 150.142
-Y = 150.124
-Z = 150.123

So, the Y is 0.001 out. Why is this?
- Note: I've probably made a very stupid mistake...

Side question: Is dbPrint supposed to truncate floats down to 7 characters?
Michael P
18
Years of Service
User Offline
Joined: 6th Mar 2006
Location: London (UK)
Posted: 18th Feb 2008 21:21 Edited at: 18th Feb 2008 23:47
[EDIT 3] Results in DBP are the same.

I have discovered that when running in both DGDK and DBP with the starting position of the camera set to 0,0,0 the results are correct. Note that auto cam is set to off, so actual starting position is not 0,0,0:

(DBP code)
Michael P
18
Years of Service
User Offline
Joined: 6th Mar 2006
Location: London (UK)
Posted: 19th Feb 2008 17:34 Edited at: 19th Feb 2008 17:44
I have spent a bit of time looking into this and working out exactly what the problem is. The new code looks like this:


After 1 up key press, the camera should move into the same position as the cube. Printed on the screen after 1 press is as follows:
Current object positions: 0,0,5 (XYZ)
Current camera positions: 0,0,4.99999952316 (XYZ)
Original distance between camera and object: 5
Original camera position: 0,0,0 (XYZ)

Clearly, the object is not in exactly the right place (it is about 0.0000005 out of place).

We can see that the value used with dbMoveCamera is 5 because this is the original distance between the camera and object. This means that there is no problem in calculating the distance between the camera and object (the distance calculated is correct).

Therefore, it appears that there is a bug with dbMoveCamera which is causing it to move the camera slightly too short.

Any second opinions?
Benjamin
21
Years of Service
User Offline
Joined: 24th Nov 2002
Location: France
Posted: 19th Feb 2008 18:04
Quote: "Clearly, the object is not in exactly the right place (it is about 0.0000005 out of place)."

Single-precision floating point numbers just aren't this accurate.

Michael P
18
Years of Service
User Offline
Joined: 6th Mar 2006
Location: London (UK)
Posted: 19th Feb 2008 18:19
Ah . Well in that case, I have a few noob questions for you:

1. If I tell it to move 5.0, shouldn't it move 5.0; not 4.99999952316?
2. Is there a way I can get it to move exactly to the right place?
3. How accurate are single/double floats?
kBessa
17
Years of Service
User Offline
Joined: 8th Nov 2006
Location: Manaus, Amazonas, Brazil
Posted: 19th Feb 2008 18:52
Quick search on msdn:

float
3.4E +/- 38 (7 digits)

double
1.7E +/- 308 (15 digits)
Michael P
18
Years of Service
User Offline
Joined: 6th Mar 2006
Location: London (UK)
Posted: 19th Feb 2008 19:41 Edited at: 19th Feb 2008 19:48
Does that mean that the only difference between a single float and a double float is that a single float can have a maximum of approximately 7 digits whilst a double float has 15?

If what I'm saying is right, then my question 'If I tell it to move 5.0, shouldn't it move 5.0; not 4.99999952316?' remains unanswered. Surely, it doesn't really matter about the accuracy in my 2nd scenario since it is supposed to move exactly 5.0, which is only 2 digits.

[EDIT] Another point: the new position after movement is 4.99999952316. In theory, shouldn't this be 4.99999900000 since it's a single float we're telling it to move with, so it doesn't have any values past 7 digits. Where does the 52316 come from?
kBessa
17
Years of Service
User Offline
Joined: 8th Nov 2006
Location: Manaus, Amazonas, Brazil
Posted: 19th Feb 2008 19:59
It probably is something with MoveCamera.

I tested it with dbPositionCamera and it works just fine, so it's nothing to do with float precision.
Michael P
18
Years of Service
User Offline
Joined: 6th Mar 2006
Location: London (UK)
Posted: 19th Feb 2008 20:32
In that case, I'll post in the bug reporting section later.

For now, how can I replicate the effect of dbMoveCamera, taking into account angles of the camera?
kBessa
17
Years of Service
User Offline
Joined: 8th Nov 2006
Location: Manaus, Amazonas, Brazil
Posted: 20th Feb 2008 02:28
Er... A lot of sines and cosines. It's been a looooooong time since I had algebra classes, I can't remember now!
jason p sage
17
Years of Service
User Offline
Joined: 10th Jun 2007
Location: Ellington, CT USA
Posted: 20th Feb 2008 06:16 Edited at: 20th Feb 2008 06:21
Here we are again Micheal - You're asking something - I don't have any idea what you're trying to do - so I don't know how to answer. Your idea for the dbMouseMove to be treated like 2d vector sorta - you know - to get distance etc... could POSSIBLY be fixed with something as simple as swapping the X and Y to their opposite 0-dbMouseMoveX() but I don't know.

I guess one would need to know what you need the mouse values to be at the end of your snippet to try an arrive at a good way to get it - perhaps a description of what you;re trying to accomplish if you can do so without giving away the bank as it were.

[edit]
Also - Benjamin and Zotoaster would know better than me more likely - but I've thought about it a little - and I was thinkning that EULAR math - like how Camera Move works regardless of orientation - could be done with pthygorian theorum - One AXIS at a time... Except - a twist where the Hypotenuese is not the number you're seeking but the distance you want to move... then the Bottom of the triangle, length would be the amount to add to that axis. Naturally the angle of the "cam" would come into play for the angle at the tip of the triangle... (Hypotenuese and bottm on triangle meet... not the Right angle side)

That's how I think it would work but I'm no math guru.
[/edit]

Michael P
18
Years of Service
User Offline
Joined: 6th Mar 2006
Location: London (UK)
Posted: 20th Feb 2008 08:44
Since there is this limitation of the dbMoveCamera command, I want to find a way of fixing the problem so that I can move the camera any distance, and it will arrive in exactly the right place. One way is to 'write your own command' that is accurate.

The point about angles is that, lets say the cube isn't directly in front of the camera; In this case, the camera would be at an angle and so simply doing 'dbPositionCamera(dbCameraPositionX(0),dbCameraPositionY(0),dbCameraPositionZ(0)+fDistance' wouldn't work.
jason p sage
17
Years of Service
User Offline
Joined: 10th Jun 2007
Location: Ellington, CT USA
Posted: 20th Feb 2008 14:27 Edited at: 20th Feb 2008 14:33
Quote: "The point about angles is that, lets say the cube isn't directly in front of the camera; In this case, the camera would be at an angle and so simply doing 'dbPositionCamera(dbCameraPositionX(0),dbCameraPositionY(0),dbCameraPositionZ(0)+fDistance' wouldn't
work. "
Yes - this is where the pythagoriam theory comes in.

Theory (normally) kinda works like:
If you know the bottom of the triangle length and the right side of the triangle length - you can calc the hypotenuese. I'm sure angles can be derived from this.

In your case - you have the angle (camera tilt) and the distance you want to travel (this case along the hypotenuse) and I thinking math wise there is a way to do a twist on the pythagoriam theory to calc the bottom of the triangle (How much you move camera on one axis). This basic psuedo formula would take your cam angle into account - and the hypotenuese (How much cam moves) is not the same as the distance you tell DB (The bottom of the triangle. I think if you do this on all three axis - you'd have your move command.


[edit]
also I struggled with "accuracy" in DBPro before - and I actually changed the scale of my entire game to make the numbers more closely jive with the stuff I wanted to do - meaning I made stuff bigger to get into the whole number "ranges" kinda - I still had issues like your 4.999999 thing but it was close enouogh to me. You see - floating point is RARELY digit accurate - and thats because how the numbers are actually stored. Sounds silly - but if you look how a float is stored low level - it becomes a little easier to understand why they...um... float like that! lol... I think Integers are more accurate do to this - in their own right.

I've worked on some business systems that preferred to use integers with implied decimal places just to get 100% nailed accuracy - fixed precision if you will.

Also - have you considered perhaps using doubles to store your "Desired location" - and then feed that to the engine.. but when your code wants to read the value back - get it from your extra "doubles" set aside for this - instead of trying to get back positions verbatum from DB?

Michael P
18
Years of Service
User Offline
Joined: 6th Mar 2006
Location: London (UK)
Posted: 20th Feb 2008 16:30
I've decided that simply rounding positions to 3 decimal places (more if necessary) is a good enough fix. This is not a bug, in fact (quoting bug report forums):

Quote: "This is not a bug, this is simply the result of carrying out many trig floating point calculations on a number as dark coder has described. Each calculation carried out increases the potential inaccuracy of the intermediate results."
Morcilla
21
Years of Service
User Offline
Joined: 1st Dec 2002
Location: Spain
Posted: 20th Feb 2008 18:02 Edited at: 20th Feb 2008 18:04
Quite true, just welcome to Intel CPU's family.

I really do not recommend you to round the floats. You are getting less precision than before by doing this, and I thought this was your initial trouble.

[Edit: Ah and I won't bother about those 0.0000005 either, that doesn't really affect the camera, that should be already -clipped- at greater values. A coding must be very extreme to face this as a real problem.]
Michael P
18
Years of Service
User Offline
Joined: 6th Mar 2006
Location: London (UK)
Posted: 20th Feb 2008 18:49
The real problem was comparing two positions (they ended up different, even though they were almost the same). Rounding should fix this, realistically there isn't any need for all those decimal places anyways.
jason p sage
17
Years of Service
User Offline
Joined: 10th Jun 2007
Location: Ellington, CT USA
Posted: 20th Feb 2008 18:53 Edited at: 20th Feb 2008 18:54
For comparing - rounding or some sort of range checking - versus EXACT Value checking seems worthwhile for you. Yup Yup Yup

(though use a homemade efficient abs function - not native one - its slow)

if abs(MyFloat1 - MyFloat2) < 1.5 then Print "We close Enough"

[edit]ugh - had greater than sign originally ...oops[/edit]

Morcilla
21
Years of Service
User Offline
Joined: 1st Dec 2002
Location: Spain
Posted: 20th Feb 2008 20:52
Yep, that's the right way to compare floats.
Never use something like 'if (MyFloat1 == 0.15f)' because it is likely to hit the condition only sometimes, as MyFloat1 could be 0.150001 or 0.149999

Login to post a reply

Server time is: 2024-10-08 11:34:52
Your offset time is: 2024-10-08 11:34:52