Jump to content

World coordinates to local group coordinates


Recommended Posts

Given a position x/y in world coordinates I need the same position, but in the local coordinate system of a given group. The group is a child of a chain of other groups that all apply various transformations.

How do I get the local position?

I'd expect there to be a matrix somewhere to turn global into local coordinates, but I've failed to find it anywhere.

At this point my best idea would be to go through the groups and build my own matrix, but that seems like bypassing something Phaser should be able to do for me?



Link to comment
Share on other sites

What kind of transformations have been done to the chain of groups?  If it's just position and rotation then I think it's reasonably easy maths to convert world coords into local coords.  Of the top of my head, something like this I think:

x(local) = (x(world) - x(group)) / cos(theta)  

where x(local) is what you are trying to find, the x coord local to the group in question, x(world) is the screen coord you already know, x(group) is the world position of the group in question and theta is the rotation of the group in relation to the world.

If there's scaling going on as well, then it get trickier. 

Link to comment
Share on other sites

There may be scaling going on. I know the needed math, just asking about API capabilities.

I've started working out how I'll do it by hand, unless somebody comes around and points at a method somewhere that does what I want already.

So I am just wondering if Phaser already has done this somewhere. No need to reinvent wheels in that case after all.

Link to comment
Share on other sites

  • 7 months later...


What about rotation and scale?

What I'm trying to accomplish here is to move a sprite from the world to a group while maintaining exactly how it looks like (position, rotation and scale) on the screen.

Moving a sprite from a group to the world is easy: just assign it's position to worldPosition, rotation to worldRotation and scale to worldScale. I'm still hoping there's something built-in in phaser to do the reverse that I just haven't found yet. Otherwise my current approach of doing it manually involves inferring the position, scale and rotation based on the result of targetGroup.worldTransform.applyInverse on two different points. Something like:

// Mostly untested, just a demonstration of the approach. No idea if it'll work for nested groups.
function fromWorldTransform(obj, group) {
  let a = group.worldTransform.applyInverse({x: 0, y: 0});
  let b = group.worldTransform.applyInverse({x: 1, y: 0});
  let dist = Phaser.Math.distance(a.x, a.y, b.x, b.y);
  // Assume that scale X and scale Y are equal and are both > 0.
  let scale = 1 / dist;
  let rotation = Phaser.Math.angleBetween(a.x, a.y, b.x, b.y);
  // Position is more straight-forward to calculate, this part generally seems to work.
  let c = group.worldTransform.applyInverse(obj.position);
  let position = c;
  obj.x = c.x;
  obj.y = c.y;
  obj.scale.x = scale;
  obj.scale.y = scale;
  obj.rotation = rotation;


Link to comment
Share on other sites

So I just strangled my memory a bit and read over some old code and I conclude: I did not solve this issue in that way.

I gave up on using deep stacks of groups and instead only used a single group and did everything within it by hand, as this allowed me to separate Phaser from my games logic more cleanly. I also never solved all the problems that came from using Phasers groups in the deep stacked fashion I first tried.


Link to comment
Share on other sites


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...