# 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.

### DarkBASIC Discussion / Object Screen X/Y

Message
Posted: 30th Nov 2012 14:38
I finally ran into a situation where I have no choice but to get the X/Y positions of an object on the screen. As you all well know, there is an age-old bug in DarkBASIC's OBJECT SCREEN X and OBJECT SCREEN Y commands, where an object's position will be indicated 180 degrees from where it actually is, effectively making it look like you have two of the same object. Worse yet, OBJECT IN SCREEN isn't of much use for really large objects.

The first thing that jumps to mind is using a simple algorithm to determine if the object's position falls in front of or behind the camera. This isn't hard in 2D, but in 3D, the math eludes me. I barely stumbled through high school algebra, so don't expect me to be some kind of math genius. I know someone who is a math genius (*cough* Latch *cough*). A plug-and-play BEHIND CAMERA command that returns a true or false value depending on which side of the camera's "origin plane" (the imaginary plane even closer to the camera than the near clipping plane) a 3D coordinate set is on would be awesome. Just 3D algebra, right?
Posted: 30th Nov 2012 18:07
Quote: " Just 3D algebra, right?"

Haha, I've taken coursES in 3D algebra (and it's applications). Now I'm not familiar with the bug, but it sounds like it has no depth perception (it will give x and y coordinates without checking if its in front of or behind the camera). Could you just use the in place commands and check if the object is in front of or behind the camera (still using some custom math but without having to completely reinvent the wheel)?

If yes, here is my approach:

Construct a 3D vector from the camera to 1 unit in front of it (you could position an object at the cameras position and orientation, then move it forward one to get the end point, or just move the camera, record the location, then move it back, or any of a number of solutions here). This is your forward unit vector and will be stored in 3 float type variables like so:

Once done, construct a 3D vector from the camera to the object. This is equally similar, just the object's position coordinates minus the camera's, like so:

You will then perform the dot product of the tracking vector onto the heading vector. What this will return is a non-vector (scalar) quantity that effectively is the tracking vector projected along the heading vector (so if you were to draw a line from the tracking vector to the heading vector, this would return the distance from the camera to the point where the lines intersect).

