非均匀缩放的 3x3 矩阵旋转
3x3 Matrix Rotation with non uniform scaling
我在处理矩阵变换时遇到了一些问题。对于测试,我有一个 10 个正方形链,每个正方形都是前一个正方形的父级。然后我可以对每个正方形应用旋转并得到这个结果...
这是正确的,正是我想要的。现在这是同样的事情,第 8 个正方形被统一缩放。
再一次,这是完美的。 children 继承了它们的 parents 转换。现在,当我将 non-uniform 比例应用于第 8 个方块时,问题就来了。
这张照片是一个微妙的例子,但我希望你们能理解。最后一个方块没有碰到前一个方块的角。它也可能不明显,但最后两个方块实际上不是正确的尺寸。如果我应用更多旋转,这将变得更加明显。
这是我构造矩阵的代码。
maths::mat3 DisplayObject::getGlobalTransform() {
maths::mat3 output(1.0f);
output *= maths::mat3::Rotate(rotation);
output *= maths::mat3::Scale(scale);
output *= maths::mat3::Translate(position);
if(parent != nullptr){
output *= parent->getGlobalTransform();
}
return output;
}
任何帮助或想法将不胜感激!
编辑:这是我应用旋转和缩放的方式。
mat3 mat3::Rotate(float angle)
{
mat3 result(1.0f);
float r = toRadians(angle);
result.elements[0] = cos(r);
result.elements[1] = -sin(r);
result.elements[3] = sin(r);
result.elements[4] = cos(r);
return result;
}
mat3 mat3::Scale(const vec2& scale)
{
mat3 result(1.0f);
result.elements[0] = scale.x;
result.elements[4] = scale.y;
return result;
}
...这就是我如何再次将它们取出...
float mat3::GetRotation() const
{
return atan2(elements[1], elements[0]);
}
vec2 mat3::GetScale() const
{
return vec2(rows[0].Magnitude(), rows[1].Magnitude());
}
我试过这个:
#include<GL/glut.h>
#include<math.h>
#define PI 3.14159265
#define M 50.0f
void display() {
glClear(GL_COLOR_BUFFER_BIT);
for (int i = 0; i < M; i++)
{
glTranslatef(1, 1, 0);
glRotatef(25.0f, 0, 0, 1);
glScalef(1.2, 1, 0);
glColor3f(1.0f-i/M, i/M, 0.0f);
glBegin(GL_QUADS);
glVertex2f(0.0, 0.0);
glVertex2f(0.0, 1.0);
glVertex2f(1.0, 1.0);
glVertex2f(1.0, 0.0);
glEnd();
}
glFlush();
}
void myinit() {
glClearColor(1.0, 1.0, 1.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 250.0, 0.0, 250.0);
glTranslatef(125, 125, 0);
}
void main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(501, 501);
glutInitWindowPosition(0, 0);
glutCreateWindow("59531834");
glutDisplayFunc(display);
myinit();
glutMainLoop();
}
它给出了预期的结果:
正确的矩阵顺序接缝为 PTRS:父级、平移、旋转、缩放。
编辑:PTSR 适用于。
所以试试这个:
maths::mat3 DisplayObject::getGlobalTransform() {
maths::mat3 output(1.0f);
if(parent != nullptr){
output *= parent->getGlobalTransform();
}
output *= maths::mat3::Translate(position);
output *= maths::mat3::Scale(scale);
output *= maths::mat3::Rotate(rotation);
return output;
}
我在处理矩阵变换时遇到了一些问题。对于测试,我有一个 10 个正方形链,每个正方形都是前一个正方形的父级。然后我可以对每个正方形应用旋转并得到这个结果...
这是正确的,正是我想要的。现在这是同样的事情,第 8 个正方形被统一缩放。
再一次,这是完美的。 children 继承了它们的 parents 转换。现在,当我将 non-uniform 比例应用于第 8 个方块时,问题就来了。
这张照片是一个微妙的例子,但我希望你们能理解。最后一个方块没有碰到前一个方块的角。它也可能不明显,但最后两个方块实际上不是正确的尺寸。如果我应用更多旋转,这将变得更加明显。
这是我构造矩阵的代码。
maths::mat3 DisplayObject::getGlobalTransform() {
maths::mat3 output(1.0f);
output *= maths::mat3::Rotate(rotation);
output *= maths::mat3::Scale(scale);
output *= maths::mat3::Translate(position);
if(parent != nullptr){
output *= parent->getGlobalTransform();
}
return output;
}
任何帮助或想法将不胜感激!
编辑:这是我应用旋转和缩放的方式。
mat3 mat3::Rotate(float angle)
{
mat3 result(1.0f);
float r = toRadians(angle);
result.elements[0] = cos(r);
result.elements[1] = -sin(r);
result.elements[3] = sin(r);
result.elements[4] = cos(r);
return result;
}
mat3 mat3::Scale(const vec2& scale)
{
mat3 result(1.0f);
result.elements[0] = scale.x;
result.elements[4] = scale.y;
return result;
}
...这就是我如何再次将它们取出...
float mat3::GetRotation() const
{
return atan2(elements[1], elements[0]);
}
vec2 mat3::GetScale() const
{
return vec2(rows[0].Magnitude(), rows[1].Magnitude());
}
我试过这个:
#include<GL/glut.h>
#include<math.h>
#define PI 3.14159265
#define M 50.0f
void display() {
glClear(GL_COLOR_BUFFER_BIT);
for (int i = 0; i < M; i++)
{
glTranslatef(1, 1, 0);
glRotatef(25.0f, 0, 0, 1);
glScalef(1.2, 1, 0);
glColor3f(1.0f-i/M, i/M, 0.0f);
glBegin(GL_QUADS);
glVertex2f(0.0, 0.0);
glVertex2f(0.0, 1.0);
glVertex2f(1.0, 1.0);
glVertex2f(1.0, 0.0);
glEnd();
}
glFlush();
}
void myinit() {
glClearColor(1.0, 1.0, 1.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 250.0, 0.0, 250.0);
glTranslatef(125, 125, 0);
}
void main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(501, 501);
glutInitWindowPosition(0, 0);
glutCreateWindow("59531834");
glutDisplayFunc(display);
myinit();
glutMainLoop();
}
它给出了预期的结果:
正确的矩阵顺序接缝为 PTRS:父级、平移、旋转、缩放。
编辑:PTSR 适用于。
所以试试这个:
maths::mat3 DisplayObject::getGlobalTransform() {
maths::mat3 output(1.0f);
if(parent != nullptr){
output *= parent->getGlobalTransform();
}
output *= maths::mat3::Translate(position);
output *= maths::mat3::Scale(scale);
output *= maths::mat3::Rotate(rotation);
return output;
}