Rotation problem

BlitzMax Forums/BlitzMax Programming/Rotation problem

ziggy(Posted 2008) [#1]
I need a formula to get the X and Y position of an image, giving another X and Y position as a center, and a rotation factor, and I have had no luck with my trigonometric skill. Any help would be much apreciated.

Somethig Like:
Function GetNewXY(..
      OriginX:Float, OriginY:float, ..
      CenterX:Float, CenterY:Float, ..
      Angle:Float, ..
      Var ReturnX:Float, Var ReturnY:Float..
)
DOSTUFFHERE
End Function

Any help would be very apreciated.


Dreamora(Posted 2008) [#2]
newX = originX + radius*cos(angle)
newY = originY + radius*sin(angle)


ziggy(Posted 2008) [#3]
Thanks Dreamora!
I think this will do the trick. Just one question, this OriginX is relative to the centerX, isn't it?


Dreamora(Posted 2008) [#4]
No, it is global coordinates.
If you want it to be relative, just remove the originX / Y from the equations and let the coordinates rotate around a "fictive" 0,0 point in space. By adding the original center coords to that, you then can let an object rotate around any origin you want.


ziggy(Posted 2008) [#5]
Ok, that's what I was suposing. Thanks


Dreamora(Posted 2008) [#6]
btw: if you intend that to use within a system, I would suggest make a 2x3 matrix out of it :)

Matrix T =  |r*cos(angle)  r*sin(angle)  offsetX|
            |-r*sin(angle) r*cos(angle)  offsetY|
Vector newPos, oldPos, both [X Y 1] component wise

newPos = T * oldPos


This matrix T can be split down to 2 distinct submatrices and save calculation time if you want to use it for hierarchy . (as well, sin and cos can be precalculated)

Multiple transformations down the hierarchy would be as simple as

newPos = T_3 * T_2 * T_1 * oldPos
where T_x refers to the level down the hierarchy (depth) and oldPos is the global position you want to transform through that.


ziggy(Posted 2008) [#7]
where r is radius?
Angle will be constant in most situations, so I don't thing it would make a real diference, but I will make some tests before proceeding. thanks!


Dreamora(Posted 2008) [#8]
the matrices make only sense if you have hierarchy and need to be able to propagandate the changes to the childs attached to the current object. otherwise not.


ziggy(Posted 2008) [#9]
Hy, I've finally done this function, but it is not working as spected. Resulting coordinates are sometimes wrong. Any ideas?

Function GetRotationCords:TDrawingPoint(Angle:Float, Source:TDrawingPoint, Center:TDrawingPoint) 
	Local Radius:Double = Sqr((source.X - center.x) ^ 2 + (source.Y - center.Y) ^ 2) 
	Local NewX:Double = Center.X + radius * Cos(angle) 
	Local NewY:Double = Center.Y + radius * Sin(angle) 
	Return CreateDrawingPoint(newx, newy) 
End Function

'----------
Type TDrawingPoint
	Field X:Float
	Field Y:Float	
	Function Create:TDrawingPoint(X:Float, Y:Float) 
		Local DP:TDrawingPoint = New TDrawingPoint
		dp.X = x
		dp.Y = y
		Return dp
	End Function
End Type

Function CreateDrawingPoint:TDrawingPoint(X:Float, Y:Float) 
	Return TDrawingPoint.Create(x, y) 
End Function


In this function: Angle is the angle to rotate, Source is the non-rotated point(x and Y), and Center is the rotation center. I don't know why but I'm getting some problems when the rotation center Y is not the same as the source Y, very weird. I have no idea what is wrong.


Jesse(Posted 2008) [#10]
I tested your code and it is doing exactly what it supposed to do. if you don't move the center, the point rotates around the radius created by the center and the point. if you move the center while processing, the radius either becomes larger or smaller and will creates a different radius of rotation. if you want it to continually rotate around a fixed radius than you need to make it a fixed radius. this is how I tested it:
SuperStrict

Function GetRotationCords:TDrawingPoint(Angle:Float, Source:TDrawingPoint, Center:TDrawingPoint) 
	Local Radius:Double = Sqr((source.X - center.x) ^ 2 + (source.Y - center.Y) ^ 2) 
	Local NewX:Double = Center.X + radius * Cos(angle) 
	Local NewY:Double = Center.Y + radius * Sin(angle)
	Return CreateDrawingPoint(newx, newy) 
End Function

'----------
Type TDrawingPoint
	Field X:Float
	Field Y:Float	
	Function Create:TDrawingPoint(X:Float, Y:Float) 
		Local DP:TDrawingPoint = New TDrawingPoint
		dp.X = x
		dp.Y = y
		Return dp
	End Function
End Type

Function CreateDrawingPoint:TDrawingPoint(X:Float, Y:Float) 
	Return TDrawingPoint.Create(x, y) 
End Function


Local a# = 0.0
Local source:tdrawingpoint = createDrawingPoint(160,160)
Local center:tdrawingPoint = CreateDrawingPoint(200,200)

Graphics 800,600

Repeat

	'Cls
	source = GetRotationCords(a,source,center)
	Plot center.x,center.y
	DrawOval source.x-10,source.y-10,20,20
	a:+1.0
	Flip()
Until KeyDown(key_escape)

if you want it to rotate around a moving object then you need to have a fixed radius and keep track of the angle.
[edited]
if you want to determine the original angle the point is
from the center then you need the atan2 math function.


ziggy(Posted 2008) [#11]
Thanks, it work... it was me being stupid