Rotate around point
BlitzMax Forums/BlitzMax Programming/Rotate around point
| ||
Hey, can someone tell me what I'm doing wrong with the math behind this: I'm just trying to rotate a point around another point, storing those new x/y values. The ending goal of which is to attach a image to another image. as sort of a child: RotateAroundOrigin(x, y, player.x, player.y, player.angle) SetRotation(player.angle) DrawImage img, y, x SetRotation(0) However, this is not working. Additionally, does anyone know of a place that can explain the math behind rotation around a point? I always seem to have trouble getting that to work, no matter how many projects I use it in. |
| ||
You're overcomplicating it. Typed straight into the reply box, so untested. It should give you one point orbiting another. Strict Local xP:int = 400 Local yP:int = 300 Local d:int = 50 Local a:int Local newX:float,newY:float Graphics 800,600 Repeat a:+1 a:Mod 360 newX = Cos(a) * d + xP newY = Sin(a) * d + yP Cls Plot xP,yP 'centre Plot newX,newY ' new coords Flip Forever |
| ||
That works.. Then what was I doing? I googled "rotate point around point 2d" to get the equation I used: "RotatePoint.X = Cos(D2R(Degrees)) * pPoint.X - Sin(D2R(Degrees)) * pPoint.Y RotatePoint.Y = Sin(D2R(Degrees)) * pPoint.X + Cos(D2R(Degrees)) * pPoint.Y" Much different? Anyways, thanks Gfk. |
| ||
I dunno what that's all about! Looks like there's a function missing in there as they're converting from degrees to radians. Your code by-passed that which probably explains why the result did not work. |
| ||
Blitz uses degrees though, right? |
| ||
@Zakk, yes. @Yahfree Your code doesn't behave like the equation you posted. According to the equation, your code should be: newX = Cos(a) * (x-ox) - Sin(a) * (y-oy) + ox newY = Sin(a) * (x-ox) - Cos(a) * (y-oy) + oy However this gives weird results. There is a way to fix your code, but there are some major errors. First of all you don't hold data about the angle of the point. Just the distance. Then the math behind tx an ty is wrong: Function RotateAroundOrigin(X:Float Var, Y:Float Var, ox:Float, oy:Float, a:Int) Local DX:Float = X - ox Local DY:Float = Y - oy Local angdiff:Float = ATan2(DX, DY) Local dist:Float = Sqr(DX * DX + DY * DY) Local s:Float = Sin(a + angdiff) Local c:Float = Cos(a + angdiff) Local tx:Float = (dist * s) Local ty:Float = (dist * c) x = tx + ox y = ty + oy Return End Function Graphics 800, 600 Global oX:Float = 400 Global oY:Float = 300 Global rX:Float = oX + 60 Global rY:Float = oY + 40 Global a:Float = 1 While Not KeyHit(KEY_ESCAPE) RotateAroundOrigin(rX, rY, ox, oy, a) Plot rX, rY Plot ox, oy Flip Wend End This works, but I would recommend using something like this: Type TTransform2D Field Matrix:Double[2, 2] Field Rotation:Float = 0 Field ScaleX:Float = 1 Field ScaleY:Float = 1 Method Init(sx:Float = 1, sy:Float = 1, rot:Float = 0) Self.ScaleX = sx Self.ScaleY = sy Self.Rotation = rot Self.Update() EndMethod Method Scale(sx:Float, sy:Float) ScaleX = sx ScaleY = sy Self.Update() EndMethod Method Update() Matrix[0, 0] = Cos(Rotation) Matrix[1, 0] = - Sin(Rotation) Matrix[0, 1] = Sin(Rotation) Matrix[1, 1] = Cos(Rotation) End Method Method Rotate(angle:Float) Rotation = angle Self.Update() EndMethod Method Transform(x:Float var, y:Float var) Local xx:Float Local yy:Float x = x * ScaleX y = y * ScaleY xx = x * Matrix[0, 0] + y * Matrix[1, 0] yy = x * Matrix[0, 1] + y * Matrix[1, 1] x = xx y = yy End Method Method ITransform(x:Float var, y:Float var) Local xx:Float Local yy:Float Self.Rotation = -Self.Rotation Self.Update() xx = x * Matrix[0, 0] + y * Matrix[1, 0] yy = x * Matrix[0, 1] + y * Matrix[1, 1] Self.Rotation = -Self.Rotation Self.Update() xx = xx / ScaleX yy = yy / ScaleY x = xx y = yy End Method End Type Function RotateAroundOrigin(X:Float Var, Y:Float Var, ox:Float, oy:Float, a:Int) Local t2d:TTransform2D = New TTransform2D t2d.Init(1, 1, a) X:-ox Y:-oy t2d.Transform(X, Y) X:+ox Y:+oy Return End Function Graphics 800, 600 Global oX:Float = 400 Global oY:Float = 300 Global rX:Float = oX + 60 Global rY:Float = oY + 40 Global a:Float = 1 While Not KeyHit(KEY_ESCAPE) RotateAroundOrigin(rX, rY, ox, oy, a) Plot rX, rY Plot ox, oy Flip Wend End |