Arcanaville! I need your help, please!


Arcanaville

 

Posted

I'm working on a 3D project, and I'm stuck for a solution to a problem.

In a 3D world you draw with the following formula:
x = x - window.x; x = x * 500 / (z + 500);
y = y - window.y; y = y * 500 / (z + 500);

window.x,y being the current view point of the world (0.0, 500.0).

If you touch the window viewing the world at an touch.x, touch.y point, and a puck slides straight ahead in a z path directly under the touch.x along a plane with a y of 640.0. How do you calculate where the puck will be when it meets the point of your touch?

I figured out calculating for x and y was easily done with the following formula:
x = touch.x - window.x; x = ((x - window.x) * ((z + 500) / 500)) + window.x; //This will keep x in line no matter the distance of z.
y = 640.0; //As the puck is sliding along the ground at a plane of 640.0.

The only thing, I'm missing is the calculation for the distance the puck must travel ahead (z) before it touches the height the finger is pointing (touch.y). I just can't figure it out...ugh.

I got this far in the solution:
y = touch.y + (window.y - 500); z = ?;
x = touch.x - window.x; x = ((x - window.x) * ((z + 500) / 500)) + window.x;
y = 640.0;

Arcanaville...anyone. Please help!


 

Posted

Sorry for the constant edits. My brain has gone to mush trying to figure this out. I'm done now.


 

Posted

I don't understand what you're asking for what you intend to do...

You know where the puck stops because according to your explanation it's where the puck ends but also where it launches...


 

Posted

Basically, I want to calculate the tragectory where a puck will stop as the puck slides straight along the floor of the world behind the window. The location the puck stops being relative to where I am pointing at on the window.

I think I'm getting closer to the solution, I'm now at:
y = touch.y; y = 640.0 - y;
z = (y * ((y + 500) / 500)) * ?;
x = touch.x; x = x * ((z + 500) / 500);
y = 640.0;

I removed all the offsets for the window position I had on there to make the current formula I'm using a little more clearer. They'll be put back after I figure out the solution for ?.


 

Posted

Let's see whether I understood you:
Assuming that positive numbers move you to the right and to the bottom (the usual screen coordinates), and positive z coordinates go "into" the screen, you are "simulating" depth by scaling x and y down (in other words, in the direction of the viewpoint).

The puck doesn't start directly at the point of your touch, but at a fixed plane with y=640. It is supposed to travel forward ("into the screen"). Since your current viewpoint is (0; 500), it will be seen from above. As it moves away from "you", it will seem to "rise" on the screen because its increasing z component will cause its 2d transformation y coordinates to move closer to the viewpoint.

Now you're asking for the distance the puck needs to travel "into" the screen to reach the position indicated by touch.y? (Of course, this will only work if touch.y is still below the viewpoint, otherwise the puck will never reach your finger.)

You didn't explicitly state so in your post, but I assume that the puck is launched from a z=0 position, i. e. from your screen. So you're asking for a backwards transformation, giving you the z component of the 2d coordinates given by touch.x and touch.y, assuming you are pointing at the "floor" plane.

Since we know the y component of your puck (it is moving in the y=640 plane), this is rather easy. Start with


touch.y = 640 * 500 / (z + 500)

and you will find that

z = (640 * 500 / touch.y) - 500

Hope this helps,

10joy


 

Posted

Quote:
Originally Posted by Tenjoy View Post
Let's see whether I understood you:
Assuming that positive numbers move you to the right and to the bottom (the usual screen coordinates), and positive z coordinates go "into" the screen, you are "simulating" depth by scaling x and y down (in other words, in the direction of the viewpoint).

The puck doesn't start directly at the point of your touch, but at a fixed plane with y=640. It is supposed to travel forward ("into the screen"). Since your current viewpoint is (0; 500), it will be seen from above. As it moves away from "you", it will seem to "rise" on the screen because its increasing z component will cause its 2d transformation y coordinates to move closer to the viewpoint.

Now you're asking for the distance the puck needs to travel "into" the screen to reach the position indicated by touch.y? (Of course, this will only work if touch.y is still below the viewpoint, otherwise the puck will never reach your finger.)