The math (where <>'s denote a vector):
<x1,y1,z1>*<x2,y2,z2>=x1x2+y1y2+z1z2

Applied to our situation:

Now, the value distance should be positive, negative, or zero. If its zero, the object is positioned right at the camera's position (not likely but it could happen). If positive, that means that the object is in front of the camera. If negative, it's behind.

Make sense? If I misunderstood the bug, a more complete solution would include this stuff.

Great Quote:
"Time...LINE??? Time isn't made out of lines...it is made out of circles. That is why clocks are round!" -Caboose
Posted: 1st Dec 2012 01:03 Edited at: 1st Dec 2012 01:31
@BN2-

That sounds very helpful. A pure math solution would be better, of course, but I'll see I can get this to work.

Actually, there might be a problem. In my 3D world, objects are so far away from the origin that small numbers don't affect anything whatsoever due to floating point imprecision. So, moving an object 1 unit from the camera probably won't work. Would it be possible to move the object some arbitrary distance from the camera? Like, say, 1000? Would the results still be valid?

EDIT: Yes they would! I put together a demo.

Posted: 1st Dec 2012 01:26
The sign convention would still be valid, but the magnitude itself would not be. One unit will allow you to create whats known as a unit vector, basically a line that is 1 unit long in any direction. I've used this type of approach in large worlds without issue.

Strictly speaking, when you are on large scales like that, the loss of decimal places becomes negligible. Note that the heading vector will still be a float with each component being less than one. When the dot product is computed, the much larger components of the tracking vector will be reduced correctly, though they might be without a large amount of decimals.

I would almost suggest always just keeping an object 1 unit in front of the camera (hidden, of course) to use for heading calculations. This is only beneficial if you are going to be checking things against the camera's heading frequently. That way your routine doesn't have that overhead and it is pure math (ultimately, it all get's called anyway, its just your tracking routine won't perform the object positioning tasks).

Great Quote:
"Time...LINE??? Time isn't made out of lines...it is made out of circles. That is why clocks are round!" -Caboose
Posted: 1st Dec 2012 10:58
Quote: "The sign convention would still be valid, but the magnitude itself would not be."

Sign convention is all I care about.

Quote: "Strictly speaking, when you are on large scales like that, the loss of decimal places becomes negligible. Note that the heading vector will still be a float with each component being less than one. When the dot product is computed, the much larger components of the tracking vector will be reduced correctly, though they might be without a large amount of decimals."

What? Math, math, math. All I know is that the camera's position is so far out that I have to build up a lot of acceleration just to move on the X axis. That's some heavy floating point imprecision right there.

Quote: "I would almost suggest always just keeping an object 1 unit in front of the camera (hidden, of course) to use for heading calculations. This is only beneficial if you are going to be checking things against the camera's heading frequently. That way your routine doesn't have that overhead"

That's a good idea. If there are a bunch of objects, it's important to optimize.
Posted: 2nd Dec 2012 01:15
Quote: "there is an age-old bug in DarkBASIC's OBJECT SCREEN X and OBJECT SCREEN Y commands, where an object's position will be indicated 180 degrees from where it actually is"

Since when? I don't recall such a bug.

Quote: "So, moving an object 1 unit from the camera probably won't work"

Yes it will, the distance is irrelevant. Whether you look at a point 1 unit in front of the camera or 1000, the resulting directional vector is the same.

Technically this should position a cube in front of the camera, but I can't figure out why it's not working properly. The Y-coordinate seems way off. If I can figure out why its not right, then you'll be able to get a point in front of the camera for the rest of your calculations.

"You're not going crazy. You're going sane in a crazy world!" ~Tick
Posted: 2nd Dec 2012 01:51

Where did these equations come from? I imagine they deal with Euler rotation, but I haven't seen them before.

Great Quote:
"Time...LINE??? Time isn't made out of lines...it is made out of circles. That is why clocks are round!" -Caboose
Posted: 2nd Dec 2012 06:30
Quote: "I don't recall such a bug."

Well, it's there in DarkBASIC Classic.

Quote: "Yes it will, the distance is irrelevant. Whether you look at a point 1 unit in front of the camera or 1000, the resulting directional vector is the same."

Yes, unless the addition of values under 500 doesn't do anything due to an extreme glitch caused by floating point imprecision.

Quote: "Where did these equations come from? I imagine they deal with Euler rotation, but I haven't seen them before."

I suspect Phaelax found them inscribed around the base of some ancient artifact from Antartica.
Posted: 2nd Dec 2012 08:48
Quote: "Yes, unless the addition of values under 500 doesn't do anything due to an extreme glitch caused by floating point imprecision."

That's interesting, I've never encountered that. Could you post some code that demonstrates it? It would be nice to know how it works so that I can anticipate and avoid it.

Great Quote:
"Time...LINE??? Time isn't made out of lines...it is made out of circles. That is why clocks are round!" -Caboose
Posted: 2nd Dec 2012 10:41
@BN2-

I wish I could, man. I wish I could! But I can't, because it's part of a space game, and I don't want to post anything from it until it's good enough that I'd want other people to see it. I might even sell it. It's a space game, and where it is right now, there are planets many units out. It is not the rendering, but the raw numbers themselves that cause the impreceision. All you need is a number. Put your action out at this number or greater on any axis, and you will see what I mean:

149597.890

Hundreds of thousands. That's where the glitches are. Apparently, DarkBASIC can't really handle numbers that big. If your scale is about 1 or 2 units and you're moving at a slow-normal speed, you will get the glitches I talked about.
Posted: 2nd Dec 2012 20:28
I didn't mean post YOUR code, just a quick demo of the glitch. As it stands, I tried to duplicate with this:

But I don't see anything unexpected happening. It does convert the position to scientific notation and rounds up a bit (it displays as 1.23457x10^6) but, as I was saying earlier, when you are that far out, the loss in precision of the 1's and 10's becomes unimportant because it's so far out. The difference in angle, screen position, etc, all become so small you don't notice them. If you are trying to track the object, then you would want a routine that continuously or periodically re-checks.

As you can see in the example, I tried anything I could to make things not work. There is multiplication capability, variable referencing (pos variable), and testing whether or not you can add small numbers and it still changes correctly.

Does this program demonstrate the conditions for the bug or did I misunderstand?

Great Quote:
"Time...LINE??? Time isn't made out of lines...it is made out of circles. That is why clocks are round!" -Caboose
Posted: 3rd Dec 2012 01:49
Quote: "Where did these equations come from?"

You could find them here:

But I gathered them from an old snippet written by Dmitry.

"You're not going crazy. You're going sane in a crazy world!" ~Tick
Posted: 3rd Dec 2012 02:36
@BN2-

The rounding is what causes the errors. Your code doesn't show any big problems because you aren't moving objects around. When using delta time and gradual acceleration, being out that far makes you not move at all on whichever axis until you've built up enough acceleration, so it's like you're sliding against a wall. When you go out to about 200000, objects actually start to jitter when you rotate the camera around. If you go out to about 1500000, a lot of objects might not even display.
Posted: 3rd Dec 2012 04:15
Interesting. I was able to get it to happen once, though since I couldn't re-do it, I can't tell if I really got it or another program was causing lag.

One thing I did notice was that if you set a variable equal to the object's position, it stores it as standard notation (1234567), instead of scientific notation(1.23457e+006). Try implementing that into your program and see if it fixes the jittery issue.

As far as the tearing goes, I seem to recall reading that that is something that comes along with large worlds (either in DBC's rendering math or in DirectX). You can try to scale everything down, so that it will still seem the same size, though you do get limited as the near clipping plane of the camera has a minimum of 1 unit. That's the method that many professional games do (or at least, the few that I've followed closely have done).

Great Quote:
"Time...LINE??? Time isn't made out of lines...it is made out of circles. That is why clocks are round!" -Caboose
Posted: 3rd Dec 2012 12:37
Quote: "One thing I did notice was that if you set a variable equal to the object's position, it stores it as standard notation (1234567), instead of scientific notation(1.23457e+006). Try implementing that into your program and see if it fixes the jittery issue."

Try implementing what into my program? Magic fairy dust? Please explain how to fix the problem. I'm afraid I don't understand.

Quote: "As far as the tearing goes, I seem to recall reading that that is something that comes along with large worlds (either in DBC's rendering math or in DirectX). You can try to scale everything down, so that it will still seem the same size, though you do get limited as the near clipping plane of the camera has a minimum of 1 unit. That's the method that many professional games do (or at least, the few that I've followed closely have done)."

That's what I was planning on doing, but would I still have to do that if I could sort out the math issue mentioned above?
Posted: 3rd Dec 2012 16:48
Quote: "That's what I was planning on doing, but would I still have to do that if I could sort out the math issue mentioned above? "

Yeah probably, since it's more of an error in rendering correctly, rather than positioning. Try fixing math stuff first (it'll be easier), but you'll probably still need to scale down.

Quote: "Try implementing what into my program? Magic fairy dust? Please explain how to fix the problem. I'm afraid I don't understand."

POSITION OBJECT Object Position()+X,...

or something similar, use

aFloat#=Object Position()
aFloat#=aFloat#+X
POSITION OBJECT aFloat#

Because the variable aFloat# won't convert it to scientific notation, it seems like this would resolve the rounding issue. I would almost suggest just writing a quick function that would effectively be a copy of the POSITION OBJECT command, but would, instead use intermediate variables to eliminate the problem.

Great Quote:
"Time...LINE??? Time isn't made out of lines...it is made out of circles. That is why clocks are round!" -Caboose
Posted: 3rd Dec 2012 19:04
@BN2-

None of that seemed to help much. I estimate I'd need to scale down the simulation to 1/10 of its current size to really solve the problem, but doing so would completely wreck the near clipping plane. Here's the thingy as it is right now. (You start off inside of a planet for debugging, so it looks a little strange at first.)

#### Attachments

Posted: 4th Dec 2012 01:44
Having seen it, I think you could pull off scaling it down with no real impact on things. You might have to get a little creative with placing your ship, but it should be doable.

Great Quote:
"Time...LINE??? Time isn't made out of lines...it is made out of circles. That is why clocks are round!" -Caboose
Posted: 4th Dec 2012 03:24 Edited at: 4th Dec 2012 03:48
@BN2-

I don't know. At 1/4 of this scale, the near clipping plane cut into planet Earth far too much. I'll try it at 1/2, but that is the absolute lowest I can go while still retaining realistic scale.

EDIT: Attached is the same thing at half scale. It is a little better, but it's pushing it when close to Earth.

#### Attachments

Posted: 4th Dec 2012 03:48
Check your clipping distance, because it should only be 1 unit. Do you plan on getting closer than 1 unit to the surface of the Earth?

Great Quote:
"Time...LINE??? Time isn't made out of lines...it is made out of circles. That is why clocks are round!" -Caboose
Posted: 4th Dec 2012 03:50 Edited at: 4th Dec 2012 03:52
@BN2-

Quote: "Check your clipping distance, because it should only be 1 unit. Do you plan on getting closer than 1 unit to the surface of the Earth?"

Nope. 1 unit is what it's set at. Planets are surprisingly small compared to their distance from one another.

EDIT: However, if I could get closer than 1 unit, that would be awesome.
Posted: 8th Dec 2012 04:44
Phaelex and Fluffy:

I did some Euler angle research and came up with a function that will determine the x,y, and z coordinates of local axis offsets from an object (so a local z axis offset of 1 would be 1 unit in front of an object).

It uses an array called newPos#(3) to return data.

Here's the function. If you want to use camera angles, just change the first line from object angle _() commands to camera angle _() commands.

Numbers are accurate to the third decimal place or so. My guess is this is because of round off errors somewhere. To observe, rotate an object to a random angle then start rolling it left and right, you will notice that the returned values change, but not that significantly.

Great Quote:
"Time...LINE??? Time isn't made out of lines...it is made out of circles. That is why clocks are round!" -Caboose
Posted: 9th Dec 2012 09:58
@BN2-

Too bad about the imprecision. For now, I'll probably just stick with the hacks I'm currently using. However, that is a useful piece of code there. Three dimensions of movement. I was able to do it along two dimensions, but your concept really takes it further. Not all languages have DarkBASIC's math commands, so this might come in handy.
Posted: 9th Dec 2012 19:38

My suspicion is that this is due to DBC's limitations, as I cannot find the error in the math. Regardless, where the test point was 10 units away or 1, it still resulted in the third decimal point being off around the third decimal place. Incidentally it oscillated around the last point, so you will still average the appropriate number.

Great Quote:
"Time...LINE??? Time isn't made out of lines...it is made out of circles. That is why clocks are round!" -Caboose
Posted: 9th Dec 2012 22:12
Quote: "My suspicion is that this is due to DBC's limitations"

Yes, somehow.

Quote: "Incidentally it oscillated around the last point, so you will still average the appropriate number."

I don't think averaging would necessarily work in this case. What kind of oscillation are we talking about here? I would think the computer would just be thinking "odd/even/odd/even", causing one of two unknown computational quirks.
Posted: 9th Dec 2012 23:07
Quote: "What kind of oscillation are we talking about here"

I didn't bother to do any kind of analysis. But it would float around the actual value +/- 0.003 ish.

Again, I didn't stop to due a full analysis, because it was close enough (the variances are pretty insignificant). Also, given the fact that it was the same range for further values (ie still only +/- 0.003ish when I was checking a point 10 times further away than the original test), it seems likely that it's a non-issue.

There are ways you could simplify things and reduce problems. Since it wouldn't even effect pixel locations (0.003 pixels gets rounded to 0 and on large distances there will probably be division included), I suspect that any 2D operations would be unchanged.

Ultimately though: as far as any application brought up in this thread goes, the math still holds and will not be affected by the variances to any degree that will impact its functionality. If your heading vector is off by 0.003, it will still be close to the general direction, the sign of the dot product will still be the same, and everything will continue to work.

Great Quote:
"Time...LINE??? Time isn't made out of lines...it is made out of circles. That is why clocks are round!" -Caboose
Posted: 9th Dec 2012 23:43
So, is it rotation or big numbers that throws this off? Because I mean, if I'm out at 99999999999999999999999999999, I wouldn't want that to affect how it's calculated.

I trust you and I think this is great math, but at the moment I prefer the sloppy hack that I originally implemented.
Posted: 9th Dec 2012 23:59
Quote: " So, is it rotation or big numbers that throws this off? Because I mean, if I'm out at 99999999999999999999999999999, I wouldn't want that to affect how it's calculated."

My suspicion is that it's due to calculations involved in sin and cos. Changing the distance of the point being tracked had no effect on the variance in the number. So if you track a point 10,000 units ahead, you should see the same variance as 1 unit ahead (all I tested was 1 and 10, but saw no noticeable effect).

Also note that I was using the free flight rotation commands because I was feeling kind of lazy and those do tend to throw curveballs. But it should work cleanly. Since its a function, I'd say implement it and see how it compares to what you currently have.

Great Quote:
"Time...LINE??? Time isn't made out of lines...it is made out of circles. That is why clocks are round!" -Caboose
Posted: 10th Dec 2012 00:12 Edited at: 10th Dec 2012 00:13
@BN2-

I am also using the free flight rotation commands because I too am lazy, and I will do my best to implement (or at least test) this once I catch up on some sleep and stop watching so many YouTube videos. It sounds like a better solution than what I have, and it applies to just about everybody's situation when using the object screen commands, but at the moment how I'm doing it sounds just fine too. At least I'm not using object in screen().