У меня есть 2D геометрия. Я хочу взять ограничивающий прямоугольник вокруг моей геометрии, а затем сделать ее уменьшенную версию где-нибудь еще на плоскости. Вот более или менее код, который я должен сделать масштабирование и перевод:
// source and dest are arbitrary rectangles.
float scaleX = dest.width / source.width;
float scaleY = dest.height / source.height;
float translateX = dest.x - source.x;
float translateY = dest.y - source.y;
glScalef(scaleX, scaleY, 0.0);
glTranslatef(translateX, translateY, 0.0);
// Draw geometry in question with its normal verts.
Это работает точно так, как ожидается для данного измерения, когда источник dest равен 0. Но если источник, скажем, x, отличен от нуля, результат по-прежнему корректно масштабируется, но выглядит (?), Что переводится во что-то близкое к нулю в любом случае на этой оси - оказывается, это не совсем то же самое, что если бы dest.x были равны нулю.
Может ли кто-то указать на очевидное, что мне не хватает?
Спасибо!
ЗАКЛЮЧИТЕЛЬНОЕ ОБНОВЛЕНИЕ Согласно ответам Бахбара и Маркуса ниже, я провел еще несколько экспериментов и решил это. Комментарий Адама Боуэна был подсказкой. Мне не хватало двух важных фактов:
- Мне нужно было масштабировать вокруг центра геометрии, о которой я заботился.
- Мне нужно было применить преобразования в порядке, обратном интуиции (для меня).
Первый вид очевиден в ретроспективе. Но для последнего, для других хороших программистов / плохих математиков, таких как я: Оказывается, моя интуиция работала в том, что Красная книга называет "Великой фиксированной системой координат", в которой существует абсолютная плоскость, и ваша геометрия перемещается на этой плоскости, используя преобразования. Это нормально, но учитывая природу математики, лежащей в основе объединения нескольких преобразований в одну матрицу, это противоположно тому, как все работает на самом деле (подробности см. В ответах ниже или в Красной книге). По сути, преобразования «применяются» в «обратном порядке» к тому, как они появляются в коде. Вот окончательное рабочее решение:
// source and dest are arbitrary rectangles.
float scaleX = dest.width / source.width;
float scaleY = dest.height / source.height;
Point sourceCenter = centerPointOfRect(source);
Point destCenter = centerPointOfRect(dest);
glTranslatef(destCenter.x, destCenter.y, 0.0);
glScalef(scaleX, scaleY, 0.0);
glTranslatef(sourceCenter.x * -1.0, sourceCenter.y * -1.0, 0.0);
// Draw geometry in question with its normal verts.