; Step 5 ; Let's add real orientation - background orientation. ; So we will be working with only background oriented positions ; which will have to be converted to visual (screen) orientation. ; Bedazzling? ; The question is how the background position relates ; to the screen position. ; ; +---------------+ ; | | - Screen ; | | ; | | ; | + - - - |-------+ ; | | | | - Background ; | | | ; | | | | ; +---------------+ | ; | | ; | | ; | | ; +---------------+ ; ; Imagine that the background doesn't move. ; And we can move our screen using the Screen_Pos variables. ; ; So the background is always at position: ; ; ( 0 , 0 ) ; ; Then the screen, in the above picture, would have to be located at: ; ; ( -Screen_SizeX / 2 , -Screen_SizeY / 2 ) ; ; So our screen position of the background is: ; ; ( Screen_SizeX / 2 , Screen_SizeY / 2 ) ; ; Yes, it's *again* the reversed of each other. ; But what if we introduce Back_WorldPos variables ; to control the background position in our world? ; ; +---------------+ ; | | - Background ; | | ; | | ; | +---------------+ ; | | | | - Screen ; | | | ; | | | | ; +-------| - - - + | ; | | ; | | ; | | ; +---------------+ ; ; In relativity, by definition, you can't figure out an absolute point ; without an absolute orientation point. ; So let's add a universal orientation point 'P' ; which is always located at world coordinate ( 0 , 0 ). ; Yes, world coordinate, meaning it can be anywhere on, ; or off our screen. ; ; We'll hide the background for now and make the screen (view) ; start at world coordinate ( 0 , 0 ). ; ; (0,0) ; \ ; P---------------+ ; | | - Screen ; | | ; | | ; | | ; | | ; | | ; | | ; +---------------+ ; ; Moving the screen around, like before, for example, ; to the upperleft about half a screen. ; So our screen position: ; ; ( -Screen_SizeX / 2 , -Screen_SizeY / 2 ) ; ; Now where is our orientation point? ; ; +---------------+ ; | | - Screen ; | (0,0) | ; | \ | ; | P | ; | | ; | | ; | | ; +---------------+ ; ; This is.. where? ; ; ( Screen_SizeX / 2 , Screen_SizeY / 2 ) ; ; Oh no not again.. ; The orientation point position on screen seems to be the ; reversed of the screen position. ; ; So how would you calculate the position of P on screen ; using the position of P in our world (0,0) ; and our screen position? ; E.g. converting a world coordinate to a screen coordinate. ; ; Say, we move screen to position (-10,-10).. ; Then where is our orientation point on screen? ; ; ( 10 , 10 ) ; ; So, in english, our orientation point at (0,0) does something ; with the screen position to get the point on screen. ; ; P in world ... Screen_Pos = P on screen ; ; So.. ; ; ( 0 , 0 ) ... Screen_Pos = P on screen ; ; If Screen_Pos is (-10,-10) then you know that the position ; on screen is (10,10). ; Just fill that in. ; ; ( 0 , 0 ) ... ( -10 , -10 ) = ( 10 , 10 ) ; ; So let's reverse the formula using what we know. ; ; Screen_Pos = ( -10 , -10 ) ; P on screen = ( 10 , 10 ) ; P in world = ( 0 , 0 ) ; ; P on screen ... Screen_Pos = P in world ; ( 10 , 10 ) ... ( -10 , -10 ) = ( 0 , 0 ) ; ; What operator (/, *, -, +) needs to be on the '...'? ; ; 10 / -10 = -1 ; 10 * -10 = -100 ; 10 - -10 = 20 ; 10 + -10 = 0 ; ; I think it needs to be a '+' :) ; So, fill it in: ; ; P on screen + Screen_Pos = P in world ; ; Well we already know the world position. ; But we want to know the screen position, right? ; So reverse the formula back to the way it was: ; ; P in world ... Screen_Pos = P on screen ; ; Swap the sides so it's more clear. ; ; P on screen = P in world ... Screen_Pos ; ; And the other formula.. ; ; P on screen + Screen_Pos = P in world ; ; Also swap sides. ; ; P in world = P on screen + Screen_Pos ; ; Let's compare those two. ; ; P in world = P on screen + Screen_Pos ; P on screen = P in world ... Screen_Pos ; ; So our first is from world to screen position. ; And the second is from screen to world position. ; Let's fill in some values to make it very clear. ; ; P in world = 0 ; Screen_Pos = -10 ; P on screen = 10 ; ; 0 = 10 + -10 ; 10 = 0 ... -10 ; ; Let's simplify this a bit to make it *even* more clear :) ; ; P in world = 3 ; Screen_Pos = 1 ; P on screen = 2 ; ; 3 = 2 + 1 ; 2 = 3 ... 1 ; ; Must be clear enough now that by subtracting 1 from 3 you get 2. ; There's even a handyman technique to figure this out. ; ; +---+ ; / \ ; / 3 \ ; / \ ; + = + ; | | ; | 1 + 2 | ; | | ; +-----+-----+ ; ; Who lives upstairs is dominant, 3 = 1 + 2. ; ; +---+ ; / \ ; / 3 \ ; / \ ; + - + ; | | ; | 1 = 2 | ; | | ; +-----+-----+ ; ; There's more.. ; ; +-----------+ ; | | ; | 3 | ; | | ; | - +-----+ ; | | ; | 1 = 2 | ; | | ; +-----+-----+ ; ; +-----------+ ; | | ; | 3 | ; | | ; +-----+ - | ; | | ; | 1 = 2 | ; | | ; +-----+-----+ ; ; +-----------+ ; | | ; | 3 | ; | | ; |-- = --| ; | | ; | 1 + 2 | ; | | ; +-----------+ ; ; Let's get back to the original formula's.. ; ; P in world = 0 ; Screen_Pos = -10 ; P on screen = 10 ; ; 0 = 10 + -10 ; 10 = 0 ... -10 ; ; You see here that P in world is 'dominant'. ; So.. ; ; 10 = 0 - -10 ; ; And you know that.. ; ; a = b - - c ; ; Is the same as.. ; ; a = b + c ; ; So.. ; ; 0 + 10 = 10 ; ; So it *has* to be correct :) ; The formula: ; ; P on screen = P in world - Screen_Pos ; ; Can also be written as: ; ; P on screen = -Screen_Pos + P in world ; ; Because: ; ; P on screen = (P in world) + (-Screen_Pos) ; ; So, now you know how to go from world position to screen position! :) ; And the best thing is that this works for all relative positioning. ; ; So if we get our background back, and use a screen position ; and a world position for it. ; And ofcourse we still have our screen position. ; Then you can simply substitute the orientation point with the ; background points. ; ; Background on screen = Background in world - Screen_Pos ; ; So this means: ; ; Back_ScreenPosX = Back_WorldPosX - Screen_PosX ; Back_ScreenPosY = Back_WorldPosY - Screen_PosY ; ; Okay, so after 5 miles of text and headaches, ; let's use this in practice :o) ; ; It's basically the same program as before, ; *but* with a significant addition. ; You can now control both the background and the screen independently. ; ; Use the regular arrow keys to control the screen, ; and the arrows on the keypad to control the background. Back_SizeX = GraphicsWidth () Back_SizeY = GraphicsHeight () ; Background starts at world coordinate (0,0). Back_WorldPosX = 0 Back_WorldPosY = 0 ; Screen starts at coordinate (0,0). Screen_PosX = 0 Screen_PosY = 0 ; I hear you asking what kind of orientation the screen has. ; Frankly it's pretty much up to you. ; Sometimes you want to start displaying stuff from a certain offset, ; for example in split screen games. ; In our case the screen position is actually also a world coordinate. ; For example because our scale is always the same. ; E.g. one pixel in our world is one pixel on the screen. ; But let's keep it simple by just using an absolute screen position. ; E.g. the view point of our screen. SetBuffer BackBuffer () Repeat ; Regular arrows If KeyDown ( 200 ) Then Screen_PosY = Screen_PosY - 2 If KeyDown ( 208 ) Then Screen_PosY = Screen_PosY + 2 If KeyDown ( 203 ) Then Screen_PosX = Screen_PosX - 2 If KeyDown ( 205 ) Then Screen_PosX = Screen_PosX + 2 ; Keypad arrows If KeyDown ( 72 ) Then Back_WorldPosY = Back_WorldPosY - 2 If KeyDown ( 80 ) Then Back_WorldPosY = Back_WorldPosY + 2 If KeyDown ( 75 ) Then Back_WorldPosX = Back_WorldPosX - 2 If KeyDown ( 77 ) Then Back_WorldPosX = Back_WorldPosX + 2 ; Calculate background position Back_ScreenPosX = Back_WorldPosX - Screen_PosX Back_ScreenPosY = Back_WorldPosY - Screen_PosY Rect Back_ScreenPosX , Back_ScreenPosY , Back_SizeX , Back_SizeY , False Flip Cls Until KeyHit ( 1 ) End ; In Blitz3D you can use so called 'pivots', being pivot points, which ; serve exactly the same purpose; relativity :)