Преобразование координаты из одного пространства в другое - PullRequest
1 голос
/ 26 января 2012

У меня, похоже, здесь что-то вроде математического сбоя ... Мне нужно преобразовать точку (x, y) из одного координатного пространства в другое - не в смысле полярности в декартову или что-то в этом роде. .. просто от одного, связанного с другим. т.е. для определенного (x, y), который попадает в прямоугольник с нижним левым (-100, -100) и верхним правым (100,100), мне нужно выяснить, где эта точка будет в прямоугольнике с нижним левым (0 , 0) и верхний правый (500, 500).

Я чувствую, что это просто математика, но у меня чертовски много времени, чтобы все сделать правильно ...

Это для маленькой компьютерной программы, написанной на Java. По существу, есть окно клипа, которое изменяется, и это окно клипа должно заполнять все окно просмотра. Начальные значения для клипа и вида задаются вышеуказанными прямоугольниками в указанном порядке. Однако клип может измениться, например, на прямоугольник с нижним левым (-80, -65) и верхним правым (75, 65). Затем мне нужно будет преобразовать точку, которая попадает в этот прямоугольник, в точку, которая попадает в окно просмотра (нижний левый (0,0), верхний правый (500, 500))

Вот что у меня есть для этого прямо сейчас:

public int normalizeX(float x) {
    float clipWidth = clipRight - clipLeft;
    int viewWidth = viewRight - viewLeft;
    x += 100; //Get x into range [0, 200] instead of [-100, 100]
    //First convert x to value within clip width, then "scale" to viewport width
    return (int)(((clipWidth*x)/200) * (viewWidth/clipWidth));
}

public int normalizeY(float y) {
    float clipHeight = clipTop - clipBottom;
    int viewHeight = viewTop - viewBottom;
    y += 100; //Get y into range [0, 200] instead of [-100, 100]
    //First convert y to value within clip height, then "scale" to viewport height
    return (int)(((clipHeight*y)/200) * (viewHeight/clipHeight));
}

Спасибо за любую помощь!

Ответы [ 4 ]

4 голосов
/ 26 января 2012

Предполагая, что ваши старые границы xLoOld и xHiOld (-80 и 75 соответственно в вашем примере) и ваши новые границы xLoNew и xHiNew (0 и 500 соответственно в вашем примере) тогда вы можете нормализовать ваш xOld к вашей новой системе координат следующим образом:

xNew = (xOld-xLoOld) / (xHiOld-xLoOld) * (xHiNew-xLoNew) + xLoNew

То же самое для тебя.

2 голосов
/ 26 января 2012

Простой, как ад: вы хотите преобразование, которое отображает от -100 до 0 и от 100 до 500. Или ставьте вслепую, которое отображает диапазон [-100, 100] в диапазон [0, 500]:

[-100, 100] ----> [0, 500]

Первый шаг - преобразование диапазона [-100, 100] в [0, 200]:

x ----> x + 100

Следующим шагом является преобразование диапазона [0, 200] в [0, 500]

x ----> x * 500 / 200 = 2.5 * x

В порядке , ваше преобразование будет иметь вид

x ----> 2.5 * (x + 100) 

и аналогично для y:

y ----> 2.5 * (y + 100).

Надеюсь, это прояснит ситуацию, и вы сможете повторно использовать логику в более сложных случаях.

2 голосов
/ 26 января 2012

Нечто подобное может вам помочь.

    public static float scale(
           float x,
           float old_min, float old_max,
           float new_min, float new_max)
    {
        float old_range = old_max - old_min;
        float new_range = new_max - new_min;
        return new_min + (x - old_min) * new_range / old_range;
    }

Вам нужно будет масштабировать ваши координаты в обоих измерениях. Я пропустил другие вычисления, такие как приведение к int и т. Д.

Я также рекомендую создавать подходящие типы, такие как Region или Rectangle, чтобы упростить ваш код, по крайней мере, уменьшив количество аргументов этой функции.

0 голосов
/ 26 января 2012

Отличный и общий способ сделать это с помощью аффинного преобразования. У вас будет матрица 2 x 2 (назовите ее A), которая характеризует «растяжение» исходного поля ко второму полю, и матрица 2 x 1 (назовите ее b), характеризующая смещение.

Затем, с x как вашим (2 x 1) входом и y как вашим (2 x 1) выходом, это просто y = Ax + b.

Техника также позволяет вам делать намного больше (например, ротации), но, вероятно, это не важно для вашего приложения.

http://en.wikipedia.org/wiki/Affine_transformation

...