- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
假设我们有一个 3D 网格,每个顶点都有纹理坐标,所以如果我渲染它展开,我会得到这样的东西(忽略红色方 block ):
现在我正在尝试找到合适的算法来使用顶点 UV 唯一标识这些区域并存储具有此唯一 ID 值的属性。这个想法是使用这个值作为颜色表的索引并得到这样的东西(手工制作):
我尝试迭代每个顶点并找到比较纹理坐标的“未连接”三角形,但网格索引顺序似乎与 UV 的放置方式无关,或者我没有应用正确的公式。我对如何存储这个值并将其传递给着色器或其他任何东西没有疑问,问题是如何知道顶点所属的“区域”,或者最终,像素。
谢谢。
更新:用于渲染网格的数据是顶点列表 (GL_VERTEX_BUFFER) 加上索引列表 (GL_ELEMENT_ARRAY)。网格被渲染为 GL_TRIANGLES,每个顶点都是这样的结构:
struct Vertex
{
float x, y, z;
float nx, ny, nz;
float tcx, tcy;
float regionId; //the attribute I want to fill
};
struct MPUVRegionVertex
{
float x, y;
int faceId, regionId;
};
更新 2:我创建了一个新的 MPUVRegionVertex 顶点数组,每个索引都有一个元素(不是每个唯一顶点)。在@CsabaBálint 回复之后,我得到了这段代码:
MPUVRegionVertex* uvVertexData = new MPUVRegionVertex[indexCount];
for(int ic = 0; ic < indexCount / 3; ic++)
{
for(int vc = 0; vc < 3; vc++)
{
uvVertexData[3*ic+vc].x = vertexData[indexData[3*ic+vc]].tcx;
uvVertexData[3*ic+vc].y = vertexData[indexData[3*ic+vc]].tcy;
uvVertexData[3*ic+vc].faceId = ic;
}
}
std::vector<std::forward_list<int> > graph(indexCount);
for(int t1=0;t1 < indexCount; ++t1)
{
for(int t2 = t1 + 1; t2 < indexCount; ++t2)
{
if (uvVertexData[t1].faceId == uvVertexData[t2].faceId)
{
graph[t1].push_front(t2);
graph[t2].push_front(t1);
}
}
}
std::forward_list<int> stack;
std::vector<int> component(indexCount);
std::set<int> notvisited;
for(int nv = 0; nv < indexCount; nv++)
{
notvisited.insert(nv);
}
int k = 0;
while(notvisited.size() > 0)
{
stack.push_front(*notvisited.begin());
notvisited.erase(notvisited.begin());
while(!stack.empty())
{
//SOMETHING WRONG HERE
int temp = stack.front();
notvisited.erase(temp);
stack.pop_front();
component[temp] = k;
stack.merge(graph[temp]);
graph[temp].clear();
}
k++;
}
结果是每三个索引都有一个不同的 k,这意味着为每个新三角形调用 k++,所以我在算法中遗漏了一些东西 :S。
component[0]=0
component[1]=0
component[2]=0
component[3]=1
component[4]=1
component[5]=1
component[6]=2
component[7]=2
component[8]=2
component[9]=3
...
component[1778]=592
component[1779]=593
component[1780]=593
component[1781]=593
关于网格的一些信息:
Size of shape[0].indices: 1782
shape[0].positions: 1242
shape[0].texcoords: 828
shape[0].normals: 1242
更新 3
有关更多信息,每个顶点只有一个 UV 坐标。
到目前为止的扣除/规则:
如果我没看错的话,这是实现非递归图遍历的正确信息。我需要迭代并保存连接和未连接的顶点,所有连接的顶点都将成为当前区域的一部分,所有不连接的顶点都将再次检查已连接的顶点,第一次迭代存储第一个三角形顶点,第二次存储所有顶点“接触”第一个三角形的三角形,继续直到迭代没有给出新的连接顶点(如果我们只检查上次迭代中添加的顶点列表,则此处优化),没有添加新顶点意味着是时候增加 regionId 和从第一个未连接的顶点重新开始。
我将尝试按照该设计实现搜索。
最佳答案
Now I'm trying to find the proper algorithm to uniquely identify those regions using the vertex UVs and storing an attribute with this unique id value.
创建图表
为顶点和面创建 id(给它们编号)。但要确保相同的顶点获得相同的 id-s,通过 UV 或位置进行比较。
创建一个 vector :std::vector<int> vertexToFace;
vertexToFace[i]==j
表示第 i 个顶点在 j 面上。
如果两个顶点在同一个面上,则它们是相邻的。
然后创建一个 std::vector<std::forward_list<int> > graph;
将顶点存储为 vector 索引,并添加邻居。 (O(n^2) 复杂度)
为此,您必须取第 i 个顶点,并且对于每个 j,您必须检查它们是否在同一面上。稍微优化的版本:
for(int i=0; i<n; ++i) for(int j=i+1; j <n ++j)
if (vertexToFace[i] == vertexToFace[j])
{
graph[i].push_front(j);
graph[j].push_front(i);
}
这是 O(n^2),但很容易实现。一个更难但更快的需要另一个 vector :std::vector<std::array<int,3>> faceToVertex;
,这样,从第 i 个顶点你可以在常数时间内访问它的邻居。无论哪种方式,我们都建立了一个图表,我们正在寻找 connected components。 , 这很容易 depth-first search .
实现连通分量算法
要实现这一点,您必须创建另一个 vector :std::vector<bool> visited(n,false);
, 和另一个 std::vector<int> component(n)
.您的问题的解决方案将在最后一个中。
算法简单,从顶点0开始,设visited[0] = true;
和 component[0]=0;
.然后对每个未访问的邻居做完全相同的事情,所以对于邻居 i(forward_list 的某个元素)if (!visited[i]) component[i] = 0;
,然后做同样的事情。当组件的所有元素都被访问时它停止。因此,您必须寻找一个未访问的元素,然后再次执行上述操作,但要知道您正在执行组件 1,依此类推。示例:
int l, k=0;
while(l!=n)
{
l=0;
while(visited[l]) l++;
fill_from(graph, visited, component, l, k);
++k;
}
我想你明白了,所以:(伪代码)
void fill_from(graph, visited, component, l, k)
{
if(visited[l]) return;
component[l] = k;
for(auto &i : graph[l])
fill_from(graph,visited,component,i,k);
}
然后我们完成了任务,但这还不是最快的解决方案。
更快的算法
为了更快,我们必须摆脱递归,之后我们不需要图表,使用 std::forward_list<int>
用于堆栈。将第一个顶点插入堆栈。然后弹出一个顶点,将其组件设置为 k。将 所有邻居 插入堆栈,然后删除邻居。换句话说,将邻居列表附加到堆栈(非常快的操作)。重复直到栈不为空。
这样我们就不会无限循环,因为如果我们回到同一个顶点,它就没有邻居,而且我们已经访问过它们。因此不需要访问 vector 。我们可以多次设置分量 vector 元素,但总是设置相同的值,所以为什么要检查它?
但是,如果我们没有访问过的 vector ,那么就很难找到我们没有访问过的另一个顶点。虽然我们可以在图中寻找一些仍然有邻居的顶点,但有更好的解决方案。
创建 std::set<int> notvisited();
对于那些还没有访问过的点。起初它应该包含所有顶点 ID,然后每次我们设置组件 ID 时,我们都会尝试从 notvisited
中删除一个顶点。放。我们重复从集合中获取一个顶点并运行 fill_from() 算法直到集合变空,同时,我们拥有所有组件 id-s。
更新:使用有关如何存储网格的更新信息。
如果您在“顶点列表”中没有相等的元素(为什么会这样),那么顶点的索引就是它在数组中的位置。这样,顶点的 id-s 就完成了。
三角形或面的 id-s 在“索引列表”中,让我将此数组命名为 int listOfIndices[];
,对于第j个面,与其相连的顶点为listOfIndices[3*j + 0]
, listOfIndices[3*j + 1]
和 listOfIndices[3*j + 2]
.要制作第一个 vector ,您必须执行以下操作:
std::vector<int> vertexToFace(num_of_verteces); //previously n
for(int j = 0; j < num_of_faces; ++j)
{
vertexToFace[listOfIndices[3*j + 0]]=j;
vertexToFace[listOfIndices[3*j + 1]]=j;
vertexToFace[listOfIndices[3*j + 2]]=j;
}
(建立逆关系的算法);请注意,在这种情况下,您甚至不需要不同的 faceToVertex
数组,因为你已经有了它(listOfIndices
),你只需要用不同的方式索引它(每次除以 3)。
关于c++ - 识别展开的网格 UV 区域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33402857/
您能否建议如何在 Bootstrap 或 IE 兼容的 CSS 网格中,在没有 CSS 网格的情况下进行以下布局。 在大屏幕中 头部,左侧堆叠的 body 和右侧覆盖头部和 body 高度的图像。 [
我想在 Objective-C 中绘制一个 15*15 的网格。格子颜色是蓝色的,就像在诺基亚制作“贪吃蛇”游戏的棋盘一样。 我试过使用 for 循环来创建 subview ,但它似乎不起作用,我查看
我正在尝试将 CSS 网格与 grid-template-columns: repeat(auto-fill, auto) 一起使用,单元格被设置为最大宽度,导致每行一个元素。 p> 是否可以让元素宽
我正在努力在网格的自定义列上添加一个指向网站的简单、简单的链接。我用了 Inchoo blog为列添加自定义渲染器,它可以工作。我认为只需修改渲染并添加标签就足够了。但我的希望破灭了,行不通。 如何做
使用 Gnuplot 我绘制了下图 - 现在,正如您在图像中看到的那样,很难在线条之间识别出其末端的块。所以我想用不同的颜色或样式交替着色网格。 我现在用来给网格着色的代码是 - set style
假设我有一个非常简单的 WPF 网格(6 行 x 6 列),定义如下:
我有一个希望绑定(bind)到 WPF 网格的集合。 我面临的问题是列数是动态的并且取决于集合。这是一个简单的模型: public interface IRows { string Messa
我正在使用 Vaadin 8,我想制作某种混淆矩阵。我想知道是否可以根据单元格位置而不是数据提供者手动填充表格/网格的值。 referenceTable.addColumn(reference ->
我在 http://jsfiddle.net/TsRJy/ 上创建了一个带有 div 框的网格. 问题 我不知道如何使 a:hover 工作。 信息 重写 HTML 代码,因为表格不适合我。 http
银光处女在这里。如何使网格周围的用户控件自动调整大小以适应内部网格宽度?目前,当浏览器窗口更宽时,用户控件的显示尺寸约为 300 或 400 像素。它在数据网格周围呈现垂直和水平滚动条,这很丑陋。我想
这个问题已经有答案了: Equal width columns in CSS Grid (11 个回答) 已关闭 2 年前。 使用 CSS Grid,当您不知道会有多少个子项时,如何将所有子项保留在一
我想使用 CSS Grid 的 grid-template-areas。 但问题是我正在使用的 CMS 添加了大量额外的包装器。有没有办法忽略额外的包装?因为它弄乱了漂亮的网格区域...... 我正在
在我的Grid中,当我单击“操作”按钮(下面的代码中显示的“删除和编辑”按钮)时,我需要弹出一个窗口,而不用警告消息提醒用户; 在下面的代码中,我正在使用HANDLER handler: button
这个问题已经有答案了: Equal width columns in CSS Grid (11 个回答) 已关闭 2 年前。 使用 CSS Grid,当您不知道会有多少个子项时,如何将所有子项保留在一
我需要模拟一个仓库,其中有几辆自动驾驶车辆在给定的布局上移动,并具有简单的优先级规则。根据我的理解,这个问题可以通过离散事件模拟(DES)轻松解决,我会使用 SimPy为了这。 我看到的问题是,我似乎
在 ASP.NET 中,我可以让用户控件在页面上的表格中占据多个单元格: 用户控件1: foo bar 第1页: 并且自动调整列宽以适应最大的用户控件。 这也可以在 WPF
我正在寻找一种方法来实时搜索我的网格+要过滤的复选框。我有一个包含学生的网格(照片和姓名)。我想要的是有一个复选框,可以过滤学生所在的不同类(class)。还有一个搜索栏,我可以在其中输入学生姓名。
我正在使用 jQuery 和 jQuery UI 构建一个 Web 应用程序。我陷入了僵局。我需要的是一个 jQuery 网格,它具有可编辑字段,并以某种方式在这些可编辑单元格之一上合并一个自动完成字
我想知道是否有其他 JavaScript 组件可以提供具有多个分组的网格表示。下面是jqGrid的截图我扩展了允许该功能,但它需要获取所有数据。我希望在扩展分组时加载数据。 另一个修改后的 jqGri
我一直在为我将在此处描述的 CSS 问题而烦恼: 在下面的示例 ( https://codesandbox.io/s/jjq4km89y5 ) 中,您可以看到一个可滚动的内容(紫色背景)和一个被左侧面
我是一名优秀的程序员,十分优秀!