Функция php для переноса матрицы координат (x, y) вокруг точки вращения

У меня есть матрица элементов [ n x m ], где центр не может быть на координате (x, y) 0,0:

<?php
$matrix_yx = array(
     21 => array(10,11,12),
     22 => array(10,11,12),
     23 => array(10,11,12),
     24 => array(10,11,12)
);
$origin_yx = array(23,11);
?>

Я пытаюсь написать функцию для передачи в качестве ввода

  1. матрица
  2. координата поворота, которая будет использоваться в качестве точки опоры
  3. в конечном итоге вращение в градусах (это может быть только 90, 180 или 270)

Итак, рассматривая представление элементов матрицы (x, y):

y
^
| 10,24   11,24   12,24
| 10,23  >11,23<  12,23
| 10,22   11,22   12,22
| 10,21   11,21   12,21
+-----------------------> x

Мне нужно повернуть его на 90 градусов по часовой стрелке вокруг точки (11,23), в основном получая новую матрицу, подобную этой:

y
^
| 09,24   10,24   11,24   12,24
| 09,23   10,23  >11,23<  12,23
| 09,22   10,22   11,22   12,23
+-------------------------------> x

Я немного смущен, как если бы начало координат (x, y) было бы по координате (0,0), тогда это было бы просто как

(x,y) = (11,23)

перевести 90' вокруг (0) я бы получил

function Rotate($matrix) {
    list($x,y) = array($y,-$x);
    (x,y) = (23,-11);
}

но тогда что я должен учитывать, если я хочу передать другую опорную координату?

function Rotate($matrix, $pivot_x, $pivot_y) {
    //-- (...)
}

В случае, если мне придется транспонировать матрицу 180 или 270 градусов (вместо 90), тогда функция будет вызываться 2 или 3 раза... если, конечно, не будет более разумного подхода (который, я уверен, существует, но - на данный момент - не в моем уме).


person Stefano Radaelli    schedule 12.11.2015    source источник
comment
вам не нужно беспокоиться о своей опорной точке, переведите свою матрицу в опорную точку (0,0), это означает, что если у вас есть точка (x, y) = (11,23) и ваша опорная точка (x_p, y_p) = (1,1 ) ваша точка в (0,0) = (x-x_p, y-y_p) и может применить вашу функцию. А что касается вызываемой вами функции, помните, что вы находитесь в круге, разделите свою оценку на 90 и выполните мод 4, например 450:90 = 5, 5 мод 4 = 1 => 1 раз вам нужно вызвать вашу функцию и максимальное время = 3, 3 по модулю 4 = 3   -  person Laurentiu    schedule 12.11.2015


Ответы (1)


Следуя предложению @Laurentiu, это функция, которая должна ответить на мой вопрос:

$matrix = array(
     21 => array(10,11,12),
     22 => array(10,11,12),
     23 => array(10,11,12),
     24 => array(10,11,12)
);

function Rotate($matrix, $pivot_x, $pivot_y) {
        $output = array();
        krsort($matrix);
        while (list($y) = each($matrix)) {
                reset($matrix[$y]);
                while (list(,$x) = each($matrix[$y])) {
                        list($offset_x,$offset_y) = array(
                                ($pivot_y - $y),
                                -1 * ($pivot_x - $x)
                        );
                        list($newx,$newy) = array($pivot_x - $offset_x , $pivot_y - $offset_y);

                        $output[$newy][] = $newx;
                }
        }
        return($output);
}

Итак, начиная с такой матрицы...

10,24    11,24    12,24
10,23   >11,23<   12,23
10,22    11,22    12,22
10,21    11,21    12,21

Если я повернусь на оси (x, y) (11,23)..

$output  = Rotate($matrix, 11, 23);

9,24    10,24    11,24    12,24
9,23    10,23   >11,23<   12,23
9,22    10,22    11,22    12,22

Принимая во внимание, что если я вращаюсь на оси (0,0):

$output = Rotate($matrix, 0, 0);

21,-10    22,-10    23,-10    24,-10
21,-11    22,-11    23,-11    24,-11
21,-12    22,-12    23,-12    24,-12

Очевидно, что любое исправление ошибок более чем ценится!

person Stefano Radaelli    schedule 13.11.2015