You didn't explicitly state so in your post, but I assume that the puck is launched from a z=0 position, i. e. from your screen. So you're asking for a backwards transformation, giving you the z component of the 2d coordinates given by touch.x and touch.y, assuming you are pointing at the "floor" plane.

Since we know the y component of your puck (it is moving in the y=640 plane), this is rather easy. Start with


touch.y = 640 * 500 / (z + 500)

and you will find that

z = (640 * 500 / touch.y) - 500

Hope this helps,

10joy
Yes exactly what I'm asking! I'll get back to you on this after some tests. Thanks for clearing it up, as I said my brain has been through the grinder on this.


 

Posted

Quote:
Originally Posted by Tenjoy View Post
Since we know the y component of your puck (it is moving in the y=640 plane), this is rather easy. Start with [/color]

touch.y = 640 * 500 / (z + 500)

and you will find that

z = (640 * 500 / touch.y) - 500

Hope this helps,

10joy
Hmmm something is backwards here...with this the puck seems to end up higher on the screen the lower I point on the screen.
Edit: I saw where you were going with this so I did some recalculating myself, and got the same solution as you. However, when I tried the solution, the z ended up with higher numbers than expected causing the puck to appear to go higher the lower I touch. Ugg...back to the mind grinder.


 

Posted

Quote:
Originally Posted by Innovator View Post
Hmmm something is backwards here...with this the puck seems to end up higher on the screen the lower I point on the screen.
Edit: I saw where you were going with this so I did some recalculating myself, and got the same solution as you. However, when I tried the solution, the z ended up with higher numbers than expected causing the puck to appear to go higher the lower I touch. Ugg...back to the mind grinder.
Reverse the polarity!


Speeding Through New DA Repeatables || Spreadsheet o' Enhancements || Zombie Skins: better skins for these forums || Guide to Guides

 

Posted

Quote:
Originally Posted by Zombie Man View Post
Reverse the polarity!
Don't cross the streams!


Leader of The LEGION/Fallen LEGION on the Liberty server!
SSBB FC: 2062-8881-3944
MKW FC: 4167-4891-5991

 

Posted

Ok I found my mistake and reran the numbers on an Excel sheet and I'm getting a perfect result. Sweet thanks, Tenjoy! Now I just got to figure out how to work in the window offset of 500.0 into it.


 

Posted

The answer is, of course: squirrel.



 

Posted

The final solution BTW, thanks to Tenjoy was:

y = touch.y + (window.y - 500); z = ((500 * (640.0 - window.y)) / (y - window.y)) - 500;
x = touch.x - window.x; x = ((x - window.x) * ((z + 500) / 500)) + window.x;
y = 640.0;

Ugh, I hate math even though I used to teach it. Hehehehe


 

Posted

I still don't understand what you're trying to do, but I think it's cuz I'm over thinking what you're trying to do >.> largely because if it's what i think you're trying to do is look up the calculation for orbiting...

What i think you're doing is you have a window and a ground... and you want to touch the screen and have a "puck" shot out and then arc down to the ground.

in which case... shouldn't this be the answer?
http://en.wikipedia.org/wiki/Trajectory_of_a_projectile


But you apparently have your answer and i still got no clue lol ^.^


 

Posted

It was more like kicking a puck over the floor while firing a laser beam (the touchpoint) pointing at a place further away on the floor where the puck is supposed to end up.

10joy


 

Posted

Quote:
Originally Posted by Tenjoy View Post
It was more like kicking a puck over the floor while firing a laser beam (the touchpoint) pointing at a place further away on the floor where the puck is supposed to end up.

10joy
Yep, pretty much this.


 

Posted

Strangely I had to work yesterday on my supposed day off. Normally I break from the forums on days I have off and its interesting to see that God had a plan B for ensuring I was going to be doing calculations on Monday no matter what happened.


[Guide to Defense] [Scrapper Secondaries Comparison] [Archetype Popularity Analysis]

In one little corner of the universe, there's nothing more irritating than a misfile...
(Please support the best webcomic about a cosmic universal realignment by impaired angelic interference resulting in identity crisis angst. Or I release the pigmy water thieves.)

 

