After translating shape doesn't rotate around it's origin
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
add a comment |
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
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
add a comment |
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
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
c# opengl graphics 3d
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
add a comment |
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
add a comment |
2 Answers
2
active
oldest
votes
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.
add a comment |
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.
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
add a comment |
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.
add a comment |
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.
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.
answered Nov 13 '18 at 9:19
datenwolf
132k10131234
132k10131234
add a comment |
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
answered Nov 12 '18 at 21:06
Dmitry
183
183
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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