Math Question!

Started by Ryan Timothy B, Sat 08/08/2009 18:22:23

Previous topic - Next topic

Ryan Timothy B

I could have placed this in technical, but it's more or less simply JUST math.  So here it is! :P

Alright.  I know 'how' I could do this, but I am not a CPU friendly kind of guy sometimes when it comes to math.  So this is why I'm asking YOU!  ;D

I want to know how to calculate the rooftop placement for my next Road Racer game.  I know the base of the buildings vertices and the center of perspective point (obviously).  I just need to know how to find where the roof should go depending on the size of the rooftop.

Here's the image first before I get into the technical part of it:



The dark areas are the base of the building.  The colored parts are obviously the rooftops. :P  And the Red dot as the center of perspective.

What I'm going to tell you next won't be exact yet, I'll have to play with it, but I need the formula first.  If the building is 1 story the rooftop will be resized to 110% of the base.  If the building is 2 stories, the rooftop will be resized to 120% of the base, etc.

The only way I can think of doing this would be using y=mx+b and then check between the two lines of perspective if the distance is now 110% of the base, for example.  But if I decide to have rotated buildings down the road, I wouldn't know how to go about doing this anymore.

So if anyone knows the math how to make a rectangle and a larger rectangle line up with a perspective point, that would be excellent!  Thanks!

Evil

There's probably an easy way to do it based on the coordinates of the edges of the roofs and the perspective point, which is the middle of the screen. Like if the building is so far X,Y direction from the perspective point, then the X,Y,B of the base, where B is the scaling of the base, is where ever you want the base. Right? I don't know shit about math, I just had to post because I thought this idea was cool. ^_^

Jim Reed

I know the answer, but I'm at work now, and typing this from a mobile phone, so give me a few hours to get home, and I'll gladly help.

Khris

It's relatively simple: calculate the vector from the perspective point to the top left vertice, then multiply it by a certain factor.
To get to 110%, simply multiply x and y with 1.1.
As long as the buildings aren't rotated, draw the rectangle beginning at the top left corner with original_dimensions*1.1.

Note that if you're using 110% to get the roof of a one story building, a two story roof will be at 121%.
F(n) = F(n-1) * F(n-1) / F(n-2).
Three stories: 133,1% (1.1^3)
Four stories: 146,41% (1.1^4)
Five stories: 1,61051% (1.1^5)

Ryan Timothy B

Is it seriously that easy? Wow.  I'll take a look at it in a moment when I get the script going.  I'll let you know.

Jim Reed

Solved allready?
Well, never mind then, but you can PM anyway.

Ryan Timothy B

Thanks Khris!  After some tinkering around, I finally got it working this morning.  It works smoother than a babies ass!  Yeehaw!

Now it's time for the solid colored 'raycasting' (if I can call it that) for the walls.  Good thing AGS has filled triangles; CJ is a golden god.  Something I noticed was quite funny, he made a comment in the manual/index-thing for the filled triangle saying: "Well, don't look at me, you might find it useful for something :-)" 
Well.. I'm going to find it useful! :P lol

Oh and Khris.  I know you said that each floor is an exponent, like 1.1^2   or   1.1^4   etc.   But once I made a building over 2 floors it was HUGE and swaying all over the place.  It had looked like a gigantic 6 floor building when it was only 3 or something.  So I decided to just stick with  1.1 for 1 floor.  1.4 for 4 floors, etc.  I don't care if it's not accurate, it looks good enough.

Thanks again!

Ryan Timothy B

Hmm.
I appear to have run into a snag on the placement of the building 'walls'.  I always thought that the closest building should have it's walls drawn last, but have realized this isn't always the case.

Going to have to put the thinking cap on for a while.... OR perhaps take a look at some type of tutorial, which I haven't been able to find yet.  :P

Khris

I've had this problem in the past.
The problem is that to calculate the distance from the camera, one usually uses a single 3D point, the center of the wall. But if one of the walls is long enough, it's possible that the center of wall A is closer than the center of wall B although B is in front of A.

There are two solutions:
1) split the walls into smaller pieces. This makes it less likely that the distance sort creates a wrong drawing order.
2) (what pros do) during the sort, check if the two walls are close and might obscure each other. If they are, create a virtual plane in between the two (hard part) and see which side the camera is on (easy part). Draw the wall on the same side as the camera last.

The second method is used by AGS3D. The source code is available so you could check it for some pointers.

Wonkyth

Hmm, this is good stuff!

I've been working on creating a first-person driving minigame, and this has helped with allot of problems I'd been trying to work my head around.
Quote from: Ryan Timothy on Mon 10/08/2009 03:07:37
I appear to have run into a snag on the placement of the building 'walls'.  I always thought that the closest building should have it's walls drawn last, but have realized this isn't always the case.
Especially this one!
"But with a ninja on your face, you live longer!"

Ryan Timothy B

It's a shame.. my computer just died yesterday (again).  A few weeks ago the power supply blew up (nasty burning smell, loud spark... all that fun stuff. yay!) This time the hard drive finally won't run long enough to make it through the windows startup and just dies out, crashing the computer.  For the past half a year the hard drive has been humming like crazy as though it has a bad bearing, motor or whatever and I kept using it anyway.  I have all my stuff backed up, obviously.  But for the moment will have to put this on hold.

