gpt4 book ai didi

c++ - 需要帮助了解如何使用 2D/3D 字形

转载 作者:太空宇宙 更新时间:2023-11-04 12:39:16 24 4
gpt4 key购买 nike

这是我想帮助理解的代码片段

for (i = 0; i < samplesX; i++)
for (j = 0; j < samplesY; j++)
{
newI = DIM * i / samplesX;
newJ = DIM * j / samplesY;
idx = (round(newJ) * DIM) + round(newI);
if (color_dir == 1 && draw_vecs == 1) {
direction_to_color(vx[idx], vy[idx], color_dir);
}
if (color_dir == 1 && draw_vecs == 2) {
direction_to_color(fx[idx], fy[idx], color_dir);
}
else if (color_dir == 2) {
scalar = rho[idx];
set_colormap(scalar, min, max, clampLow, clampHigh);
}
else if (color_dir == 3) {
scalar = sqrt(vx[idx] * vx[idx] + vy[idx] * vy[idx]);
set_colormap(scalar, min, max, clampLow, clampHigh);
}
else if (color_dir == 4) {
scalar = sqrt(fx[idx] * fx[idx] + fy[idx] * fy[idx]);
set_colormap(scalar, min, max, clampLow, clampHigh);
}
/*if (draw_vecs == 1) {
glVertex2f(wn + (fftw_real)newI * wn, hn + (fftw_real)newJ * hn);
glVertex2f((wn + (fftw_real)newI * wn) + vec_scale * vx[idx], (hn + (fftw_real)newJ * hn) + vec_scale * vy[idx]);
}
else if (draw_vecs == 2) {
glVertex2f(wn + (fftw_real)newI * wn, hn + (fftw_real)newJ * hn);
glVertex2f((wn + (fftw_real)newI * wn) + vec_scale * fx[idx], (hn + (fftw_real)newJ * hn) + vec_scale * fy[idx]);
}*/
if (draw_vecs == 1) {
glVertex2f(wn + (fftw_real)i * wn, hn + (fftw_real)j * hn);
glVertex2f((wn + (fftw_real)i * wn) + vec_scale * vx[idx], (hn + (fftw_real)j * hn) + vec_scale * vy[idx]);
}
else if (draw_vecs == 2) {
glVertex2f(wn + (fftw_real)i * wn, hn + (fftw_real)j * hn);
glVertex2f((wn + (fftw_real)i * wn) + vec_scale * fx[idx], (hn + (fftw_real)j * hn) + vec_scale * fy[idx]);
}
}
glEnd();
}

据我所知,目前所做的是显示这些二维线/箭头(刺猬),这些二维线/箭头(刺猬)可视化 2D 中的力/速度,如下图所示。

-

遗憾的是,我对线性代数、微积分和计算机图形学的一般理解仅到此为止,我在剖析这篇文章时遇到了困难。

理想情况下,我想了解这一点,并了解如何使用这个预先存在的代码并添加可以显示其他两种显示 vector 和/或标量场的字形类型的功能,例如

  • 三维锥体
  • 三维椭圆体

如果我遗漏了什么,请告诉我!

上述代码段中包含的一些变量:

const int DIM = 50;             //size of simulation grid
int color_dir = 0; //use direction color-coding or not
float scalar;
int newI, newJ;
float temp;
float vec_scale = 1000; //scaling of hedgehogs
int draw_vecs = 1; //draw the vector field or not

最佳答案

您那里的代码片段本来可以写得更简单(也需要一些有根据的猜测一些变量和函数的含义)。

让我们分解一下。

前两行很容易理解,它们是遍历二维数组的标准节

for (i = 0; i < samplesX; i++)
for (j = 0; j < samplesY; j++)

ij 是运行索引,它将迭代 (i,j) ∈ [i, samplesX) × [j 中的每个离散坐标元组, 样本Y)。接下来的两行将 2D 索引重新映射到一个新的值范围,特别是 [i, samplesX)×[j, samplesY) → [0, DIM)×[0, DIM)。缺少的一条信息是,DIM 是什么类型。这将使它成为某种浮点类型。

     newI = DIM * i / samplesX;
newJ = DIM * j / samplesY;

下一行很容易出错。它将 newInewJ 转换为一维数组的运行一维索引,由 ij 寻址。

为什么这是有问题的?因为在转换到 DIM 空间时信息可能已经丢失。这种信息丢失可能会导致安全漏洞(!),事实上,最近Google Chrome、Android等项目使用的渲染库Skia就出现了这种漏洞;这篇文章值得一读:https://googleprojectzero.blogspot.com/2019/02/the-curious-case-of-convexity-confusion.html

实现这个的正确方法是让 DIM 是一个整数并对其执行定点运算,最终截断小数位。但我离题了。下一个 block 实质上是执行穷人的查找表查找。 vx``vyfx``fy 是一些扁平的二维数组,通过一维索引访问,direction_to_color 映射到一个值 < strong>大概是调用glColorset_colormap 可能也是如此。这是对 OpenGL 的错误使用。

ijDIM 的整个重新映射,然后查找只是纹理查找的糟糕实现。 OpenGL 已经有了纹理。只需加载为纹理坐标数组并启用纹理。

最后,对于每个脊柱,调用两次 glVertex,一次调用位于网格中心 (wn, hn) 的起始点到偏移位置(wn, hn) + (i, j)

我对该代码的评价:完全是垃圾!所有这些都可以做得更优雅,即使是在 1994 年使用 OpenGL-1.0 时,代码似乎就是为之编写的。如果您想实现自己的 vector 场图,请不要以此为起点。

如今,我们拥有带着色器的可编程 GPU。所有这些都可以通过几行着色器代码来完成。

关于c++ - 需要帮助了解如何使用 2D/3D 字形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55048195/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com