为带有GLM(旋转)的OpenGL创建转换矩阵

问题描述 投票:2回答:1

原始问题:

问题

我有一个unit cube,我想对其进行转换,以使其连接两个点。我是OpenGL新手,只了解线性代数的最基本部分。在连接点的过程中,我试图模仿类似于极坐标的东西。当Z和另一个轴发生变化时,我当前的实现不起作用。我也尝试过mat = glm::lookAt(center, terminal, y_axis);,但没有成功。

代码

这来自schedule_edge_update()中for循环的主体。

auto const initial = p1;
auto const terminal = p2;
auto const distance = glm::distance(initial, terminal);
auto const length = distance * 0.5f;
auto const center = (initial + terminal) / 2.f;
auto const rejection = terminal - initial;
auto const delta = glm::normalize(rejection);

auto mat = glm::mat4(1);

// translate
mat = glm::translate(mat, center);

// rotate
auto const phi_hyp = glm::length(glm::vec2(delta.x, delta.z));
if (phi_hyp != 0.0f) {
    auto phi = acosf(delta.x / phi_hyp);
    mat = glm::rotate(mat, phi, y_axis);
}

auto const theta_hyp = glm::length(glm::vec2(delta.x, delta.y));
if (theta_hyp != 0.0f) {
    auto theta = acosf(delta.x / theta_hyp);
    theta *= delta.x > 0 ? -1.0f : 1.0f;
    mat = glm::rotate(mat, theta, z_axis);
}

// scale
edges->add_matrix(glm::scale(mat, glm::vec3(length, 0.05f, 0.01f)));

将矩阵添加到edges时,将排队等待缓冲以进行实例渲染。

远方

以下是我的测试点和我制作的一个大立方体。“很远”

关闭

这里是一个不起作用的例子。起始点标记为p1,终点标记为p2。未连接任何点的线应连接p1和p2。“关闭”>>

不同特写

这里是另一个例子,但是这个例子标有p1和p2的坐标。 p1和p2的区别在于Y和Z的变化。但是,我的代码将立方体(在转换后)绕y轴旋转了90度。然后是缩放比例。您可以说它是旋转的,因为它在一个轴(旋转前的y轴)上更宽。Different Close Up

完整的坐标列表
// Test points
auto const A = glm::vec3(-10.0f, -10.0f, -20.0f);
auto const B = glm::vec3(+10.0f, -10.0f, -20.0f);
auto const C = glm::vec3(+10.0f, +10.0f, -20.0f);
auto const D = glm::vec3(+00.0f, +10.0f, -20.0f);
auto const E = glm::vec3(+05.0f, +05.0f, -20.0f);
auto const F = glm::vec3(+00.0f, +00.0f, -30.0f);
auto const G = glm::vec3(-10.0f, -10.0f, -30.0f);
auto const H = glm::vec3(+55.0f, -15.0f, -60.0f);
auto const I = glm::vec3(+55.0f, -05.0f, -70.0f);

get_nodes().emplace_back(A);
get_nodes().emplace_back(B);
get_nodes().emplace_back(C);
get_nodes().emplace_back(D);
get_nodes().emplace_back(E);
get_nodes().emplace_back(F);
get_nodes().emplace_back(G);
get_nodes().emplace_back(H);
get_nodes().emplace_back(I);

get_edges().emplace_back(A, B);
get_edges().emplace_back(B, C);
get_edges().emplace_back(C, D);
get_edges().emplace_back(D, E);
get_edges().emplace_back(E, F);
get_edges().emplace_back(F, G);
get_edges().emplace_back(G, H);
get_edges().emplace_back(H, I);

// Big cube
auto const C0 = glm::vec3(-5.0f, -5.0f, -5.0f);
auto const C1 = glm::vec3(-5.0f, -5.0f, +5.0f);
auto const C2 = glm::vec3(-5.0f, +5.0f, -5.0f);
auto const C3 = glm::vec3(-5.0f, +5.0f, +5.0f);
auto const C4 = glm::vec3(+5.0f, -5.0f, -5.0f);
auto const C5 = glm::vec3(+5.0f, -5.0f, +5.0f);
auto const C6 = glm::vec3(+5.0f, +5.0f, -5.0f);
auto const C7 = glm::vec3(+5.0f, +5.0f, +5.0f);

get_nodes().emplace_back(C0);
get_nodes().emplace_back(C1);
get_nodes().emplace_back(C2);
get_nodes().emplace_back(C3);
get_nodes().emplace_back(C4);
get_nodes().emplace_back(C5);
get_nodes().emplace_back(C6);
get_nodes().emplace_back(C7);

get_edges().emplace_back(C0, C1);
get_edges().emplace_back(C0, C2);
get_edges().emplace_back(C0, C4);
get_edges().emplace_back(C1, C3);
get_edges().emplace_back(C1, C5);
get_edges().emplace_back(C2, C3);
get_edges().emplace_back(C2, C6);
get_edges().emplace_back(C3, C7);
get_edges().emplace_back(C4, C5);
get_edges().emplace_back(C4, C6);
get_edges().emplace_back(C5, C7);
get_edges().emplace_back(C6, C7);

schedule_node_update();
schedule_edge_update();

Spektre使用GLM的解决方案

代码

auto const A = vec3(-0.5f, 0.0f, 0.0f);
auto const B = vec3(+0.5f, 0.0f, 0.0f);
auto const C = p1;
auto const D = p2;

auto M = mat4(1.0f);

// Translate
auto const center = (C + D) / 2.0f;
M = translate(M, center);

// Rotate
auto const p = B - A;
auto const q = D - C;
auto const n = cross(p, q);
auto const a = angle(normalize(p), normalize(q));
if (n != vec3()) {
    M = rotate(M, a, n);
}

// Scale
auto constexpr thickness = 0.05f;
M = scale(M, vec3(0.5f * distance(C, D), thickness, thickness));

edges->add_matrix(M);

成功的结果

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS9JMDVPTC5wbmcifQ==” alt =“成功的结果”>“ >>

原始问题:问题我有一个要变换的单位立方体,以使其连接两个点。我是OpenGL新手,只了解线性代数的最基本部分。我有...

c++ opengl trigonometry glm-math rotational-matrices
1个回答
3
投票

所以问题归结为:

我知道4点A,B,C,D,并且我想计算将A,B转换为C,D的变换矩阵。

© www.soinside.com 2019 - 2024. All rights reserved.