Posted

I belive the adage that "God is a Iron" comes to mind


Now we aren't ready quite yet to let the catgirls out of the bag.... (quote from ex libris)

 

Posted

Quote:
Originally Posted by Arcanaville View Post
Strangely I had to work yesterday on my supposed day off. Normally I break from the forums on days I have off and its interesting to see that God had a plan B for ensuring I was going to be doing calculations on Monday no matter what happened.
It's all good. Tenjoy got your back and helped me solve the issue. Thanks anyway!


 

Posted

Quote:
Originally Posted by Tenjoy View Post
It was more like kicking a puck over the floor while firing a laser beam (the touchpoint) pointing at a place further away on the floor where the puck is supposed to end up.

10joy
>.> I know he said you solved this but I'm still having trouble understanding because that is just calculating a triangle where the triangle can be at a different angle from the ground and that's pretty easy and i'm sure the math you're using is overly complex...


also just have to point this out as i just realized it

"y = touch.y + (window.y - 500); z = ((500 * (640.0 - window.y)) / (y - window.y)) - 500;
x = touch.x - window.x; x = ((x - window.x) * ((z + 500) / 500)) + window.x;
y = 640.0;"

if this is your programming it's messed up because you are a setting y to touch.y plus the math and then setting it again to 640.0 making the original statement pointless... unless you're only doing it for setting z, but then y and z would be broken so >.>


 

Posted

Quote:
Originally Posted by Durakken View Post
>.> I know he said you solved this but I'm still having trouble understanding because that is just calculating a triangle where the triangle can be at a different angle from the ground and that's pretty easy and i'm sure the math you're using is overly complex...


also just have to point this out as i just realized it

"y = touch.y + (window.y - 500); z = ((500 * (640.0 - window.y)) / (y - window.y)) - 500;
x = touch.x - window.x; x = ((x - window.x) * ((z + 500) / 500)) + window.x;
y = 640.0;"

if this is your programming it's messed up because you are a setting y to touch.y plus the math and then setting it again to 640.0 making the original statement pointless... unless you're only doing it for setting z, but then y and z would be broken so >.>
I put the touch values modified by the viewpoint of the window to get the correct x,y values at a z of 0.0 (the screen/window as understood by the renderer and which is not always the same a the mouse/touch pointer value as the viewpoint can change). I then used that value into pretty much the same formula used to render the world modified to solve for z instead of x or y (in this case using y to solve for z).

The second part after the ";" of the second line calculates for x based on the location of the touch at z of 0 (first part) and then the value derived for z, since I'm shooting at a location ahead x has to be modified by the z value to get a correct target.

After using the y touch location to solve for z, I didnt need to use the value for anything else so I put the y value back to its constant 640.0 plane (the ground where the puck slides) on the third line.

These lines are basically to set the ending location of a projectile sliding forward along the ground that's straight. The values that may change other than touch is the view point of the window/screen which can pan the world left right up an down, therefore modifies the targeting.


 

Posted

Quote:
Originally Posted by Innovator View Post
After using the y touch location to solve for z, I didnt need to use the value for anything else so I put the y value back to its constant 640.0 plane (the ground where the puck slides) on the third line.
I suppose I could change it to look like this to make my intent clearer, but it doesn't really make a difference.

z = touch.y + (window.y - 500); z = ((500 * (640.0 - window.y)) / (z - window.y)) - 500;
x = touch.x - window.x; x = ((x - window.x) * ((z + 500) / 500)) + window.x;
y = 640.0;


 

Posted

Quote:
Originally Posted by Innovator View Post
I suppose I could change it to look like this to make my intent clearer, but it doesn't really make a difference.

z = touch.y + (window.y - 500); z = ((500 * (640.0 - window.y)) / (z - window.y)) - 500;
x = touch.x - window.x; x = ((x - window.x) * ((z + 500) / 500)) + window.x;
y = 640.0;
...
... ...

You know... you might not like this but I'm going to tell you that that is atrocious.