QuoteHmm, this is good stuff!

I've been working on creating a first-person driving minigame, and this has helped with allot of problems I'd been trying to work my head around.
It's a good thing this thread has been useful for someone else too! :P


Anyway Khris, I'll look into your 'how the pros' do it method whenever I get my computer back up and running.  But first I'll just get it working without proper wall placement where they overlap IF they are too close.  Then I'll see if my building locations are in an obvious need of this method of drawing placement.

Thanks for your help so far, it's been very handy.

Ryan Timothy B

I figured I'd revive this old thread with yet ANOTHER Math Question!

I imagine this is quite simple to solve, I'm just having mental issues at the moment (starting to wish I took more math classes when I was in high school). :P

Situation:
Imagine something moving along the X axis.  It has a speed which let's say is 3.0 at the moment.  Each game loop this speed is decreased by a constant speed, let's say 0.1.  So the first loop the object moves 3.0 pixels from where it was, the next loop it moves an extra 2.9 pixels, the next loop it moves 2.8, so on and so on until it reaches zero.

My question is:
How do I know the total distance it will travel on the X axis until the speed reaches zero, at any point from where it is to where it'll be?
Obviously I could use a while loop which simply does this:  distance=3.0+2.9+2.8+2.7+2.6+etc+etc..
But I like math too much to cheat my way out of a seemingly easy math problem.

Thanks for your time!

Quintaros

distance

x=1/2a*t^2+v0*t+ x0

where a=acceleration, -0.1 pixel/cycle^2 in your example
v0=initial velocity, 3 pixel/cycle in your example
x0= initial position
t=number of cycles

velocity is derivative of distance with respect to time,

v=dx/dt= a*t+ v0

solve for v=0

t= -v0/a


Khris

For a graphical interpretation, imagine a graph with t increasing to the right and v to the top.
The distance is the area under the curve (distance = velocity * time).

In the case of your example with the graph going straight from (0;3) to (30;0) it's a right triangle, thus x = (3*30)/2 = 45.

Ryan Timothy B

Thanks for the quick responses guys.

Quintaros, I seem to be having issues understanding your solution.  Is there anyway it could be dumbed down a little--perhaps with basic pseudo-code?
I tried it with a speed of 1.0 and it came out around 140-something.  Without a doubt, I did something wrong.

Bulbapuck

#15
This is basically what Quintaros wrote:

In the case of constant acceleration a we have the following formulas:

Position:
x=(1/2)*a*(t^2)+v0*t+ x0

Where we have a, v0 and x0. But to determine x we also need t. And t is the amount of game cycles until the thing stops, hence the value of t when the speed (v) is 0.

Velocity:
v=a*t+ v0
0=a*t+ v0
a*t=-v0
t=-v0/a

In your case: t = -3.0/(-0.1) = 30.

Now you put all your values in the formula for position (x=1/2a*t^2+v0*t+ x0) and you've got your answer!

Ryan Timothy B

#16
Hmm, I didn't know it was: (1/2)*a    (although I'm using 0.5 instead of calculating it for no reason every time I need it)
I was doing: 1/(2*a)

It's still not accurate though.

With this script right here:
float t=-1.0 / (-0.1);
x=0.5 * (-0.1) * (t*t) + 1.0 * t + 0.0;

Starting speed is: 1.0
Acceleration is: -0.1

I'm getting 5 when it's supposed to be 5.5.  I've actually noticed that with every 1 increment of the initial speed it subtracts 0.5 from what it's supposed to be.  What am I doing wrong?

Gilbert

#17
In fact, since you're deducting a constant in each game loop, you could also consider it discrete and use just the sum of an arithmetic series to solve it.

Say:
Initial distance moved = x0
Distance moved in loop i = xi = xi-1 - 0.1

To move until the object comes to a stop, the final loop number is x0/0.1.

The sum of an arithmetic series can be easily memorised as follows:
(1st term + last term)*(number of terms)/2

So, in your case, it is:
(x0+xn)*(n+1)/2
where n= x0/0.1 is the loop number when this stops, and the total number of terms is n+1 as the index starts from 0.
As xn=0, so it can be further simplified to:
(x0+xn)*(n+1)/2=(x0)*(n+1)/2

If x0=3, then the total distance moved is just 3(3/0.1 + 1)/2=3*31/2 = 46.5.

If x0=1, then the total distance moved is 1(1/0.1 + 1)/2=1*11/2 = 5.5, note that as your implementation is discrete, using general continuous physics formulae may yield a bit different result (such as you getting 5 instead of 5.5).





Ryan Timothy B

Right on, thanks Gilbet.  Works like a charm.

Bulbapuck

#19
Ah, I misunderstood your question :P

Here's why you would get an error of 0.5 times the initial speed.

The left table is the speed I was calculating with, and the right one is the one you were calculating:


The difference of our solutions are the areas of the green triangles- which are:
(v0/0.1)*((1/2)*1*0.1) = (1/2)*v0

In this case: Gilbet's solution is the best one :)

SMF spam blocked by CleanTalk