#include <iostream>
#include <math.h>
using std::cout;
using std::endl;
struct Vector2D
{
float x, y;
Vector2D() : x(0), y(0) {}
Vector2D(float x, float y) : x(x), y(y) {}
Vector2D operator -(const Vector2D& v) const
{
return (Vector2D(x - v.x, y - v.y));
}
Vector2D operator -(void) const
{
return (Vector2D(-x, -y));
}
Vector2D operator /(float f) const
{
return (Vector2D(x / f, y / f));
}
};
// constants
const float chunkSize = 512;
const Vector2D minimapCenter(627, 135);
float distance(const Vector2D& a, const Vector2D& b)
{
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
void rotate(Vector2D& p, float theta)
{
p.x = cos(theta) * p.x - sin(theta) * p.y;
p.y = sin(theta) * p.x + cos(theta) * p.y;
}
float getTheta(const Vector2D& v)
{
return atan2(v.y,v.x) - atan2(-1 , 0); // b(0, -1)
}
Vector2D getRelativePosition(const Vector2D& vert0, const Vector2D& vert1)
{
Vector2D p = vert0 - minimapCenter;
rotate(p, getTheta(vert0 - vert1));
return -p / (distance(vert0, vert1) / chunkSize);
}
int main()
{
// input
Vector2D vert0(309.88147, -144.74777); // top left
Vector2D vert1(305.99057, 389.2381); // bottom left
Vector2D p = getRelativePosition(vert0, vert1);
cout << "Relative position = (" << p.x << ", " << p.y << ")" << endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bWF0aC5oPiAKCnVzaW5nIHN0ZDo6Y291dDsKdXNpbmcgc3RkOjplbmRsOwoKc3RydWN0IFZlY3RvcjJECnsKICAgIGZsb2F0IHgsIHk7CiAgICBWZWN0b3IyRCgpIDogeCgwKSwgeSgwKSB7fQogICAgVmVjdG9yMkQoZmxvYXQgeCwgZmxvYXQgeSkgOiB4KHgpLCB5KHkpIHt9CiAgICBWZWN0b3IyRCBvcGVyYXRvciAtKGNvbnN0IFZlY3RvcjJEJiB2KSBjb25zdAogICAgewogICAgICAgIHJldHVybiAoVmVjdG9yMkQoeCAtIHYueCwgeSAtIHYueSkpOwogICAgfQogICAgVmVjdG9yMkQgb3BlcmF0b3IgLSh2b2lkKSBjb25zdAogICAgewogICAgICAgIHJldHVybiAoVmVjdG9yMkQoLXgsIC15KSk7CiAgICB9CiAgICBWZWN0b3IyRCBvcGVyYXRvciAvKGZsb2F0IGYpIGNvbnN0CiAgICB7CiAgICAJcmV0dXJuIChWZWN0b3IyRCh4IC8gZiwgeSAvIGYpKTsKICAgIH0KfTsKCi8vIGNvbnN0YW50cwpjb25zdCBmbG9hdCBjaHVua1NpemUgPSA1MTI7CmNvbnN0IFZlY3RvcjJEIG1pbmltYXBDZW50ZXIoNjI3LCAxMzUpOwoKZmxvYXQgZGlzdGFuY2UoY29uc3QgVmVjdG9yMkQmIGEsIGNvbnN0IFZlY3RvcjJEJiBiKQp7CiAgICByZXR1cm4gc3FydCgoYS54IC0gYi54KSAqIChhLnggLSBiLngpICsgKGEueSAtIGIueSkgKiAoYS55IC0gYi55KSk7Cn0KCnZvaWQgcm90YXRlKFZlY3RvcjJEJiBwLCBmbG9hdCB0aGV0YSkKewogICAgcC54ID0gY29zKHRoZXRhKSAqIHAueCAtIHNpbih0aGV0YSkgKiBwLnk7CiAgICBwLnkgPSBzaW4odGhldGEpICogcC54ICsgY29zKHRoZXRhKSAqIHAueTsKfQoKZmxvYXQgZ2V0VGhldGEoY29uc3QgVmVjdG9yMkQmIHYpCnsKICAgIHJldHVybiBhdGFuMih2Lnksdi54KSAtIGF0YW4yKC0xICwgMCk7IC8vIGIoMCwgLTEpCn0KClZlY3RvcjJEIGdldFJlbGF0aXZlUG9zaXRpb24oY29uc3QgVmVjdG9yMkQmIHZlcnQwLCBjb25zdCBWZWN0b3IyRCYgdmVydDEpCnsKICAgIFZlY3RvcjJEIHAgPSB2ZXJ0MCAtIG1pbmltYXBDZW50ZXI7CiAgICByb3RhdGUocCwgZ2V0VGhldGEodmVydDAgLSB2ZXJ0MSkpOwogICAgcmV0dXJuIC1wIC8gKGRpc3RhbmNlKHZlcnQwLCB2ZXJ0MSkgLyBjaHVua1NpemUpOwp9CgppbnQgbWFpbigpCnsKICAgIC8vIGlucHV0CiAgICBWZWN0b3IyRCB2ZXJ0MCgzMDkuODgxNDcsIC0xNDQuNzQ3NzcpOyAvLyB0b3AgbGVmdAogICAgVmVjdG9yMkQgdmVydDEoMzA1Ljk5MDU3LCAzODkuMjM4MSk7IC8vIGJvdHRvbSBsZWZ0CiAgICAKICAgIFZlY3RvcjJEIHAgPSBnZXRSZWxhdGl2ZVBvc2l0aW9uKHZlcnQwLCB2ZXJ0MSk7CiAgICBjb3V0IDw8ICJSZWxhdGl2ZSBwb3NpdGlvbiA9ICgiIDw8IHAueCA8PCAiLCAiIDw8IHAueSA8PCAiKSIgPDwgZW5kbDsKICAgIHJldHVybiAwOwp9Cg==