Rob Gates
Rob Gates

Reputation: 275

Rotating a point around origin in canvas

For a game a friend and I are creating, we are making a radar. We've already made a basic radar, in the sense that everything is displayed in the proper position, however we are trying to add rotation to the radar. This rotation is based on the local players angle which starting at 0 degrees is facing directly north, goes 360 clockwise until north again.

I was wondering how to rotate all the points on the canvas (these can be other players, items, etc) from the local player angle. We are trying to make it so whenever the player walks forward, the player moves directly up in the radar as well. No matter what the degree of rotation is, the player should always be going "up" the radar while walking directly forward.

I tried doing basic rotation, like this to each player: var baseX = x - localX, baseY = (canvas.height-y) - localY; var localAngle = toRadians(players[0].rotation);

  var newX = baseX * Math.cos(localAngle) - baseY * Math.sin(localAngle);
  var newY = baseX * Math.sin(localAngle) + baseY * Math.cos(localAngle);

  newX += localX;
  newY += localY;

The issue with that is that I was not always going "up" the radar, it depended where I was looking. Thank you.

Upvotes: 0

Views: 592

Answers (1)

Anatoly Strashkevich
Anatoly Strashkevich

Reputation: 1914

In order to efficiently rotate things you need to understand concept of basis from linear algebra. In a nutshell this mean that you need two separate vectors (basis vectors) which define for you location of ALL vectors(objects) is space(2D in your case). So if you want to rotate objects in scene you need to apply rotation transformation to all of them. This might be: (rotate to right)

Math.cos  -Math.sin 0
Math.sin  Math.cos 0
0         0        1

(rotate to left)

Math.cos  Math.sin 0
-Math.sin  Math.cos 0
0          0        1

So it goes like this:

let multiplyMatrixVector = (A, v)  => {
    let C=[]; 
    C[0] = (A[0]*v.x)+(A[1]*v.y)+(A[2]*v.z);   
    C[1] = (A[3]*v.x)+(A[4]*v.y)+(A[5]*v.z);
    C[2] = (A[6]*v.x)+(A[7]*v.y)+(A[8]*v.z);   
    return {x:C[0], y:C[1], z:C[2]};   
}; 


let locations = [{x:34,y:7,z:0}];
let newLocations = map(
                     (location) => {
                        return multiplyMatrixVector(matrix,location)
                     },  
                     locations
                   )

EDIT: If you want to not only rotate point on radar but also move it you need to apply

translation to your point object in matrix form:
x+a      1 0 a     x
y+b   <- 0 1 b <-  y
1        0 0 1     z 

You can compose it with rotation into single matrix. so you vector goes into translation matrix then into rotation, don't forget about origin vector as well. You need to account it in transformation.

Upvotes: 1

Related Questions