How to draw rotated box

BlitzMax Forums/BlitzMax Beginners Area/How to draw rotated box

monotonic(Posted 2009) [#1]
Hi folks,

I've been trying to figure out how to draw a rotated box, but to no avail. So basically I want to draw a box (2D) which will be rotated at a random angle, I need to draw it pixel by pixel, so I can't use sprites. technically I'm not drawing it I'm writing values into a 2D array, which is used for pathfinding.

Any ideas would be appreciated.


N(Posted 2009) [#2]
Just use SetHandle to set the position you want the pixel (I guess) to be rotated from relative to the pixel you're drawing. E.g.,

SetRotation some°
For each box
  SetHandle box.x - origin.x, box.y - origin.y
  DrawRect origin.x, origin.y, width, height
Next



monotonic(Posted 2009) [#3]
Hi,

thanks for the reply, I was looking for something where I calculate the new position of the pixel based on it's original position and the angle of the box. I've tried using:

new_x = x*cos(theta) - y*sin(theta);
new_y = y*cos(theta) + x*sin(theta);

but that didn't work, obviously the origin of the box was added to the result.


N(Posted 2009) [#4]
That's probalby more effort than it's worth if you've already got equivalent functionality built into Max2D.


monotonic(Posted 2009) [#5]
That's the point I'm not drawing a box to the screen I'm writing values into a 2D array, so the standard drawing techniques won't work. I just need the transformed x, y coordinates.


_Skully(Posted 2009) [#6]
Oh...

I think what you need to do is get the atan2 & dist of the position relative to your handle, then rotate it

so if your point is 15,10 and your mid-handle is 20,20

ang#=atan2(15-20,10-20)
dist#=sqr((15-20)^2+(10-20)^2)

then I think...

new_x=sin(ang+theta)*dist+20
new_y=cos(ang+theta)*dist+20

or something like that (its just off the top of my head)


matibee(Posted 2009) [#7]
Somthing like this...

superstrict

Graphics 1200, 100

' simple function for showing our arrays on screen
Function drawArray( xpos%, ypos%, scale%, a:Byte Ptr, width%, height% )
	For Local y% = 0 To height - 1
		For Local x% = 0 To width - 1
			If ( a[y * width + x] )
				DrawRect( xpos + (x * scale), ypos + (y * scale), scale, scale )
			End If 
		Next 
	Next 
End Function 

' rotate array function
Function rotateArray( xorig%, yorig%, angle#, srcArray:Byte Ptr, destArray:Byte Ptr, width%, height% )
	For Local y% = 0 To height - 1
		For Local x% = 0 To width - 1
			Local srcX% = ( Cos( angle ) * (x - xorig) - Sin( angle ) * (y - yorig) ) + xorig
			Local srcY% = ( Sin( angle ) * (x - xorig) + Cos( angle ) * (y - yorig) ) + yorig
			If ( srcX >= 0 And srcX < width And srcY >= 0 And srcY < height )
				destArray[ y * width + x ] = srcArray[srcY * width + srcX]
			End If 
		Next 
	Next 
End Function 

' src and destination arrays
Local arraySrc:Byte[20,20] 
Local arrayDest:Byte[20,20] 

' a solid rect in the middle of the array..
For Local y% = 4 To 15
	For Local x% = 6 To 13
		arraySrc[y,x] = 1
	Next 
Next 

' draw some results..
Cls 

For Local rotate% = 0 To 90 Step 10
	rotateArray( 10, 10, rotate, arraySrc, arrayDest, 20, 20 )
	drawArray( rotate * 12, 0, 5, arrayDest, 20, 20 )
Next 

Flip 

While ( Not KeyDown( key_escape ) )
Wend 


Another way would be to actually draw a rotated box to the screen, grab the screen area and interrogate it for set pixels.

That code hasn't been tested much beyond the sample you see there.

Cheers
Matt


monotonic(Posted 2009) [#8]
Hi Matibee,

that's basically what I'm using at the minute, the snippet I posted earlier is the same the only difference is I the origin of my original data is 0,0 so I don't need to take into account the difference I just use the x, y coordinates. This would suggest there is a problem somewhere else in my code, ugh... Looks like another late night debugging.

Thanks for the help guys.


matibee(Posted 2009) [#9]
So how is it broke?

I was looking for something where I calculate the new position of the pixel based on it's original position


That's the wrong way round btw. Some rotated pixels will end up in more than one destination. My example does the inverse transform of the dest pixel to look into the source.

Upon re-reading I guess you mean *something else* is broke in your code, not your array rotation :)


luke101(Posted 2009) [#10]
Toook a look at your loops. Just a quick note. Wouldnt it be much faster to store all angle calculations in an array rather then calculating them real time? It will use more ram and increase the loading time but the pros will outweigh the cons.