After translating shape doesn't rotate around it's origin










0














I am developing an analogue of OpenGL. So I have model, view and projection matrices.



Scaling and rotating work pefectly without translating. But when I apply translating to object and trying to rotate it again - it rotates around world origin.



I know that transformation operations should come in next order: scaling -> rotating -> translating. But I don't understand how to do it with only one matrix (model).



So, how can I do it in the right way? Should I use 3 matrices insted?



My work with matrices:



 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);



Rotation algorithm example:



private void RotateZ(MCommonPrimitive shape, double angle)

double rads = angle * Math.PI / 180.0;

float[,] rotateZ =
(float)Math.Cos(rads), -(float)Math.Sin(rads), 0, 0 ,
(float)Math.Sin(rads), (float)Math.Cos(rads), 0, 0 ,
0, 0, 1, 0 ,
0, 0, 0, 1
;

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



MatrixMultiplier:



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;











share|improve this question

















  • 2




    It's all a matter of order. See this answer.
    – Nico Schertler
    Nov 12 '18 at 18:20










  • @NicoSchertler wow, this really helped me a lot. Now shape rotates around it's origin. Thank you!
    – Dmitry
    Nov 12 '18 at 18:32










  • Feel free to write an answer to this question or delete it altogether then.
    – Nico Schertler
    Nov 12 '18 at 19:13















0














I am developing an analogue of OpenGL. So I have model, view and projection matrices.



Scaling and rotating work pefectly without translating. But when I apply translating to object and trying to rotate it again - it rotates around world origin.



I know that transformation operations should come in next order: scaling -> rotating -> translating. But I don't understand how to do it with only one matrix (model).



So, how can I do it in the right way? Should I use 3 matrices insted?



My work with matrices:



 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);



Rotation algorithm example:



private void RotateZ(MCommonPrimitive shape, double angle)

double rads = angle * Math.PI / 180.0;

float[,] rotateZ =
(float)Math.Cos(rads), -(float)Math.Sin(rads), 0, 0 ,
(float)Math.Sin(rads), (float)Math.Cos(rads), 0, 0 ,
0, 0, 1, 0 ,
0, 0, 0, 1
;

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



MatrixMultiplier:



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;











share|improve this question

















  • 2




    It's all a matter of order. See this answer.
    – Nico Schertler
    Nov 12 '18 at 18:20










  • @NicoSchertler wow, this really helped me a lot. Now shape rotates around it's origin. Thank you!
    – Dmitry
    Nov 12 '18 at 18:32










  • Feel free to write an answer to this question or delete it altogether then.
    – Nico Schertler
    Nov 12 '18 at 19:13













0












0








0







I am developing an analogue of OpenGL. So I have model, view and projection matrices.



Scaling and rotating work pefectly without translating. But when I apply translating to object and trying to rotate it again - it rotates around world origin.



I know that transformation operations should come in next order: scaling -> rotating -> translating. But I don't understand how to do it with only one matrix (model).



So, how can I do it in the right way? Should I use 3 matrices insted?



My work with matrices:



 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);



Rotation algorithm example:



private void RotateZ(MCommonPrimitive shape, double angle)

double rads = angle * Math.PI / 180.0;

float[,] rotateZ =
(float)Math.Cos(rads), -(float)Math.Sin(rads), 0, 0 ,
(float)Math.Sin(rads), (float)Math.Cos(rads), 0, 0 ,
0, 0, 1, 0 ,
0, 0, 0, 1
;

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



MatrixMultiplier:



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;











share|improve this question













I am developing an analogue of OpenGL. So I have model, view and projection matrices.



Scaling and rotating work pefectly without translating. But when I apply translating to object and trying to rotate it again - it rotates around world origin.



I know that transformation operations should come in next order: scaling -> rotating -> translating. But I don't understand how to do it with only one matrix (model).



So, how can I do it in the right way? Should I use 3 matrices insted?



My work with matrices:



 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);



Rotation algorithm example:



private void RotateZ(MCommonPrimitive shape, double angle)

double rads = angle * Math.PI / 180.0;

float[,] rotateZ =
(float)Math.Cos(rads), -(float)Math.Sin(rads), 0, 0 ,
(float)Math.Sin(rads), (float)Math.Cos(rads), 0, 0 ,
0, 0, 1, 0 ,
0, 0, 0, 1
;

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



MatrixMultiplier:



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;








c# opengl graphics 3d






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 12 '18 at 18:15









Dmitry

183




