- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试使用 OpenGL,我决定做的一件事是创建我自己的 Matrix 类,而不是使用 glm 的矩阵。Matrix 类具有平移、旋转和缩放对象的方法,如下所示:
Matrix4 Matrix4::translate(Matrix4& matrix, Vector3& translation)
{
Vector4 result(translation, 1.0f);
result.multiply(matrix);
matrix.mElements[3 * 4 + 0] = result.x;
matrix.mElements[3 * 4 + 1] = result.y;
matrix.mElements[3 * 4 + 2] = result.z;
return matrix;
}
Matrix4 Matrix4::rotate(Matrix4& matrix, float angle, Vector3& axis)
{
if (axis.x == 0 && axis.y == 0 && axis.z == 0)
return matrix;
float r = angle;
float s = sin(r);
float c = cos(r);
float omc = 1.0f - cos(r);
float x = axis.x;
float y = axis.y;
float z = axis.z;
matrix.mElements[0 + 0 * 4] = c + x * x * omc;
matrix.mElements[1 + 0 * 4] = x * y * omc - z * s;
matrix.mElements[2 + 0 * 4] = z * x * omc + y * s;
matrix.mElements[0 + 1 * 4] = x * y * omc + z * s;
matrix.mElements[1 + 1 * 4] = c + y * y * omc;
matrix.mElements[2 + 1 * 4] = z * y * omc - x * s;
matrix.mElements[0 + 2 * 4] = x * z * omc - y * s;
matrix.mElements[1 + 2 * 4] = y * z * omc + x * s;
matrix.mElements[2 + 2 * 4] = c + z * z * omc;
return matrix;
}
Matrix4 Matrix4::scale(Matrix4& matrix, Vector3& scaler)
{
matrix.mElements[0 + 0 * 4] *= scaler.x;
matrix.mElements[1 + 0 * 4] *= scaler.x;
matrix.mElements[2 + 0 * 4] *= scaler.x;
matrix.mElements[0 + 1 * 4] *= scaler.y;
matrix.mElements[1 + 1 * 4] *= scaler.y;
matrix.mElements[2 + 1 * 4] *= scaler.y;
matrix.mElements[0 + 2 * 4] *= scaler.z;
matrix.mElements[1 + 2 * 4] *= scaler.z;
matrix.mElements[2 + 2 * 4] *= scaler.z;
matrix.mElements[3 + 3 * 4] = 1;
return matrix;
}
当我在 while 循环中调用平移、旋转和缩放方法(按此特定顺序)时,它会执行我想要的操作,即平移对象,然后围绕其局部原点旋转并缩放它。但是,当我想切换顺序时,我先调用旋转然后再调用翻译,我希望它这样做:
但我的代码不会那样做。相反,它这样做:
我该怎么做才能让我的对象只围绕屏幕中心旋转,而不是围绕它的本地原点旋转?我唯一的猜测是我在转换后的矩阵上添加旋转计算时做错了,但我仍然不知道它是什么。
编辑:我需要指出的一件事是,如果我省略了旋转方法,我只处理平移和缩放,他们会做我期望他们做的事情,首先是平移,然后是旋转,然后是先旋转,然后是平移订单。
编辑 2:这是我在 while 循环中调用这些函数的方式。
Matrix4 trans = Matrix4(1.0f);
trans = Matrix4::rotate(trans, (float)glfwGetTime(), Vector3(0.0f, 0.0f, 1.0f));
trans = Matrix4::translate(trans, Vector3(0.5f, -0.5f, 0.0f));
trans = Matrix4::scale(trans, Vector3(0.5f, 0.5f, 1.0f));
shader.setUniformMatrix4f("uTransform", trans);
最佳答案
您必须通过矩阵乘法来连接矩阵。
矩阵乘法 C = A * B
的工作原理如下:
Matrix4x4 A, B, C;
// C = A * B
for ( int k = 0; k < 4; ++ k )
for ( int j = 0; j < 4; ++ j )
C[k][j] = A[0][j] * B[k][0] + A[1][j] * B[k][1] + A[2][j] * B[k][2] + A[3][j] * B[k][3];
我建议以某种方式创建指定矩阵类:
#include <array>
class Matrix4
{
public:
std::array<float, 16> mElements{
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1 };
const float * dataPtr( void ) const { return mElements.data(); }
Matrix4 & multiply( const Matrix4 &mat );
Matrix4 & translate( const Vector3 &translation );
Matrix4 & scale( const Vector3 &scaler );
Matrix4 & rotate( float angle, const Vector3 &axis );
};
实现矩阵乘法。请注意,您必须将结果存储在缓冲区中。如果您将结果直接写回矩阵成员,那么您将更改元素,稍后将在嵌套循环中再次读取这些元素,结果将不正确:
Matrix4& Matrix4::multiply( const Matrix4 &mat )
{
// multiply the existing matrix by the new and store the result in a buffer
const float *A = dataPtr();
const float *B = mat.dataPtr();
std::array<float, 16> C;
for ( int k = 0; k < 4; ++ k ) {
for ( int j = 0; j < 4; ++ j ) {
C[k*4+j] =
A[0*4+j] * B[k*4+0] +
A[1*4+j] * B[k*4+1] +
A[2*4+j] * B[k*4+2] +
A[3*4+j] * B[k*4+3];
}
}
// copy the buffer to the attribute
mElements = C;
return *this;
}
像这样调整平移、旋转和缩放的方法:
Matrix4 & Matrix4::translate( const Vector3 &translation )
{
float x = translation.x;
float y = translation.y;
float z = translation.z;
Matrix4 transMat;
transMat.mElements = {
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
x, y, z, 1.0f };
return multiply(transMat);
}
Matrix4 & Matrix4::rotate( float angle, const Vector3 &axis )
{
float x = axis.x;
float y = axis.y;
float z = axis.z;
float c = cos(angle);
float s = sin(angle);
Matrix4 rotationMat;
rotationMat.mElements = {
x*x*(1.0f-c)+c, x*y*(1.0f-c)-z*s, x*z*(1.0f-c)+y*s, 0.0f,
y*x*(1.0f-c)+z*s, y*y*(1.0f-c)+c, y*z*(1.0f-c)-x*s, 0.0f,
z*x*(1.0f-c)-y*s, z*y*(1.0f-c)+x*s, z*z*(1.0f-c)+c, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f };
return multiply(rotationMat);
}
Matrix4 & Matrix4::scale( const Vector3 &scaler )
{
float x = scaler.x;
float y = scaler.y;
float z = scaler.z;
Matrix4 scaleMat;
scaleMat.mElements = {
x, 0.0f, 0.0f, 0.0f,
0.0f, y, 0.0f, 0.0f,
0.0f, 0.0f, z, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f };
return multiply(scaleMat);
}
如果你像这样使用矩阵类,
float angle_radians = ....;
Vector3 scaleVec{ 0.2f, 0.2f, 0.2f };
Vector3 transVec{ 0.3f, 0.3f, 0.0f };
Vector3 rotateVec{ 0.0f, 0.0f, 1.0f };
Matrix4 model;
model.rotate( angle_rad, rotateVec );
model.translate( transVec );
model.scale( scaleVec );
那么结果会是这样的:
关于c++ - 在 C++ 中使用您自己的 Matrix 类进行 OpenGL 对象旋转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51669395/
...沮丧。我希望我的游戏仅在横向模式下运行。我已将适当的键/值添加到 Info.plist 文件中,以强制设备方向在启动时正确。 我现在正在尝试旋转 OpenGL 坐标空间以匹配设备的坐标空间。我正
我如何创建一个旋转矩阵,将 X 旋转 a,Y 旋转 b,Z 旋转 c? 我需要公式,除非您使用的是 ardor3d api 的函数/方法。 矩阵是这样设置的 xx, xy, xz, yx, yy, y
假设我有一个包含 3 个 vector 的类(一个用于位置,一个用于缩放,一个用于旋转)我可以使用它们生成一个变换矩阵,该矩阵表示对象在 3D 空间中的位置、旋转和大小。然后我添加对象之间的父/子关系
所以我只是在玩一个小的 javascript 游戏,构建一个 pacman 游戏。你可以在这里看到它:http://codepen.io/acha5066/pen/rOyaPW 不过我对旋转有疑问。你
在我的应用程序中,我有一个 MKMapView,其中显示了多个注释。 map 根据设备的航向旋转。要旋转 map ,请执行以下语句(由方法 locationManager 调用:didUpdateHe
使用此 jquery 插件时:http://code.google.com/p/jqueryrotate/wiki/Documentation我将图像旋转 90 度,无论哪个方向,它们最终都会变得模糊
我有以下代码:CSS: .wrapper { margin:80px auto; width:300px; border:none; } .square { widt
我只想通过小部件的轴移动图像并围绕小部件的中心旋转(就像任何数字绘画软件中的 Canvas ),但它围绕其左顶点旋转...... QPainter p(this); QTransform trans;
我需要先旋转图像,然后再将其加载到 Canvas 中。据我所知,我无法使用 canvas.rotate() 旋转它,因为它会旋转整个场景。 有没有好的JS方法来旋转图片? [不依赖于浏览器的方式] 最
我需要知道我的 Android 设备屏幕何时从一个横向旋转到另一个横向(rotation_90 到 rotation_270)。在我的 Android 服务中,我重新实现了 onConfigurati
**摘要:**本篇文章主要讲解Python调用OpenCV实现图像位移操作、旋转和翻转效果,包括四部分知识:图像缩放、图像旋转、图像翻转、图像平移。 本文分享自华为云社区《[Python图像处理] 六
我只是在玩MTKView中的模板设置;并且,我一直在尝试了解以下内容: 相机的默认位置。 使用MDLMesh和MTKMesh创建基元时的默认位置。 为什么轮换还涉及翻译。 相关代码: matrix_f
我正在尝试使用包 dendexend 创建一个树状图。它创建了非常好的 gg 树状图,但不幸的是,当你把它变成一个“圆圈”时,标签跟不上。我将在下面提供一个示例。 我的距离对象在这里:http://s
我想将一个完整的 ggplot 对象旋转 90°。 我不想使用 coord_flip因为这似乎会干扰 scale="free"和 space="free"使用刻面时。 例如: qplot(as.fac
我目前可以通过首先平移到轴心点然后执行旋转最后平移回原点来围绕轴心点旋转。在我的例子中,我很容易为肩膀做到这一点。但是,我不知道如何为前臂添加绕肘部的旋转。 我已经尝试了以下围绕肘部旋转的前臂: 平移
我想使用此功能旋转然后停止在特定点或角度。现在该元素只是旋转而不停止。代码如下: $(function() { var $elie = $("#bkgimg");
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 4 年前。 Improve this ques
我正在尝试创建一个非常简单的关键帧动画,其中图形通过给定的中点从一个角度旋转到另一个角度。 (目的是能够通过大于 180 度的 OBTUSE 弧角来制作旋转动画,而不是让动画“作弊”并走最短路线,即通
我需要旋转 NSView 实例的框架,使其宽度变为其高度,其高度变为其宽度。该 View 包含一个字符串,并且该字符串也被旋转,这一点很重要。 我查看了 NSView 的 setFrameRotati
我正在编写一个脚本,用于在 javascript 中旋转/循环浏览图像,同时遵守循环浏览图像的次数限制。我所拥有的如下: var delay = 3000; //6000 = change to
我是一名优秀的程序员,十分优秀!