Матч 21, Фиксированная точка (FixedPoint)

 

Карта Байтляндии была создана следующими тремя трансформациями:

1. Масштабирование с коэффициентом scale. Каждая точка плоскости (x, y) перешла в точку (scale*x, scale*y).

2. Сдвиг на вектор translate. Каждая точка плоскости (x, y) перешла в точку (x + translate[0], y + translate[1]).

3. Вращение на угол rotate (в радианах). Каждая точка плоскости (x, y) перешла в точку (x * cos(rotate) – y*sin(rotate), y * cos(rotate) + x*sin(rotate)).

Фиксированной называется точка, удовлетворяющая следующим условиям:

(scale * cos(rotate) – 1) * xscale * sin(rotate) * y =

                                                                       -translate[0] * cos(rotate) + translate[1] * sin(rotate)

scale * sin(rotate) * x + (scale * cos(rotate) – 1) * y =

                                                                       -translate[0] * sin(rotate) – translate[1] * cos(rotate)

Решите систему и верните координаты фиксированной точки в виде вектора из двух компонент (x, y). Система всегда имеет единственное решение.

 

Класс: FixedPoint

Метод: vector<double> find(double scale,

                          vector<double> translate,double rotate)

Ограничения: address1 и address2  содержат от 0 до 50 символов ‘a’ – ‘z’, ‘A’ – ‘Z’, ‘0’ – ‘9’.

 

Вход. Коэффициент масштабирования scale, вектор параллельного переноса translate и угол поворота rotate.

 

Выход. Координаты фиксированной точки в виде вектора (x, y).

 

Пример входа

scale

translate

rotate

0.5

{1, 0}

1.5707963267948966

0.5

{2, 0}

0

0.5

{1, 2}

0.785398163397

 

Пример выхода

{-0.4, 0.8}

{4.0, 0.0}

{-2.223469992542095, 2.065452845425795}

 

 

РЕШЕНИЕ

алгебра, система линейных уравнений, метод Крамера

 

Обозначим:

A = (scale * cos(rotate) – 1);

B = scale * sin(rotate);

C = -translate[0] * cos(rotate) + translate[1] * sin(rotate);

D = -translate[0] * sin(rotate) - translate[1] * cos(rotate);

Остается решить методом Крамера систему линейных уравнений в действительных числах:

По условию задачи она всегда имеет единственное решение.

 

ПРОГРАММА

 

#include <cstdio>

#include <vector>

#include <cmath>

using namespace std;

 

void kramer(double a1,double b1, double c1, double a2,double b2, double c2,

            double *x, double *y)

{

  double d = a1 * b2 - a2 * b1;

  double dx = c1 * b2 - c2 * b1;

  double dy = a1 * c2 - a2 * c1;

  *x = dx / d; *y = dy / d;

}

 

class FixedPoint

{

public:

  vector<double> find(double scale, vector<double> translate, double rotate)

  {

    vector<double> res(2);

    double A = (scale * cos(rotate) - 1);

    double B = scale * sin(rotate);

    double C = -translate[0] * cos(rotate) + translate[1] * sin(rotate);

    double D = -translate[0] * sin(rotate) - translate[1] * cos(rotate);

    kramer(A,-B,C,B,A,D,&res[0],&res[1]);

    return res;

  }

};