183







  • 2




    It's all a matter of order. See this answer.
    – Nico Schertler
    Nov 12 '18 at 18:20










  • @NicoSchertler wow, this really helped me a lot. Now shape rotates around it's origin. Thank you!
    – Dmitry
    Nov 12 '18 at 18:32










  • Feel free to write an answer to this question or delete it altogether then.
    – Nico Schertler
    Nov 12 '18 at 19:13












  • 2




    It's all a matter of order. See this answer.
    – Nico Schertler
    Nov 12 '18 at 18:20










  • @NicoSchertler wow, this really helped me a lot. Now shape rotates around it's origin. Thank you!
    – Dmitry
    Nov 12 '18 at 18:32










  • Feel free to write an answer to this question or delete it altogether then.
    – Nico Schertler
    Nov 12 '18 at 19:13







2




2




It's all a matter of order. See this answer.
– Nico Schertler
Nov 12 '18 at 18:20




It's all a matter of order. See this answer.
– Nico Schertler
Nov 12 '18 at 18:20












@NicoSchertler wow, this really helped me a lot. Now shape rotates around it's origin. Thank you!
– Dmitry
Nov 12 '18 at 18:32




@NicoSchertler wow, this really helped me a lot. Now shape rotates around it's origin. Thank you!
– Dmitry
Nov 12 '18 at 18:32












Feel free to write an answer to this question or delete it altogether then.
– Nico Schertler
Nov 12 '18 at 19:13




Feel free to write an answer to this question or delete it altogether then.
– Nico Schertler
Nov 12 '18 at 19:13












2 Answers
2






active

oldest

votes


















2















But when I apply translating to object and trying to rotate it again - it rotates around world origin.




Yes, that's how it works. You have to rotate the object first, then translate it to the desired position. Geometric transformations are not commutative, i.e. the order of operations matter.






share|improve this answer




























    0














    According to Nico Schertler's original answer it all depends on matrices multiplication order. So, for example, if I will use this code



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


    from my RotateZ method, shape will rotate around world origin. And, if I change my code to this:



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


    shape will rotate around it's center.






    share|improve this answer




















      Your Answer






      StackExchange.ifUsing("editor", function ()
      StackExchange.using("externalEditor", function ()
      StackExchange.using("snippets", function ()
      StackExchange.snippets.init();
      );
      );
      , "code-snippets");

      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "1"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













      draft saved

      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53267876%2fafter-translating-shape-doesnt-rotate-around-its-origin%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      2















      But when I apply translating to object and trying to rotate it again - it rotates around world origin.




      Yes, that's how it works. You have to rotate the object first, then translate it to the desired position. Geometric transformations are not commutative, i.e. the order of operations matter.






      share|improve this answer

























        2















        But when I apply translating to object and trying to rotate it again - it rotates around world origin.




        Yes, that's how it works. You have to rotate the object first, then translate it to the desired position. Geometric transformations are not commutative, i.e. the order of operations matter.






        share|improve this answer























          2












          2








          2







          But when I apply translating to object and trying to rotate it again - it rotates around world origin.




          Yes, that's how it works. You have to rotate the object first, then translate it to the desired position. Geometric transformations are not commutative, i.e. the order of operations matter.






          share|improve this answer













          But when I apply translating to object and trying to rotate it again - it rotates around world origin.




          Yes, that's how it works. You have to rotate the object first, then translate it to the desired position. Geometric transformations are not commutative, i.e. the order of operations matter.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 13 '18 at 9:19









          datenwolf

          132k10131234




          132k10131234























              0














              According to Nico Schertler's original answer it all depends on matrices multiplication order. So, for example, if I will use this code



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


              from my RotateZ method, shape will rotate around world origin. And, if I change my code to this:



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


              shape will rotate around it's center.






              share|improve this answer

























                0














                According to Nico Schertler's original answer it all depends on matrices multiplication order. So, for example, if I will use this code



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


                from my RotateZ method, shape will rotate around world origin. And, if I change my code to this:



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


                shape will rotate around it's center.






                share|improve this answer























                  0












                  0








                  0






                  According to Nico Schertler's original answer it all depends on matrices multiplication order. So, for example, if I will use this code



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


                  from my RotateZ method, shape will rotate around world origin. And, if I change my code to this:



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


                  shape will rotate around it's center.






                  share|improve this answer












                  According to Nico Schertler's original answer it all depends on matrices multiplication order. So, for example, if I will use this code



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


                  from my RotateZ method, shape will rotate around world origin. And, if I change my code to this:



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


                  shape will rotate around it's center.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 12 '18 at 21:06









                  Dmitry

                  183




                  183



























                      draft saved

                      draft discarded
















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.





                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53267876%2fafter-translating-shape-doesnt-rotate-around-its-origin%23new-answer', 'question_page');

                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      這個網誌中的熱門文章

                      How to read a connectionString WITH PROVIDER in .NET Core?

                      In R, how to develop a multiplot heatmap.2 figure showing key labels successfully

                      Museum of Modern and Contemporary Art of Trento and Rovereto