Алгоритм пересечения обнаружения


Это пересечение-определение алгоритм я разработал в качестве альтернативного метода был разработан для моей курсовой работы. Я не буду постить некоторые другие функции, как они используются в курсовых, не стесняйтесь спросить, если их имена не понятны. Эта функция просто возвращает Ли 2 СМР объектов являются пересекающимися. СМР объектов либо коробки или круги. Мне бы хотелось какие-либо комментарии на мой алгоритм/стиль кодирования, чтобы помочь сделать меня лучшим программистом.

def bcw_do_collide_i(obj_A,obj_B,tracer=None, accuracy = 30):
    """ Check whether Box-Circle World objects obj_A
    and obj_B collode. If so, return True,
    otherwise return False.
    """
    # items to be checked
    comp1 = [obj_A]
    comp2 = [obj_B]

    # does a component circumcircle collide, True = collides
    truth1 = [False]
    truth2 = [False]

    # Depth used to limit iterations to accuracy
    depth = 0

    while len(comp1)!=0 and depth<accuracy:
        # Find any non colliding components
        for c1,t1 in zip(comp1,range(len(truth1))):
            circum_1 = bcw_circumcircle(c1)
            for c2,t2 in zip(comp2,range(len(truth2))):
                circum_2 = bcw_circumcircle(c2)
                if tracer <> None:
                    tracer([c1,c2,circum_1,circum_2], ["k--","b--","r--","r--"])
                if bcw_do_circles_overlap(circum_1,circum_2) == True:
                    truth1[t1] = True
                    truth2[t2] = True
                    # Check for colliding components
                    in_1 = bcw_incircle(c1)
                    in_2 = bcw_incircle(c2)
                    if tracer <> None:
                        tracer([c1,c2,in_1,in_2],
                           ["g--","b--","r--","r--"])
                    if bcw_do_circles_overlap(in_1,in_2): return True

        # Subdivide all components whose outers collide
        sub = []
        for c1,t1 in zip(comp1,truth1):
            if t1:
                sub+=bcw_components(c1)

        comp1 = sub[::]
        truth1 = [False for i in comp1]

        sub =[]
        for c2,t2 in zip(comp2,truth2):
            if t2:
                sub+=bcw_components(c2)

        comp2 = sub[::]
        truth2 = [False for i in comp1]
        depth+=1

    return False

Я был соблазн с помощью СМР объектов в качестве ключей словаря, но они должны быть изменяемы.



740
3
задан 12 апреля 2011 в 02:04 Источник Поделиться
Комментарии
1 ответ

Несколько быстрых стилистические вещи:


  1. Не использовать <>, его считали старый стиль использовать != вместо

  2. Когда сравнивать не с кем, используйте "х-нет", а не "х <> Нет" или "X != Никто" это потому, что есть только один объект никто так более корректно сравнивать идентичность объекта

  3. Не использовать == true или == ложь. Есть некоторые случаи, что не то, что вы ожидаете. Они засоряют ваш код и сделать его похожим вы не знаете, что вы делаете.

  4. Ваши переменные не дают много подсказок о том, что они делают. Например, у вас есть переменные по имени истина. Учитывая, что мы уже знали, что там держали булевых это не очень полезно.

На самом деле переделать свой код:


  1. Вы задаете значения в списке правда, а затем использовать эти значения, чтобы решить, будет ли или не предпринимать никаких действий. Флаги захламлять код. А потом эти флаги, почему бы нам не вести список. Путем добавления remaining_Comp1 и список remaining_comp2 я нажимаю элементов там вместо установки значения истины в моем списке. Это полностью исключает необходимость ведения списков правды и устраняет большую часть кода.

  2. У вас есть два цикла for, которая переберет все возможные комбинации элементов из двух списков. С помощью модуле itertools.продукта, мы можем сделать это проще

  3. Вы убедитесь, что comp1 не пустой, но и не comp2. Это выглядит как недосмотр.

  4. Вы отслеживать глубину, чтобы убедиться, что вы не слишком вдавайтесь в детали. Но вы фактически перекрываем цикла for. Я бы двигаться глубина в цикл for и просто выручить оператором Break, если comp1 и comp2 пуст.

  5. А затем, проверив, есть ли следов нет, я рекомендую использовать NullTracer, который просто ничего не делает, когда он вызывается.

Код переработан:

def bcw_do_collide_i(obj_A,obj_B,tracer=None, accuracy = 30):
""" Check whether Box-Circle World objects obj_A
and obj_B collode. If so, return True,
otherwise return False.
"""
if tracer is None:
tracer = NullTracer()

# items to be checked
comp1 = [obj_A]
comp2 = [obj_B]

for depth in range(accuracy):
if not comp1 or not comp2:
return False

remaining_comp1 = []
remaining_comp2 = []
# Find any non colliding components
for c1, c2 in itertools.product(comp1, comp2):
circum_1 = bcw_circumcircle(c1)
circum_2 = bcw_circumcircle(c2)
tracer([c1,c2,circum_1,circum_2], ["k--","b--","r--","r--"])
if bcw_do_circles_overlap(circum_1,circum_2):
remaining_comp1.append(c1)
remaining_comp2.append(c2)
# Check for colliding components
in_1 = bcw_incircle(c1)
in_2 = bcw_incircle(c2)
tracer([c1,c2,in_1,in_2],
["g--","b--","r--","r--"])
if bcw_do_circles_overlap(in_1,in_2): return True

# Subdivide all components whose outers collide
def expand_components(components):
result = []
for c1 in remaining_comp1:
result += bcw_components(components)
return result

comp1 = expand_components(remaining_comp1)
comp2 = expand_components(remaining_comp2)

return False

5
ответ дан 12 апреля 2011 в 08:04 Источник Поделиться