C# 翻译后形状不';t绕着它旋转';起源

C# 翻译后形状不';t绕着它旋转';起源,c#,opengl,graphics,3d,C#,Opengl,Graphics,3d,我正在开发一个类似OpenGL的软件。所以我有模型,视图和投影矩阵 缩放和旋转在不平移的情况下工作良好。但当我将平移应用于对象并再次尝试旋转它时,它会围绕世界原点旋转 我知道转换操作的顺序应该是:缩放->旋转->平移。但我不明白如何只用一个矩阵(模型)就可以做到这一点 那么,我怎样才能用正确的方式来做呢?我应该使用3个矩阵吗 我在矩阵方面的工作: for (int i = 0; i < vertices.Count; ++i) { f

我正在开发一个类似OpenGL的软件。所以我有模型,视图和投影矩阵

缩放和旋转在不平移的情况下工作良好。但当我将平移应用于对象并再次尝试旋转它时,它会围绕世界原点旋转

我知道转换操作的顺序应该是:缩放->旋转->平移。但我不明白如何只用一个矩阵(模型)就可以做到这一点

那么,我怎样才能用正确的方式来做呢?我应该使用3个矩阵吗

我在矩阵方面的工作:

        for (int i = 0; i < vertices.Count; ++i)
        {
            float[,] vertexCoords = { { vertices[i].SX }, { vertices[i].SY }, { vertices[i].SZ }, { vertices[i].SW } };

            var modelViewMatrix = MatrixMultiplier.MultiplyMatrix(camera.ViewMatrix, shape.ModelMatrix);
            var eyeCoordinates = MatrixMultiplier.MultiplyMatrix(modelViewMatrix, vertexCoords);
            var clipCoordinates = MatrixMultiplier.MultiplyMatrix(camera.ProjectionMatrix, eyeCoordinates);


            var ndc = new float[,] {
                { clipCoordinates[0, 0] / clipCoordinates[3, 0] },
                { clipCoordinates[1, 0] / clipCoordinates[3, 0] },
                { clipCoordinates[2, 0] / clipCoordinates[3, 0] },
                { clipCoordinates[3, 0]}
            };

            var windowCoordinates = new float[,] { 
                { 640 / 2 * ndc[0, 0] + (640 / 2) },
                { 360 / 2 * ndc[1, 0] + (360 / 2) },
                { (50 - (-50)) / 2 * ndc[2, 0] + (50 + (-50)) / 2 },
                { ndc[3, 0]}
            };

            SetNewCoordinatesToPoint(vertices[i], windowCoordinates);             
        }
矩阵乘法器:

public static class MatrixMultiplier
{
    public static float[,] MultiplyMatrix(float[,] a, float[,] b)
    {
        float[,] c = null;

        if (a.GetLength(1) == b.GetLength(0))
        {
            c = new float[a.GetLength(0), b.GetLength(1)];
            for (int i = 0; i < c.GetLength(0); i++)
            {
                for (int j = 0; j < c.GetLength(1); j++)
                {
                    c[i, j] = 0;
                    for (int k = 0; k < a.GetLength(1); k++) // OR k<b.GetLength(0)
                        c[i, j] = c[i, j] + a[i, k] * b[k, j];
                }
            }
        }
        else
        {
            Console.WriteLine("\n Number of columns in First Matrix should be equal to Number of rows in Second Matrix.");
            Console.WriteLine("\n Please re-enter correct dimensions.");
            throw new ArithmeticException("Number of columns in First Matrix should be equal to Number of rows in Second Matrix");
        }

        return c;
    }
}
公共静态类矩阵乘法器
{
公共静态浮点[,]乘法矩阵(浮点[,]a,浮点[,]b)
{
浮动[,]c=null;
如果(a.GetLength(1)==b.GetLength(0))
{
c=新浮点[a.GetLength(0),b.GetLength(1)];
for(int i=0;i对于(intk=0;k
shape.ModelMatrix = MatrixMultiplier.MultiplyMatrix(rotateZ, shape.ModelMatrix);
根据我的RotateZ方法,形状将围绕世界原点旋转。如果我将代码更改为:

shape.ModelMatrix = MatrixMultiplier.MultiplyMatrix(shape.ModelMatrix, rotateZ);

形状将围绕它的中心旋转。

根据Nico Schertler的原著,这一切都取决于矩阵的乘法顺序

shape.ModelMatrix = MatrixMultiplier.MultiplyMatrix(rotateZ, shape.ModelMatrix);
根据我的RotateZ方法,形状将围绕世界原点旋转。如果我将代码更改为:

shape.ModelMatrix = MatrixMultiplier.MultiplyMatrix(shape.ModelMatrix, rotateZ);
形状将围绕其中心旋转

但当我将平移应用于对象并再次尝试旋转它时,它会围绕世界原点旋转

是的,这就是它的工作原理。你必须先旋转对象,然后将其平移到所需的位置。几何变换是不可交换的,即操作顺序很重要

但当我将平移应用于对象并再次尝试旋转它时,它会围绕世界原点旋转


是的,这就是它的工作原理。你必须先旋转对象,然后将其转换到所需的位置。几何变换不是可交换的,即操作顺序很重要。

这都是顺序问题。看。@NicoSchertler哇,这真的帮了我很大的忙。现在形状围绕其原点旋转。谢谢!请随意写一个a回答这个问题或者把它全部删除。这都是程序问题。看。@NicoSchertler哇,这真的帮了我很大的忙。现在形状围绕它的原点旋转。谢谢!请随意写一个关于这个问题的答案或者把它全部删除。