DOC

advertisement
1
Rotations of Widelands map
Table of contents:
1.
Short introduction ............................................................................................................................ 2
a)
Basic map: two coordinate systems ............................................................................................. 2
b)
Goal ............................................................................................................................................. 2
c)
How to do that? ........................................................................................................................... 2
d)
Short description of used notation. .............................................................................................. 2
2.
Math calculations ............................................................................................................................ 3
a)
Matrix multiplication ................................................................................................................... 3
b)
Creating rotation matrix .............................................................................................................. 3
3.
Connections between coordinate systems ....................................................................................... 3
a)
Cartesian to zig-zag coordinates .................................................................................................. 4
b)
Zig-zag to Cartesian coordinates ................................................................................................. 4
c)
Rotate a point or vector in Cartesian plane ................................................................................. 4
d)
Rotation of vector on zig-zag plane............................................................................................. 5
4.
Testing the results in shapes ............................................................................................................ 6
5.
Conclusion ....................................................................................................................................... 6
2
1. Short introduction
a) Basic map: two coordinate systems
Widelands maps are triangle-base shaped. It means that if we go up or down, we can choose 2 ways:
up-right and up-left with 60° between the directions.
But our calculations don’t work with that coordinate system. We used to work with square-shaped
coordinate system (Cartesian one). It is orthonormal coordinates system where laws of math are not so
complicated (we learn at school about basic geometry there, because it is easy one).
b) Goal
My goal is to create working universal rotation model. It should work for any angle and any point.
Rotations in Cartesian coordinate system are quite well described, but in triangle-base shaped one are
not. (Ok, they are, but it is not described in every geometry book).
The discussion about the usage of the work is on page https://wl.widelands.org/forum/topic/1634/ .
c) How to do that?
At first we need some “small bricks” from whole problem: get analytic transformation between the
coordinates. Then we should see if it possible to rotate casual zigzag coordinates and find the closest
rotation result- if it is not possible to rotate. At last we should test the solution on some points and
shapes to see if there are any problems with the solution.
For example I will try to get functions that explain how to get from one coordinate system to another:
f1(x1,y1)
F2(x2,y2)
d) Short description of used notation.
In some places there are code parts. This is not any exact programming language, but only an idea how
to work with calculations in any language. The index of any array there begins from 0.
3
2. Math calculations
a) Matrix multiplication
This is one of basics matrix operation. In this case we will use vector (2 row array) and 2 x 2 matrix
(or array, as you want). In result we get an vector (2 row array).
matrixMultiply ( vector , matrix ) {
resultVector = { 0 , 0 }
resultVector[0] = vector[0] * matrix[0][0] + vector[1] * matrix[1][0]
resultVector[1] = vector[0] * matrix[0][1] + vector[1] * matrix[1][1]
return resultVector
}
b) Creating rotation matrix
Also something from math: definition of rotation matrix in our 2- dimensional plane:
 cos( ) sin(  ) 

 , where α is the angle of rotation.
  sin(  ) cos( ) 
createRotationMatrix( angle ){
rotationMatrix = {{ 0 , 0 } , { 0 , 0 }}
rotationMatrix[0][0] = cos(angle)
rotationMatrix[1][1] = rotationMatrix[0][0]
rotationMatrix[0][1] = sin(angle)
rotationMatrix[1][0] = - rotationMatrix[0][1]
return rotationMatrix
}
3. Connections between coordinate systems
All coordinate systems can be displayed on 2-dimension Cartesian plane. Square plane has the same
coordinates, so we don’t have to make any other calculations to this place.
Another thing is with zig-zag coordinates.
If we say that point (0,0) is in zig-zag coordinates (0,0) and first up is to the right we can make a
formula (tested): x2  x1 
1
y 3
mod( y1 ,2)
, y2  1
. Mod is a math modulo function1.
2
2
http://en.wikipedia.org/wiki/Modulo_operation
4
a) Cartesian to zig-zag coordinates
Then we can make a function (vector to vector):
squareToZigzag( squareVector ) {
zigzagVector = { 0 , 0 }
zigzagVector[0] = squareVector[0] + mod(squareVector[1] , 2.0) / 2.0
zigzagVector[1] = squareVector[1] * sqrt(3.0) / 2.0
return zigzagVector
}
b) Zig-zag to Cartesian coordinates
Also it is useful to know backwards formula:
zigzagToSquare( zigzagVector ) {
squareVector = { 0 , 0 }
squareVector[0] = zigzagVector[0]mod(2.0 * zigzagVector[1] / sqrt(3.0) , 2.0) / 2.0
squareVector[1] = zigzagVector[1] * 2.0 / sqrt (3.0)
return squareVector
}
c) Rotate a point or vector in Cartesian plane
At first we have to remember that our plane is descrete. It means that we can’t have point with
coordinate (0.3, 1.8). The nearest point is (0, 2). So if we rotate point or vector we have to round the
result to the nearest vertex. Another thing is calculating sin and cosine functions. We can calculate it
every time or calculate it before rotations and then use values in correct place. That will make
calculations faster. Here I will calculate the rotation for every point (easier to understand what is doing
here).
rotateOneVectorCartesian( cartesianVector , angle ){
rotationMatrix = createRotationMatrix(angle)
rotatedVector = matrixMultiply(cartesianVector,rotationMatrix)
//round floating-point value to integer value
rotatedVector[0] = round(rotatedVector[0])
rotatedVector[1] = round(rotatedVector[1])
return rotatedVector
}
5
d) Rotation of vector on zig-zag plane.
Here rounding is a bit more complex. One way (I’ve discovered) is to rotate the values of vector in
Cartesian dimensions (ex.: (1/2, √3/2)), then convert the dimensions into square-shaped dimensions,
round the values there, and convert back into zig-zag plane:
rotateOneVectorZigzag( zigzagVector , angle ){
rotationMatrix = createRotationMatrix(angle)
rotatedVector = matrixMultiply(cartesianVector,rotationMatrix)
cartesianVector = zigzagToSquare(rotatedVector)
cartesianVector[0] = round(cartesianVector[0])
cartesianVector[1] = round(cartesianVector[1])
rotatedVector = squareToZigzag(cartesianVector)
return rotatedVector
}
This formula can work with vector or point- the same calculations are in both cases.
6
4. Testing the results in shapes
Using Wolfram Mathematica 10.0 I’ve tested the formula in 2 shapes: triangle and square. Both cases
divided into two possibilities: only vertices of shapes and all points inside the shape. I’ve tested all the
angles for rotations: 30, 45, 60, 90, 120 and 180 degrees. Some of the results are down here:
Square shape, 120 degree:
Triangle shape, 90 degree:
5. Conclusion
The formula works property, but it has some small problem with angles that aren’t the multiplication
of 60 degrees. Interpolation is needed to make a stable feature of rotating any part of map in
Widelands.
Download