寻找周围相邻网格节点个数

2011/05/10

 

在看Game Of Life的源码的时候,发现lifeSan()方法有段处理,摘出分析。

 

寻找周围相邻网格节点个数,假设在7*7的网格上如下1表示存在节点:

 

life[0] 0 0 0 0 0 0 0
life[1] 0 0 0 0 0 0 0
life[2] 0 0 0 0 0 0 0
life[3] 0 0 1 1 1 0 0
life[4] 0 0 1 0 0 0 0
life[5] 0 0 0 0 0 0 0
life[6] 0 0 0 0 0 0 0

 

要找出(3,2)节点周围存在几个节点,或者所有节点节点周围存在节点都找出来。

 

算法1

    for(int i = 0; i < life.length; i++){

        for(int i = 0; i < life.length; i++){

            if(life[i][j] == 1){

                //在边界范围内,遍历八个方向:左上,上,右上,左,右,左下,下,右下。存在1则计数器加1。

            }

        }

    }

这种算法很适合我们的的思维,使用时间n*m * 8,空间不变。

 

算法2

开辟一个n+2,m+2的数组,刚好大一圈。初始化数组为各项为0。用时(n+2)*(m+2)

ai[0] 0 0 0 0 0 0 0 0 0
ai[1] 0 0 0 0 0 0 0 0 0
ai[2] 0 0 0 0 0 0 0 0 0
ai[3] 0 0 1 2 3 2 1 0 0
ai[4] 0 0 2 2 3 1 1 0 0
ai[5] 0 0 2 2 4 2 1 0 0
ai[6] 0 0 1 1 1 0 0 0 0
ai[7] 0 0 0 0 0 0 0 0 0
ai[8] 0 0 0 0 0 0 0 0 0

 

/*
 * 如果life数组中life[i][j] = 1则,设置al数组[i][j]四周都是+1
 * 1 1 1
 * 1 0 1
 * 1 1 1
 * 叠加之后,就可以算出life[i][j]点周围有几个节点,就是al[i][j]的值。
 */

for (int k1 = 1; k1 < rows + 1; k1++) {
    for (int k = 1; k < cols + 1; k++)
        if ((life[k1 - 1][k - 1] & 1) == 1) {
            ai[k1 - 1][k - 1]++;
            ai[k1 - 1][k]++;
            ai[k1 - 1][k + 1]++;
            ai[k1][k - 1]++;
            ai[k1][k + 1]++;
            ai[k1 + 1][k - 1]++;
            ai[k1 + 1][k]++;
            ai[k1 + 1][k + 1]++;
        }
}

原理是相当于事件触发一样,如果life有节点,我就通知周围一次事件,因为是彼此相邻的。所以事件最终累计值就是该节点周围的节点数。

这种算法,时间是n*m * 8+(n+2)*(m+2),空间加倍。其实空间没有变化,因为第一种计数器需要数组变量count[n][m]存储,如果说空间的确是变多出row和col都加2这一小块空间。

 

第二种算法不如第一种,时间都消耗的是成倍,但是我们再分析下,时间成倍其实是用在数组的初始化上。而第一种count[n][m]数组同样也要初始化,所以时间也没有变化。那如果说初始化时间有多出+2这一点时间,那时肯定的。

但是如果不创建出一个大一圈的话,count[][]数组在计数的时候,要对遍历八个方向的判断数组是否越界了。这点处理时在每次循环的时候做的。加上去的话,第一种的算法时间也和第二种一样了。

 

总之,两种都可以使用,但是如果有扩展,比如多次从某个坐标取周围节点,只要直接取就可以了。

采用第二种比较方便。

### Techplot中计算网格节点面积的方法 在Techplot中,计算网格节点的面积可以通过以下几种方法实现。Techplot本身支持多种数据处理和计算功能,可以结合其内置工具或通过导出数据后使用外部工具完成面积计算。 #### 方法一:使用Techplot的内置变量计算 Techplot支持用户定义变量(User-Defined Variables)来计算各种物理量。对于网格节点的面积,可以尝试以下步骤: 1. 确保网格为三角形或四边形网格,因为面积计算通常基于这些基本单元。 2. 使用Techplot的`Area`变量,该变量可以直接计算每个单元的面积[^4]。 3. 如果需要计算单个节点的面积,可以通过对相邻单元面积进行加权平均来近似得到节点面积。 ```python # 示例代码:Techplot脚本伪代码 LoadData("mesh.dat") # 加载网格数据 DefineVariable("CellArea", "area") # 定义单元面积变量 DefineVariable("NodeArea", "average(area, node)") # 节点面积为单元面积的平均值 ``` #### 方法二:导出数据并使用VTK进行计算 如果Techplot无法直接满足需求,可以将网格数据导出为通用格式(如PLY、STL等),然后利用VTK库进行面积计算。具体步骤如下: 1. 在Techplot中将网格导出为PLY或STL格式。 2. 使用VTK库加载网格数据,并计算每个节点的面积。 以下是Python代码示例: ```python import vtk # 读取网格文件 reader = vtk.vtkPLYReader() reader.SetFileName("mesh.ply") reader.Update() # 将多边形网格转换为三角形网格 triangle_filter = vtk.vtkTriangleFilter() triangle_filter.SetInputConnection(reader.GetOutputPort()) triangle_filter.Update() # 获取三角形单元数据 polydata = triangle_filter.GetOutput() num_cells = polydata.GetNumberOfCells() # 计算每个节点的面积 node_areas = {} for cell_id in range(num_cells): cell = polydata.GetCell(cell_id) points = cell.GetPoints() point_ids = cell.GetPointIds() # 计算三角形单元面积 p0 = points.GetPoint(0) p1 = points.GetPoint(1) p2 = points.GetPoint(2) area = abs((p1[0] - p0[0]) * (p2[1] - p0[1]) - (p2[0] - p0[0]) * (p1[1] - p0[1])) / 2.0 # 将面积分配给节点 for i in range(point_ids.GetNumberOfIds()): node_id = point_ids.GetId(i) if node_id not in node_areas: node_areas[node_id] = 0.0 node_areas[node_id] += area / 3.0 # 每个节点分担1/3的单元面积 # 输出节点面积 for node_id, area in node_areas.items(): print(f"Node {node_id} Area: {area}") ``` #### 方法三:基于经纬度网格的面积公式 如果网格是基于经纬度生成的,则可以使用球面网格面积公式进行计算。假设网格节点位于球面上,面积公式如下: \[ \text{area}(i,j) = \left(\frac{\pi}{180.0}\right) R^2 \cdot \left| \sin\left(\frac{\text{dLat1}(i)}{180.0} \pi\right) - \sin\left(\frac{\text{dLat2}(i)}{180.0} \pi\right) \right| \cdot \left| \text{dLon1}(j) - \text{dLon2}(j) \right| \] 其中,\(R\)为地球半径,\(\text{dLat1}, \text{dLat2}\)为纬度范围,\(\text{dLon1}, \text{dLon2}\)为经度范围[^3]。 #### 注意事项 - 如果网格不是封闭的三角形网格,可能需要先进行网格修复或转换。 - 对于复杂几何形状,建议使用更高阶的有限元单元(如P-element)以提高精度[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值