- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一个三角形网格,它有不同的三角形组,例如一组 15 个相连的三角形,然后是另一组(未连接到第一个)25 个三角形。连接三角形的组数是任意的,组本身可以是任何大小(1 到任何大小)。我需要为每个三角形顶点分配一个索引,指示它属于哪一组相连的三角形。因此,在上面的示例中,我会给构成 15 个三角形组的顶点指定索引 0,为构成 25 个三角形组的顶点指定索引 1(依此类推)。
当我向它提供一个包含 70,000 多个三角形的数组时,下面的代码非常慢,但是可以运行。是否有人对我可以找到最有效优化的代码区域有所了解?
int _tmain(int argc, _TCHAR* argv[])
{
//test array of vertex indices - each triple is a discrete triangle
int vv[21] = {0,1,2, 2,3,4, 4,5,6, 7,8,9, 9,10,11, 0,99,80, 400, 401, 402};
//setup the initial arrays prior to the while loop
std::vector<int> active_points;
std::vector<vector<int>> groups;
std::vector<int> active_triplets(&vv[0], &vv[0]+21);
//put the first three triangle points into active points
active_points.push_back(active_triplets[0]);
active_points.push_back(active_triplets[1]);
active_points.push_back(active_triplets[2]);
int group_index = 0;
//put these initial points in the first group
std::vector<int> v;
v.push_back(active_points[0]);
v.push_back(active_points[1]);
v.push_back(active_points[2]);
groups.push_back(v);
//remove the first triangle points from the triplets array
std::vector<int>::iterator it = active_triplets.begin();
active_triplets.erase(it, it+3);
while (active_triplets.size() > 0)
{
//once we've exhausted the first group of connections
//we move on the next connected set of triangles
if (active_points.size() == 0)
{
group_index++;
active_points.push_back(active_triplets[0]);
active_points.push_back(active_triplets[1]);
active_points.push_back(active_triplets[2]);
std::vector<int> v;
for (std::vector<int>::iterator it = active_points.begin(); it != active_points.end(); ++it)
{
v.push_back(*it);
}
groups.push_back(v);
std::vector<int>::iterator it = active_triplets.begin();
active_triplets.erase(it,it+3);
}
//create a vector to store the 'connected' points of the current active points
//I don't think I can modify any of the existing vectors as I iterate over them
std::vector<int> temp_active_points;
//start check this group of three vertices
for (std::vector<int>::iterator it = active_points.begin(); it != active_points.end(); ++it)
{
std::vector<int> polys_to_delete;
for (std::vector<int>::iterator it_a = active_triplets.begin(); it_a != active_triplets.end();++it_a)
{
if (*it == *it_a)
{
//which triangle do we hit? put all points in temp_active_points.
//Once a vertex matches with another vertex we work out the other
//connected points in that triangle from that single connection
int offset = it_a - active_triplets.begin();
int mod = (it_a - active_triplets.begin()) % 3;
polys_to_delete.push_back(offset - mod);
if (mod == 1)
{
temp_active_points.push_back(active_triplets.at((offset - 1)));
temp_active_points.push_back(active_triplets.at((offset + 1)));
}
else if (mod == 2)
{
temp_active_points.push_back(active_triplets.at((offset - 2)));
temp_active_points.push_back(active_triplets.at((offset - 1)));
}
else
{
temp_active_points.push_back(active_triplets.at((offset + 1)));
temp_active_points.push_back(active_triplets.at((offset + 2)));
}
}
}
int offset_subtraction = 0;
for (std::vector<int>::iterator it = polys_to_delete.begin(); it != polys_to_delete.end(); ++it)
{
std::vector<int>::iterator it_a = active_triplets.begin();
active_triplets.erase(it_a + (*it - offset_subtraction), it_a + (*it - offset_subtraction) + 3);
offset_subtraction += 3;
}
}
for (std::vector<int>::iterator it = temp_active_points.begin(); it != temp_active_points.end(); ++it)
{
groups[group_index].push_back(*it);
}
//remove duplicates
std::sort( temp_active_points.begin(), temp_active_points.end() );
temp_active_points.erase( std::unique( temp_active_points.begin(), temp_active_points.end() ), temp_active_points.end() );
active_points = temp_active_points;
temp_active_points.clear();
}
for (std::vector<vector<int>>::iterator it = groups.begin(); it != groups.end(); ++it)
{
for (std::vector<int>::iterator it_sub = (*it).begin(); it_sub != (*it).end(); ++it_sub)
{
std::cout << it - groups.begin() << ' ' << *it_sub << '\n';
}
}
}
在 Peter 的评论之后,我在一位同事的帮助下重做了代码。使用 map 要快得多:
#include "stdafx.h"
#include <iostream> // std::cout
#include <algorithm> // std::set_difference, std::sort
#include <vector> // std::vector
#include <set> // std::vector
#include <cmath>
#include <map>
using namespace std;
// the global vertex indices
int numIndices;
int* indices;
class Triangle
{
public:
explicit Triangle(int positionIndex_) : added(false), positionIndex(positionIndex_) {}
int positionIndex; // positinon of the first index of this triangle in the global vert array (which is in 3's)
// only valid with 0, 1, 2
int getIndex(int i) { return indices[positionIndex + i];}
bool isNeighbour(Triangle* other)
{
for (int i = 0; i < 3; ++i)
for (int j = 0; j < 3; ++j)
if (getIndex(i) == other->getIndex(j))
return true;
return false;
}
bool isAdded() const{return added;}
void setAdded(){ added = true;}
int getNeighbourCount() const{ return neighbours.size(); }
Triangle* getNeighbour(int i) const{ return neighbours[i];}
void AddNeighbour(Triangle* neighbour)
{
neighbours.push_back(neighbour);//changed to set
}
private:
std::vector<Triangle*> neighbours;//changed to set
bool added;
};
std::vector<Triangle*> triangles;
void createAllTriangles()
{
for (int i = 0; i < numIndices; i += 3)
triangles.push_back(new Triangle(i));
//must delete all these pointers created with new
}
void setupAllNeighboursA()
{
std::map<int,std::set<int>> vertex_to_tris;
for (int i = 0; i < numIndices; i += 3)
{
vertex_to_tris[indices[i]].insert(i);
vertex_to_tris[indices[i+1]].insert(i);
vertex_to_tris[indices[i+2]].insert(i);
}
int n = triangles.size();
for (int i = 0; i < n; ++i)
{
Triangle* t = triangles[i];
std::set<int> temp_neighbours;
for (int j = 0; j < 3; ++j)
{
int test_index = t->getIndex(j);
for (std::set<int>::iterator it = vertex_to_tris[test_index].begin(); it != vertex_to_tris[test_index].end(); ++it)
{
if (*it != i) temp_neighbours.insert(*it/3);//divide by 3 to get the 'actual' tri index
}
}
for (std::set<int>::iterator it = temp_neighbours.begin(); it != temp_neighbours.end(); ++it)
{
Triangle* other = triangles[*it];
t->AddNeighbour(other);
}
}
}
class Island
{
public:
void recursiveAdd(Triangle* t)
{
AddAndSetAdded(t);
for(int i = 0; i < t->getNeighbourCount(); i++)
if ( ! t->getNeighbour(i)->isAdded() )
recursiveAdd(t->getNeighbour(i));
}
std::set<Triangle*> children;
private:
void AddAndSetAdded(Triangle* t)
{
t->setAdded();
children.insert(t);
}
};
std::vector<Island*> island_list;
void createIslands()
{
for (int i = 0; i < int(triangles.size()); ++i)
{
Triangle* t = triangles[i];
if( ! t->isAdded() )
{
Island* island = new Island;
island->recursiveAdd(t);
island_list.push_back(island);
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
indices = vv;
numIndices = 73728;
createAllTriangles();
setupAllNeighboursA();
createIslands();
for (int x = 0; x < int(island_list.size()); x++)
{
std::cout << "Island Index: " << x << endl;
std::cout << island_list[x]->children.size() << endl;
}
}
最佳答案
我想大部分时间会花在这几行:
for (std::vector<int>::iterator it = active_points.begin(); it != active_points.end(); ++it)
{
std::vector<int> polys_to_delete;
for (std::vector<int>::iterator it_a = active_triplets.begin(); it_a != active_triplets.end();++it_a)
{
if (*it == *it_a)
我的理解是,这是针对每个事件三角形测试每个事件点,因此这可能会针对每个事件点循环数千次。
我认为如果您准备一个从顶点到使用相应顶点的三角形列表的映射,这会更快。然后您会立即发现所有连接的三角形,而不必搜索它们。
关于将连接的三角形分类为组的 C++ 算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17554530/
SDL3 提供了 SDL_RenderGeometry 函数绘制几何图形,用法和 OpenGL 差不多,先定义顶点数据,然后根据顶点数据绘制几何图形。 绘制三角形的代码如下: std::array
我想在图像上使用三角形类型按钮,但我无法执行此操作... 如何做到这一点? 最佳答案 这个project可以帮你。您可以自定义 UIButton 的形状。 关于iphone - 定制非矩形按钮 三角形
我一直在尝试找出如何使用 Python 制作彩虹三角螺旋。我可以制作一个方形螺旋,但它不会导入颜色。而且它不使用三角形。 输出应该是什么样子: 我取得的成就: 我的代码: import tur
我正在使用 this 研究三角形检测算法文章。我编写了这段代码,但不幸的是,当三角形之间存在交集时,该方法返回 false。 private boolean checkTriangleCollisio
我在资源文件中找到了几个关于如何在 Android 中绘制三角形的答案。但是我没有找到任何可以解释如何更改三角形旋转的内容。 我找到的例子:
对于编码类(class)中的作业,我应该找到一种方法让 Python 制作星号三角形,如下所示: x xx xxx 但是,无论我用我的代码做什么,我都无法做到这一点。最好的我可以得到的是:
我在绘制两个多边形时遇到问题。我想填充两个三角形,但一个大于第二个。我在 winforms 中使用 UserControl。代码: Point[] DOWN = new Point[] {new Po
如何测试三角形和正方形是否相交? 当我们知道它是正方形而不是矩形时,有什么方法可以优化它吗?此外,正方形是轴对齐的,这样应该可以进一步提升性能? 或者我应该把正方形分成三角形,然后对三角形-三角形相交
我有一个方法是画一个多边形,然后将多边形向右旋转90度,使其原来的顶点现在指向右边。 这是绘制多边形(三角形)的代码,但我不知道如何旋转它。 Point[] points = new Point[3]
我知道有高效的多边形裁剪算法(例如 Maillot、Vatti、Greiner-Hormann)。然而,这些算法适用于任意多边形,尽管它们适合我的情况,但在我看来,对像我这样的简单情况使用这种通用算法
我的问题可能很愚蠢,但我没有找到三角形 strip 使用的好例子: http://i.stack.imgur.com/KL8jk.png 像这样的顶点: A: -0.5f, -0.5f, // Bo
我正在尝试创建一个等边三角形,您可以在 fiddle 中看到它: 我的想法是,我将笔放在 (0, 0) 处,然后在 (20, 11) 处画线,但三角形看起来不正确。 最佳答案 您的三角形已被
通过编写一些逻辑代码,只是无法弄清楚如何以所需的形式获得 01 三角形的输出,三角形确实打印出来,但不是根据要求的输出。 import java.util.Scanner; import java
我一直在尝试制作一个简单的 pygame 程序来检查光标是否在三角形内部或外部。我通过找到较大三角形的面积,然后从鼠标位置到所有三个点制作三个内部三角形并找到它们的面积来完成此操作。 根据我的理解,如
我有一个方法 drawTriangle,它在 JAVA 中的 OpenGL 程序的 display() 方法中被引用。 public void drawTriangle(GL gl, int x1,
我正在尝试用 C++ 创建一个程序,该程序将数字的三角形模式放入二维数组中。 示例: 1 3 4 5 9 2 9 4 6 1 顶行是一个数字(整数),三角形的每一行比它上面的行多一
所以我最近一直在尝试学习 OpenGL,遵循了几个文本和视频教程。 我无法绘制三角形,我已经双重和三次检查我是否以正确的顺序执行了所有必要的步骤,但我显然遗漏了一些东西 在添加一些代码之前,我应该声明
我遇到了一个用递归绘制谢尔宾斯基三角形的程序。我如何解释这段代码是调用 sierpinski1 直到 n == 0,然后只绘制 3 个小三角形(每次调用一个三角形),因为 n == 0 是绘制某些东西
我有一个需要 3 个点的函数,我将使用这些点来绘制一个三角形,就好像我在使用 glVertex 函数一样。 但由于我想在避免透视变形的同时对这个三角形进行纹理贴图,我必须对其进行 segmentati
下面的代码应该为三角形添加一个 3d 对象,但我收到错误 Assets/Scripts/MakeTriangle.cs(6,28):错误 CS0120:需要对象引用才能访问非静态成员 `UnityEn
我是一名优秀的程序员,十分优秀!