Rotate shape around an arbitrary point

52 views
Skip to first unread message

Darko Draskovic

unread,
Feb 5, 2016, 8:55:33 AM2/5/16
to melonJS - A lightweight HTML5 game engine
Hello! I'm trying to rotate a shape around the center of my Entity object. I use the following code:

 (me.input.isKeyPressed("left")) {
   
this.renderable.angle -=this.angSpeed*dt;
   
var s = this.body.getShape();
    s
.rotate(-this.angSpeed*dt);
}

Although a renderable rotates around its center - since entity's anchorPoint is set to 0.5, 0.5 - the polygon rotates around its upper left corner.

Is there a way to change the pivot/anchor point of the shape? I know that in SAT there is a .setOffset() function which can be used for that purpose.


Brandon Channell

unread,
Feb 5, 2016, 11:39:23 AM2/5/16
to melonJS - A lightweight HTML5 game engine
You can change the anchor point using the set method of the anchorPoint vector.

In your entity object:

this.anchorPoint.set(x, y);

Darko Draskovic

unread,
Feb 5, 2016, 12:21:13 PM2/5/16
to melonJS - A lightweight HTML5 game engine
Thanks for the answer. Maybe I was not specific enough. My anchor point is already set correctly at 0.5, 0.5 and my renderable rotates around its center.

However, I want to rotate shape around its center. As far as I see shape rotation and renderable rotation are not linked, so you have to do it manually.

I've figured out that I can translate shape's point before rotation and translate them back afterwards, but I would like to know if there is an automatic way to do it...

Jay Oster

unread,
Feb 5, 2016, 5:34:26 PM2/5/16
to melonJS - A lightweight HTML5 game engine
Yeah, the anchorPoint is only for adjusting how a renderable anchors to an entity. The shapes have their own API.

Effectively, a shape needs its vertices defined relative to the center point. And me.Rect puts the center point at the upper-left corner. (This makes me sad.) The bad news is that this will require a major redesign. The good news is that there's a workaround if you need the shape's physical center changed :
  1. Convert the rect into a polygon (if it is not already a polygon) with toPolygon()
  2. Get the poly's points array
  3. Adjust the points so they are relative to the expected center
  4. Call setShape() with the new points array
It's ugly. :( But it will get you unblocked.

You might also have to adjust the anchorPoint and entity position after this transformation step. Once it's done, the shape can be freely rotated around its center.


If you do not need to change the physical center, then you can use the standard translation steps surrounding the rotation, which sets the virtual center for rotation:

shape.translate(shape.width / 2, shape.height / 2);
shape
.rotate(Math.PI / 4);
shape
.translate(-shape.width / 2, -shape.height / 2);

Jay Oster

unread,
Feb 5, 2016, 5:45:28 PM2/5/16
to melonJS - A lightweight HTML5 game engine
Oh jeez... Ignore the second suggestion. The shapes are not implemented with matrix2d, so the transformations don't work algebraically. ;( The translate method simply adds a number to the position without taking account for rotation or scale, so it will never work.

The first option is the way to go for now. The shape's physical center needs to be set appropriately.

Darko Draskovic

unread,
Feb 6, 2016, 8:25:40 AM2/6/16
to melonJS - A lightweight HTML5 game engine
Jay, thank you for the solution.

I don't see why we need a major redesign. SAT.js already has a function for that purpose, .setOffset(). As far as I can see Melonjs uses a custom version of SAT.js and that function is left out.

Jay Oster

unread,
Feb 6, 2016, 12:47:36 PM2/6/16
to melonJS - A lightweight HTML5 game engine
An older version of SAT.js, probably. I don't believe it was ever customized. We could update it for sure. (And also use a package manager like bower to help maintain these dependencies.)
Reply all
Reply to author
Forward
0 new messages