Rotation around point (SOLVED)

Hello,
I’m trying to rotate object around another object or arond center.
I’m working with this mathematical formula:
x′=xcosθ−ysinθ
y′=ycosθ+xsinθ
I know there are more efective ways, but I need do it like this, the reason is difficult to explain.
I programmed it in Defold with this code:

pos = vmath.vector3()
pos = go.get_position()
pos1 = go.get_position()
center = go.get_position("center")

pos.x = (center.x - pos1.x) * math.cos(math.rad(90)) - (center.y - pos1.y) * math.sin(math.rad(90)) 
pos.y = (center.y - pos1.y) * math.cos(math.rad(90)) + (center.x - pos1.x) * math.sin(math.rad(90)) 
print(pos)
go.set_position(pos)

The most important part of code is there:

pos.x = (center.x - pos1.x) * math.cos(math.rad(90)) - (center.y - pos1.y) * math.sin(math.rad(90)) 
pos.y = (center.y - pos1.y) * math.cos(math.rad(90)) + (center.x - pos1.x) * math.sin(math.rad(90)) 

But it doesn’t work as I want. Does anybody know why?
Thank you for every answer.

What happens? A screenshot, or some explanation of the result would be helpful.

I would suggest that you use the world position instead of the local position. If neither of “center” or the game object the script component is attached to has a parent game object then it won’t matter, but if you parent one of them it will not work as expected.

Try using go.get_world_position() instead.

1 Like

Thank you very much for your answer.
In my game I haven’t got any parent object.
In my project when I want to rotate for example around 180 degrees then it do this:


(in the top down left corner of screen are both objects and the object who is closer to corner is rotating around the twice object)

When rotating around a point (I assume this is the “center” we’re talking about, you start by transforming into the space of that point.

This means (for this 2D point):

local dir = pos1 - center

Now, the dir vector can be rotated.
And, when you’re done, you transform it back into world space again:

pos = dir + center
2 Likes

Hello, thanks to everyone who helped me.
I finally did it. I will share my code with you here, I believe that it will be useful to someone.

function init(self)
msg.post("#camera", "acquire_camera_focus")
msg.post("@render:", "use_fixed_projection", { zoom = 0.5, near = -1, far = 1 })
dir = go.get_position("center") - go.get_position("target")
rot = 1
end

function update(self, dt)
rot = rot + 1
if rot >= 360 then
	rot = 0 
end

go.set(".", "euler.z", rot)
x = dir.x*math.cos(math.rad(rot)) - dir.y*math.sin(math.rad(rot))
y = dir.y*math.cos(math.rad(rot)) + dir.x*math.sin(math.rad(rot))
x = x + go.get_position("center").x
y = y + go.get_position("center").y
pos = vmath.vector3(x, y, 0)
go.set_position(pos)
print(rot ..": ".. x, y) 
end

I’m glad that you solved it!

Some notes in the code:

Since you update the rotation 1 degree each frame, you’ll be susceptible to varying frame rate. A better way would be multiply the speed (1) with the delta time (dt):

rot = rot + 1 * dt

However, since you’re also setting the value euler.z, you can instead animate that property over time:

function init(self)
    go.animate(".", "euler.z", go.PLAYBACK_LOOP_FORWARD, 360, go.EASING_LINEAR, 2)
end

And, there are other functions that can help when rotating around an axis, such as the vmath.quat_rotation_z

Here’s an example:

4 Likes

Thank you very much, you helped me a lot, I was surprised that the object somehow accelerates strangely.

Just a thought here - do we have more such great examples that could be on codepad? Could it be embedded to the defold website maybe? @Mathias_Westerdahl @britzl

1 Like