I may be wrong... I don't like math and hardly ever work that part of my brain out any more, but I'm fairly certain that is very very over complicated... and since i have nothing to do right now since the servers for the game I was playing went down I decided to try to streamline it down...

Ok first off... Just because it is easier to work with i changed the names of your variables to single letters and made all the numbers the smallest decimal i could so 50 instead of 500 and 64 instead of 640.0... I know why they are like that in the programming but not needed for this...

Here's the translation
a = touch.y
b = window.y
c = touch.x
d = window.x

Secondly, don't break set something and then reset it unless you have to... for example...when you are going to use the number somewhere else in the program... like z is used in x... So i fixed that and with the translation above, here's the result

z = (50*(64-b)/((a+(b-50))-(a -b)) -50;
x = ((c-d) -d) * ((z+50)/50)) + d;

Now, you know math better than I do so I'm sure you can see where I simplified and all like that and why I changed what I changed in the below...

z = (64-b)/(a2-50);
x = (c-d2) * z + d;

You should come out with correct x... but I just realized not the same z...

Modifying for that... you could do it a few ways

n = (64-b)/(a2-50);
z = (n*50)-50
x = (c-d2) * n + d;

or

z = (50(64-b)/(a2-50))-50;
x = (c-d2) * (z+50)/50) + d;


I think the second choice is better. simply because you don't have another variable in memory, but n could be helpful elsewhere in the program so yeah.

I'm pretty sure the math works, but if it's not i'm sure someone will tell me... and miss the point that the math can and should be cleaned up

Also because this is all cleaned up you never touch y and it can be used in place of "(64-b)" it could "(y-b)" and that y=640 at the bottom can be removed.

edit: actually haha i messed up...a little

z = (50*(64-b)/(a +b -50-a -b) -50;

that's the number without all the apprentices which do nothing... the bold is the important part... Now if I remember my math right you always use the symbol to the left to define the number on the right so that the first number unless otherwise stated is positive so...

+a
+b
-50
-a
-b

Notice something? The a's and b's cancel so you are left with -50... so the lines after that should read

n = (64-b)/-50;

z = (50(64-b)/(-50)-50;

That second one you might end up with divide by -100... not sure. I forget the rules in programming and if that is what you end up with and want it that way you should change it to /-100 rather than how it would be.

edit 2: another side note... on that... i forgot so much but something tells me i should at least ask this...

what you end up doing is multiplying and then dividing... all you are doing is causing the number to turn negative so you could just save yourself the trouble of that by going...

and here's what those fixes would look like...

n = (64-b)/-50;
z = (n*50)-50
x = (c-d2) * n + d;


z = -(64-b)-50;
x = (c-d2) * (z+50)/50) + d;


so yeah... umm...i think i'm done >.>


 

Posted

Hmm, you might be right. The only problem I see is that the 640 is a y coordinate for the ground. And there are actually two different values that equal 500. One is the point of view rise of the window, and the other is an arbritrary value set to designate the distance between the window and the viewer. If I represented the latter with a variable of v the simplified formula would look like this:

v = 500;
z = (v(640-b)/(a+(b-500)-b))-v;
x = (c-d2)*((z+v)/v)+d;

or in c++ code:
v=500.0f;
z=(v*640.0f-b)/(a+(b-500.0f)-b))-v;
x=(c-d*2)*((z+v)/v)+d;


 

Posted

That looks better to me... though i'd remove the "*"... the code does it itself for at least 2 of the 3, but that's just me

Anything used throughout the program that could possibly change in the future should be a global variable, set at the top. For example if for an ad I were to write...

Mcdonalds is delicious

I'd want McDonalds and Delicious as global variables... that way if for some reason they change their name or want to say is awesome instead of delicious you don't have to search through possibly millions of lines of code... though there is a limit ^.^

Anything that is never going to change no matter what should be hardcoded and not variables.

Anything that is used in a particular area but not somewhere else and could change either from in the code or later on should be a variable either at the top of that section of code or set as you go... i prefer the former as it is neater.


if i understand what you are saying then i would make both 500s variables.

I don't see why making 640 be y is a problem...don't you want that coordinate to always be on the ground thus why you are making it 640 to begin with?