【发布时间】:2026-02-21 07:15:02
【问题描述】:
原问题:
问题
我有一个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 轴)上更宽。
坐标的完整列表
// 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 constexpr A = vec3(-0.5f, 0.0f, 0.0f);
auto constexpr 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 = 0.5 * (C + D);
M = translate(M, center);
// Rotate
auto constexpr p = B - A;
auto const q = D - C;
auto const n = cross(p, q);
if (n != vec3()) {
auto const a = angle(normalize(p), normalize(q));
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);
成功的结果
【问题讨论】:
-
不清楚你想达到什么目标!通过矩阵连接 2 个点是什么意思?哪些点?您是否正在构建类似于海龟图形的立方体?矩阵不加入任何它可以定位、定向和缩放某些几何图形的东西。我在您的示例中没有看到相关代码没有渲染我没有看到几何我没有看到控制代码(这可以解释你想要做什么)。请稍微编辑您的问题以使其更清楚......
-
@Spektre 我正在尝试从两个节点之间的原点移动一个单位立方体。然后旋转和缩放它以连接节点。 imgur.com/a/U2nxItB我可以链接repo,但是控制代码非常大。立方体和球体通过 .obj 文件加载。
-
所以您希望立方体的对角线在 2 点上开始/结束?你知道立方体的中心、大小、方向(最好是两个对角点的位置)吗?还有你想要立方体击中的 2 点?
-
所以轴对齐立方体为 1。以
(0,0,0)为中心,边长为1或2或2。(0,0,0)是一个对角点,(1,1,1)是另一个?您的图片建议使用后者。 -
我设法完成编辑,请参阅我的答案。
标签: c++ opengl trigonometry glm-math rotational-matrices