; 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 :)