简体   繁体   English

如何迭代地改变 function arguments 而不是使用递归?

[英]How do I mutate a function arguments iteratively instead of using recursion?

I am trying to subdivide a triangular mesh till the length of each edge are smaller than an arbitrary value.我正在尝试细分三角形网格,直到每个边的长度小于任意值。 My approach is pretty simple, I take a look at each edge and calculate its length.我的方法很简单,我查看每条边并计算其长度。 If the length of the edge is greater than say 100, I subdivide the faces containing this edge.如果边的长度大于 100,我会细分包含该边的面。 Say for example, I subdivide the pair of faces sharing an edge into 2 faces each, then I update the vertices list as well as face list.例如,我将共享一条边的一对面细分为 2 个面,然后更新顶点列表和面列表。 This however only handles the first edge that is greater than 100. The newly formed edges might share edges with existing faces which are longer than 100. I want to check all those edges.但是,这仅处理大于 100 的第一条边。新形成的边可能与大于 100 的现有面共享边。我想检查所有这些边。 My guess now is that, I can either do it recursively or iteratively.我现在的猜测是,我可以递归或迭代地进行。 I am trying to do this recursively, but I have now a code that I barely understand and am unsure if it returns the correct result.我正在尝试以递归方式执行此操作,但我现在有一个我几乎无法理解并且不确定它是否返回正确结果的代码。 Here's what I have till now in Pseudocode.这是我到目前为止在伪代码中所拥有的。 How would I do this iteratively?我将如何迭代地做到这一点?

vertices= [[0.0, 0.0, 0.0], [0.0, 0.0, 50.0], [0.0, 50.0, 0.0], [0.0, 50.0, 50.0], [100.0, 0.0, 0.0], [100.0, 0.0, 50.0], [100.0, 50.0, 0.0], [100.0, 50.0, 50.0]]
faces = [[6, 7, 4], [4, 7, 5], [2, 6, 0], [0, 6, 4], [3, 2, 1], [1, 2, 0], [7, 3, 5], [5, 3, 1], [2, 3, 6], [6, 3, 7], [1, 0, 5], [5, 0, 4]]

edges = get_edges_from_faces(faces)

def subdivide_mesh(faces, vertices,edges):
   for edge in edges:
       if length(edge) > 100:
          create_new_faces_and_update() #delete the face sharing this edge and update faces list
          add_new_vertices() # add new vertices to 
       edges = get_edges_from_faces(faces)
       subdivide_mesh(faces, vertices, edges) 


The danger lies in modifying a list on which you are currently iterating.危险在于修改您当前正在迭代的列表。 The easiest way to avoid that danger is to make a copy of the list, so that your input list (on which you are iterating) and your output list (which you are modifying) are not the same object.避免这种危险的最简单方法是制作列表的副本,以便您的输入列表(您正在迭代)和您的 output 列表(您正在修改)不是同一个 object。

The code you supplied in your question is not a reproducible example (it's lacking the definition of get_edges_from_faces , for instance).您在问题中提供的代码不是可重现的示例(例如,它缺少get_edges_from_faces的定义)。 So instead of fixing your code, I'll solve a similar but simpler problem and you can draw inspiration from that.因此,我不会修复您的代码,而是解决一个类似但更简单的问题,您可以从中汲取灵感。

Problem: In a given list of numbers, replace every number x which is bigger than 10 by smaller numbers which sum to x .问题:在给定的数字列表中,将每个大于 10 的数字x替换为总和为x的较小数字。 For instance, the list [3, 12, 5] should become [3, 6, 6, 5] or something similar.例如,列表[3, 12, 5]应该变成[3, 6, 6, 5]或类似的东西。

We are going to iterate on a list l , and add its elements to a result list result , subdivising them when necessary.我们将对列表l进行迭代,并将其元素添加到结果列表result中,并在必要时细分它们。

Code:代码:

def subdivise_numbers(l):
  result = []
  for x in l:
    if x < 10:
      result.append(x)
    else:
      y = x // 2
      z = x - y
      result.append(y)
      result.append(z)
  return result

Note how we never added elements to the original list l .请注意我们从未向原始列表l添加元素。

Does this answer your question?这回答了你的问题了吗?

Note that if the list originally contains a number greater than 20, the y and z we add to the result might still be too big.请注意,如果列表最初包含大于 20 的数字,我们添加到结果中的yz可能仍然太大。 One possible way to fix this is to encapsulate our code into a while loop with stop condition "if we didn't subdivise anything in the last run, stop".解决此问题的一种可能方法是将我们的代码封装到带有停止条件的 while 循环中“如果我们在上次运行中没有细分任何内容,请停止”。 This require adding a variable to keep track of whether you've subdivided something is this current run or not.这需要添加一个变量来跟踪您是否已经细分了当前运行。

def subdivise_numbers(l):
  keep_going = True
  result = l
  while keep_going:
    keep_going = False
    l = result
    result = []
    for x in l:
      if x < 10:
        result.append(x)
      else:
        keep_going = True
        y = x // 2
        z = x - y
        result.append(y)
        result.append(z)
  return result

Another, better way, is to make sure the numbers y and z we add are already smaller than 10:另一种更好的方法是确保我们添加的数字yz已经小于 10:

def subdivise_numbers(l):
  result = []
  for x in l:
    while x >= 10 and x > 0:
      y = min(9, x // 2)
      x = x - y
      result.append(y)
    result.append(x)
  return result

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM