Rotation & offset position
BlitzMax Forums/BlitzMax Programming/Rotation & offset position
| ||
Example problem: I have an image (100x100) that I want to draw in the center of a rectangular area (300x200). The image can vary in size/aspect ratio as can the rectangular area. The image could also be text drawn with DrawText(), as such the image handle must remain the default (to be compatable with drawing text in it's place). To draw centered I would normally calculate the offset by the following. x = rectArea.x + rectArea.width/2 - image.width/2 This works great. However I now need to rotate the drawing area. The offset calculation won't take the rotation into account, so it will be drawn where it previously would have been, just rotated... Any suggestions on a relatively easy way to calculate the x and y offsets taking rotation into account? If it were all mid handled it wouldn't be a problem, but then I couldn't support text unless I did something like draw the text to the backbuffer, grab it with masking into an image and use that... but that will come out with some jaggies etc and is quite a lot slower since I have to draw/grab/image-draw every text element... |
| ||
use AutoMidHandle and just draw the image at the center of the rectangle? If it's text it should work too? |
| ||
I'm unaware of any way to get text to mid handle. AutoMidHandle, just sets the imagehandle to it's mid point automatically when it's created (the same process as creating an image and then setting it's handle yourself), but text is not created as an image as such, just given a draw position which is it's upper left corner. While in the end I think it all gets rendered out to surfaces before being draw (rotation works etc.) but since there's no direct access to that surface, auto mid doesn't work. |
| ||
There are also other reasons I need to calculate the offset, such as determining if a click is inside a rect that is rotated. The top example is the the cleanest I could think off (fewer extra steps etc.) though I suppose text would have been stricter... new example: I want to draw text centered, inside a rectangle, scaled and rotated I calculate the position without rotation as follows x = rectArea.x * scale + (rectArea.width * scale)/2.0 - (TextWidth(text) * scale)/2.0 How would I factor rotation into the offset for text. Alternatively how can one mid-handle text. |
| ||
Function TextHeight( text$ ) Function TextWidth( text$ ) the height/width, in pixels, of text based on the current image font. |
| ||
I don't know if this is any help to you but this code uses blitzmax integrated scale and rotation to solve it:SuperStrict Graphics 800,600 Global gfx:TMax2dGraphics = tmax2dgraphics.Current() Global text:String = "this is centered" Global scale:Float = 2.0 Global angle:Float = 0.0 Local transx:Float = (Float(TextWidth(text))/2.0) 'text center width Local transy:Float = (Float(TextHeight(text))/2.0) 'text center height SetScale scale,scale Repeat Cls SetRotation angle Local x:Float = 300 - (transx * gfx.tform_ix + transy * gfx.tform_iy) Local y:Float = 300 - (transx * gfx.tform_jx + transy * gfx.tform_jy) DrawText text,x,y angle :+ 1.0 Flip() Until KeyDown(key_escape) |
| ||
Jesse my hero! that's perfect for mid handling text... had no idea the tform was accessable and usable in that way, love it! |
| ||
Ima747 are just trying to rotate the screen and have all image drawn in the correct place? I couldn't quite work it out from your first post. If you are you might want to check out my Odd2D module which does exactly that. It even has a function for getting the correct mouse position after rotation. |
| ||
In full what I need to accomplish is to draw a base image un rotated and un-scaled. On top of that draw rectangles that can be individually rotated. They can also be outlined (with drawline) so the lines need to be positioned and rotated as well. And finally draw images and or text centered inside those rotated rectangles that preserve the image/text aspect ratio... and a few other things, but each set of elements has to be matched together. With jesse's code it is possible to calculate an offset that takes into account the currently active rotation, which means I can do all the various things I need to. His sample specifically gives you text that behaves like a midhandled image to make the rotation easy. |
| ||
Here are the offset functions I've spun incase anyone else needs them.Function OffsetWithRotationX:Float(pivotX:Float, offsetX:Float, offsetY:Float) local gfx:TMax2dGraphics = tmax2dgraphics.Current() Return pivotX + (offsetX * gfx.tform_ix + offsetY * gfx.tform_iy) End Function Function OffsetWithRotationY:Float(pivotY:Float, offsetX:Float, offsetY:Float) local gfx:TMax2dGraphics = tmax2dgraphics.Current() Return pivotY + (offsetX * gfx.tform_jx + offsetY * gfx.tform_jy) End Function For better performance mod them to take gfx as an input or just make that a global somewhere else, speed isn't an issue for me so I made it more code portable for re-use some other time. Important note, since these calculate positions with rotation factored in don't use them directly in things like DrawLine(), as the second point in draw line automatically has rotation applied to it so you end up with double rotation... but they're perfect for calculating an offset with rotation such as centering text, etc. [update] Corrected typo in function names important note, this takes your graphics scale setting into account as well so don't forget about that when passing in your desired offsets (they will be scaled, use full size) |
| ||
This thread is being weird for me. My post says (Posted 20 hours ago) Edit #5 but the post before says (Posted 54 minutes ago) #4 and the ones prior have more recent times too. |
| ||
This happens every month on the 1st. Times get screwy. Something in the calculation Mark uses. |