Should be easy find Z on a ramp with x and y (SOLVED)
#2 Members - Reputation: 152
Posted 21 February 2012 - 12:24 PM
minZ+(maxZ-minZ)*((X-minX)/(maxX-minX))
At least I think that's right off the top of my head. You use the X position to find the percent (0-1) across the tile you are, and multiply it by the height of the tile. The adding of minZ and subtracting of minX are just because the tile isn't located at (0,0,0). Hopefully that made sense...
#3 Members - Reputation: 102
Posted 21 February 2012 - 05:28 PM
#6 Members - Reputation: 152
Posted 21 February 2012 - 07:53 PM
#10 Members - Reputation: 152
Posted 22 February 2012 - 09:02 PM
Leftsidez=TopZ+ (leftz-topz) *(y/midY) ;
Top right:
Rightsidez=Topz+ (rightz-topz) *(y/midy) ;
Interpolate between left side and right side:
Z=Leftsidez+ (rightsidez-leftsidez) *(x/maxX)
(midy=maxy/2)
I think that's all right, off the top of my head. If y> midy, switch top with mid and mid with bottom.
#11 Members - Reputation: 102
Posted 22 February 2012 - 11:45 PM
a = GetDistance(Player.localX, 0, Player.localY, 22, 0, BLOCK_Z) b = GetDistance(Player.localX, 0, Player.localY, 22, 0, 0) c = BLOCK_Z s = (a + b + c) / 2 ar = (s * (s - a) * (s - b) * (s - c)) ^ 0.5 distance = ar / (c * 0.5) Player.z = distance ...... Public Function GetDistance(ByVal x1 As Long, ByVal x2 As Long, _ ByVal y1 As Long, ByVal y2 As Long, ByVal z1 As Long, ByVal z2 As Long) As Long GetDistance = ((x2 - x1) ^ 2 + (y2 - y1) ^ 2 + (z2 - z1) ^ 2) ^ 0.5 End Function
#13 Members - Reputation: 102
Posted 23 February 2012 - 12:39 PM
Edit: Help to find that post: It is halfway down on the second page posted by althing06
#16 Members - Reputation: 102
Posted 23 February 2012 - 04:32 PM
a = point_distance character x,y to right top edge (of slope sprite) b= point_distance character x,y to right bottom edge c = point_distance right top corner to right bottom corner s = (a+b+c)/2 ar = sqrt(s*(s-a)*(s- b )*(s-c)) distance = ar / (c * .5)the descriptions he gives for the points are vague. I am not sure if by right top edge he means the ztop of the ramp or the y of the sprite or the y of the diamond or what. I have tried many different combinations and no luck. It is giving me like a corner of a pyramid. I am searching on the internet but can't seem to find anything else.
#17 Members - Reputation: 110
Posted 23 February 2012 - 09:40 PM
The problem seems to be that you need to find the distance 'into the ramp' - that is, the distance in the up-right direction on the tile. On the illustration above, it's the length of the red vector. Once you have that, you can do a simple linear interpolation between 0 and maxZ.
The purple vector p in the illustration gives the position of the player relative to point D. You can easily calculate it in terms of its x- and y-components, but you need it written as a sum of the red vector and the blue vector; that way you can just take the length of the red vector component, and that will be the distance 'into the ramp'.
The green and pink vectors e1 and e2, shown coming out of point D, should be normalized. They are easy to calculate; just subtract D from A and normalize to get the green vector, and subtract D from C and normalize to get the pink vector.
The red vector is proportional to e1 and the the blue vector is proportional to e2, so all you need to do is find the scaling factors to scale them up to the correct size:
redVector = c1*e1
blueVector = c2*e2
so
p = redVector + blueVector
p = c1*e1 + c2*e2
p.x = c1*e1.x + c2*e2.x
p.y = c1*e1.y + c2*e2.y
Now you have two equations for c1 and c2, so it's easy to solve for them; you should come out with:
c1 = (p.x*e2.y - p.y*e2.x)/(e1.x*e2.y - e1.y*e2.x)
We said that e1 was normalized, so, since redVector = c1*e1, the length of redVector - and therefore the distance 'into the ramp' - is just c1. The height, then, is a linear interpolation:
height = (c1/|AD|)*maxZ
where |AD| is the length of side AD. I haven't tried this in game code of any sort, but I've graphed the c1 function and gotten sensible results. Hopefully if you decide to use it it works for you!
#18 Members - Reputation: 102
Posted 23 February 2012 - 11:42 PM
p = redVector + blueVector
p = c1*e1 + c2*e2
p.x = c1*e1.x + c2*e2.x
p.y = c1*e1.y + c2*e2.y
c1 is used in these equations and then
You find the value of c1 using the previous values you just found using c1?!?!
c1 = (p.x*e2.y - p.y*e2.x)/(e1.x*e2.y - e1.y*e2.x)
Also I am not a very strong math person. What does normalize mean?
Edit: I am trying to go through and understand. are e1 and e2 cordinates, lines, distances? you have e2.y and ect so it makes me think they are coordinates. Sorry I am very bad with math. I looked up normalizing numbers and it is simple enough. what I don't understand is am I getting a set of coordinates for the line or is it a set of lengths. Also is p.x and p stuff the players x or do you mean the line p in the picture. Please clarify and dumb it down for me. Things like this : p = redVector + blueVector <-- how do you add two lines together? They consist of 4 sets of different cords.
#19 Members - Reputation: 110
Posted 25 February 2012 - 09:26 AM
Mikekan13 said:
You find the value of c1 using the previous values you just found using c1?!?!
Mikekan13 said:
...
what I don't understand is am I getting a set of coordinates for the line or is it a set of lengths. Also is p.x and stuff the players x or do you mean the line p in the picture.
When I drew the line p, then, I meant p to be the location at the tip of the arrowhead. It's a line that represents a position. In this case I drew the line from point D, meaning that the coordinates of the location should be measured from point D, not from the origin of the entire game map.
Mikekan13 said:
The end of the vector with the arrowhead is called the head, and the back end is called the tail. Graphically, you add two vectors by lining up the head of one with the tail of the other; you can do that because, as I said, the overall position of a vector doesn't matter. The sum is then the vector from the tail of the first vector to the head of the second vector. I don't have the red and the blue vector lined up that way, but note that if you shift the blue vector down and left until its head is on the red vector's tail, the purple vector goes from the blue tail to the red head.
You can get the same result by adding the vectors' components separately; if you have three vectors a, b, and c so that a + b = c, then ax + bx = cx and ay + by = cy. That's how I got the x and the y equation from the redVector + blueVector sum. A more concrete example might be 'If I move 3 meters left and 2 meters up and then I move 1 meter right and 5 meters down, all together my position will have moved 2 meters left and 3 meters down.'
You're adding a two-component vector to another two-component vector. These vectors are stored with two components instead of four because, again, the start and end positions don't matter, just the difference between them. The result is one two component vector; two of the original components form one of the new components, and the other two form the other. Adding vectors component-by-component is usually how it's done in code.
I've written some C++ code that I hope will help clarify what I mean; instead of explicit vectors it uses separate coordinates, which might be more familiar to you. A, B, C, and D are the locations of the corners of the diamond, as defined in the image in my previous post. pxWorld and pyWorld are the two-dimensional coordinates of the player using the same coordinate system that you used to measure A, B, C and D - meaning if you measure A, B, C and D from the bottom-left of the entire map, you should measure pxWorld and pyWorld from the bottom-left of the entire map as well:
float getHeight(float Ax, float Ay, float Bx, float By, float Cx, float Cy, float Dx, float Dy, float pxWorld, float pyWorld, float maxZ)
{
//calculate player position relative to point D
float px = pxWorld - Dx;
float py = pyWorld - Dy;
//calculate e1 and e2, including normalization
float e1x = (Ax - Dx)/Sqrt((Ax - Dx)*(Ax - Dx) + (Ay - Dy)*(Ay - Dy));
float e1y = (Ay - Dy)/Sqrt((Ax - Dx)*(Ax - Dx) + (Ay - Dy)*(Ay - Dy));
float e2x = (Cx - Dx)/Sqrt((Cx - Dx)*(Cx - Dx) + (Cy - Dy)*(Cy - Dy));
float e2y = (Cy - Dy)/Sqrt((Cx - Dx)*(Cx - Dx) + (Cy - Dy)*(Cy - Dy));
//calculate c1
float c1 = (px*e2y - py*e2x)/(e1x*e2y - e1y*e2x);
//do the linear interpolation and return the result
float AD = Sqrt((Ax - Dx)*(Ax - Dx) + (Ay - Dy)*(Ay - Dy));
float height = c1/AD*maxZ;
}
I should say that I haven't tried to compile or run it. It's not at all optimized, of course - A, B, C, D, and maxZ presumably don't change, so a lot of things could be precalculated - but I hope it makes the method I describe more clear.
Edit: added Bx and By to the function's arguments; whoops!


















