Blender для начинающих/Python практика

Blender2017.png



OpenHK2.jpg - перейти к комбинациям клавиш.
Level2.jpg - перейти к первому необязательному для изучения разделу.
NextChapter.jpg - переход к следующей по курсу главе (порядок глав не совпадает с порядком глав по содержанию).

CTRL+ALT+U

CTRL+U

SHIFT+S

CTRL+Q

A

R

G

S

SHIFT+D

ALT+D

CTRL+NUMPAD+

CTRL+NUMPAD-

SHIFT+L

SHIFT+G

ALT+M

F

CTRL+ALT+SHIFT+C

SHIFT+S

D

T

I

Shift+B

B

C

Одни из главных классов Python: bpy.ops | bpy.data | bpy.types.ID

Рендеринг Рендер-ферма
Отсечение Шейдер
Трассировка лучей Сжатие текстур

Расположение элементов интерфейса


Ссылки на материалы
Возможно, Вас заинтересует следующее:
О Blender 2.76 FInfo.jpg Скачать Blender 2.76 FDownload.jpg

Алгебраические задачиПравить

Перестановка значений переменныхПравить

def Swap(a, b):
    a = a + b
    b = a - b
    a = a - b

ЦиклыПравить

Пусть, имеется переменная a, значение которой после цикла while надо узнать. Пусть, inc - число, на которое увеличивается a. B - переменная, задающая условие в цикле:

while a знак B:
    a = a + inc

inc - независимая переменная. Значение a приближается к значению B.

  1. Если неравенство нестрогое, то после цикла a = a + inc*(abs(B - a) // inc + 1).
  2. Если неравенство строгое, то рассматриваются два случая:
    1. Если B % inc != 0, то a = a + inc*(abs(B - a) // inc + 1).
    2. Если B % inc == 0, то a = a + inc*(abs(B - a) // inc).

Таким образом, если неравенство нестрогое или неравенство строгое и остаток от деления B на inc не равен 0, то a = a + inc*(abs(B - a) // inc + 1), а во всех остальных случаях a = a + inc*(abs(B - a) // inc)

Если a = B и неравенство нестрогое, то переменная a = a + inc.

Геометрические задачиПравить

Расположение точки на диагоналиПравить

Пусть, имеется точка A(x, y), то будет или нет она располагается на диагонали, можно будет узнать так:

if math.fabs(x) == math.fabs(y):
    print("Точка на диагонали")

math.fabs(x) возвращает модуль числа x.

Точка находится под прямойПравить

Пусть, имеется точка A(x, y), где x, y - нецелые числа. Уравнение прямой y = kx + b. Функция, возвращающая y в зависимости от x:

def getY(x, k, b):
    return k*x+b

Узнать ниже ли точка прямой или нет, можно, подставив ее x в уравнение прямой:

if y < getY(x, y, k):
    print("Точка под прямой.")

Точка на прямойПравить

Пусть, имеется точка A(x, y), где x, y - нецелые числа. Узнать на прямой ли точка или нет, можно, подставив ее x в уравнение прямой:

if y == getY(x, y, k):
    print("Точка на прямой.")

Точка над прямойПравить

Пусть, имеется точка A(x, y), где x, y - нецелые числа. Узнать выше прямой ли точка или нет, можно, подставив ее x в уравнение прямой:

if y > getY(x, y, k):
    print("Точка над прямой.")

Вычисление k перпендикулярной прямойПравить

Пусть, имеется точки A(x, y) и A(x2, y2), задающие прямые, где x, y - нецелые числа. То зная k первой прямой вычислить k для второй можно следующим образом:

import math
k2 = math.tan(math.atan(k)+90)

Вычисление координат точки пересечения прямыхПравить

Пусть, прямые задаются такими уравнениями:

  1. y1 = k1*x + b1
  2. y2 = k2*x + b2

Приравняв их, получим: k1*x + b1 = k2*x + b2.

  1. k1*x - k2*x = b2 - b1
  2. x(k1 - k2) = b2 - b1

Следовательно, x = (b2 - b1)/(k1 - k2). Таким образом, узнать координаты точки пересечения прямых можно так:

x = (b2 - b1)/(k1 - k2)
y = k1*x + b1 # Без разницы, в уравнение какой прямой подставлять.

Вычисление коэффициента наклона прямойПравить

Пусть, прямая проходит через две точки: A(x, y) и B(x1, y1). Причем, точка B лежит правее и выше точки A. Тогда вычисление коэффициента k для уравнения прямой будет выглядеть следующим образом:

k = (y1 - y)/(x1 - x)

СтолкновенияПравить

Окружность с окружностьюПравить

Если расстояние между радиусами окружностей больше суммы их радиусов, то они не пересекаются:

import math
if (math.sqrt((circle1.x - circle2.x)**2 + (circle1.y - circle2.y)**2) >= circle1.r + circle2.r):
    print("Окружности не пересекаются.")

Здесь circle1 и circle2 - окружности.

Пересечение отрезковПравить

   
Схема определения пересечения отрезков выглядит так:

Если проекции отрезков на ось X пересекаются:

Найти точку пересечения прямых, на которых лежат отрезки.
Если координата точки пересечения принадлежит одновременно двум проекциям отрезков на ось X, то:
Отрезки пересекаются.
Иначе:
Отрезки не пересекаются.

Пусть, есть две точки, составляющих первый отрезок: A(x, y) и B(x1, y1). Пусть, есть две точки, составляющие второй отрезок: C(x2, y2) и D(x3, y3). Пусть, точки расположены по оси +X в таком порядке: A, B, C, D.

if ((x1 >= x3) and (x1 <= x4)) or ((x >= x3) and (x <= x4)):
    intersectX = (b2 - b1)/(k1 - k2)
    if ((intersectX >= x) and (intersectX <= x1)) or ((intersectX >= x2) and (intersectX <= x3)):
        print('Отрезки пересекаются.')
    else:
        print('Отрезки не пересекаются.')
else:
    print('Отрезки не пересекаются.')

Данная схема будет корректно работать лишь в том случае, если ни один из отрезков не перпендикулярен оси X.

Принципы написания UIПравить

Аббревиатура «UI» расшифровывается на русский язык как «пользовательский интерфейс».

КнопкиПравить

 
Границей любой кнопки обычно является прямоугольник, поэтому проверка на принадлежность точки A(x, y) этому прямоугольнику можно задать следующим условием:

if (A.x >= button.x) and (A.y >= button.y) and (A.x <= button.x + button.width) and (A.y <= button.y + button.heigth):
  1. A.x - X координата точки
  2. A.y - Y координата точки
  3. button.x - X координата левого верхнего угла прямоугольника
  4. button.y - Y координата левого верхнего угла прямоугольника
  5. button.width - ширина прямоугольника
  6. button.height - высота прямоугольника

ПолзункиПравить

Любой ползунок представляет собой два прямоугольника. Первый - границы ползунка, второй - значение ползунка. Напишем функцию, которая определит лежит ли точка в границах первого прямоугольника «border»:

def intersect(A, border):
    if (A.x >= border.x) and (A.y >= border.y) and (A.x <= border.x + border.width) and (A.y <= border.y + border.heigth):
        return True
    else:
        return False

Пусть, Вы перемещайте ползунок, то код для обработки изменения значения ползунка будет следующий:

if cursor.x < border.x:
    value.x = border.x
elif cursor.x > border.x + border.width:
    value.x = border.x + border.width
else:
    value.x = cursor.x

Архитектура игровых классовПравить

При написании проекта следует определить будет ли он 2D или 3D игрой. С учетом этого, следует строить архетиктуру классов проекта.

2D игры - пример архитектуры классовПравить

class Object
    # свойства
    x_position, y_position, width, height, fill_color, border_color, border_width, filled, bordered
    class Lamp(Object)
        # свойства
        energy, distance
    class Dynamic(Object)
        # свойства
        mass, radius

Здесь основные свойства объекта занесены в один класс «Object», так как их мало.

3D игры - пример архитектурыПравить

Так как 3D игры - игры с более навороченной графикой, то было бы предпочтительнее использовать такую систему классов:

class Material
    # свойства
    fill_color, border_color, border_width, filled, bordered
class Object
    # свойства
    x_position, y_position, width, height
    # ссылка на объект:
    material
    class Lamp(Object)
        # свойства
        energy, distance
    class Dynamic(Object)
        # свойства
        mass, radius

КалькуляторПравить

Пусть, наш калькулятор поддерживает выражения вида a±b, a/b и a*b. Пусть, a, b € [0; 9]. Код калькулятора будет следующий:

while True:
    text = input()
    if len(text) != 3:
        print("Длина строки не равна 3.")
    else:
        a = int(text[0])
        b = int(text[2])
        if text[1] == "+":
            print(a + b)
        elif text[1] == "-":
            print(a - b)
        elif text[1] == "/":
            print(a / b)
        elif text[1] == "*":
            print(a * b)
        else:
            print("Недопустимая операция.")

СортировкиПравить

ДискиПравить

Пусть, имеем три палки «A», «B» и «C», причем изначально все диски лежат на «A». Следует отсортировать диски по возрастанию (от верхнего к нижниму), если мы можем видеть только верхние диски.

Пока на палке «A» находится не ноль дисков:

Перекинуть верхний диск с «A» на «B».
Повторить цикл такое количество раз, которое равно n (n - количество дисков на «A»):
Если диск на «B» меньше, чем на «A», то скинуть диск с «A» на «B».
Перекинуть диск с «B» на «C».
Перекинуть такое количество дисков с «B» на «A», которое равно n - m (n - количество всех дисков на «B», а m - количество циклов, уменьшенное на единицу).
Перекинуть диск с «C» на «B».

Сортировка при помощи функций списковПравить

Самый неудачный, но возможный вариант сортировки представлен ниже:

def SortList(a):
    b = list()
    for i in range(0, len(a)):
        m = a.min(a)
        b.append(m)
        a.remove(m)
    return b

Недостатки:

  1. Используется два списка.
  2. Слишком много используется встроенных функций.
  3. Медленная сортировка.

Использование встроенных в Python функций не гарантирует быструю скорость работы алгоритма.

Сортировка пузырькомПравить

  1. Проходим по списку несколько раз, чтобы правильно отсортировать все элементы в правильном порядке. Не всегда после n-ной итерации все элементы списка будут отсортированы.
  2. Сначала мы ищем минимальный элемент во всем списке, потом - в его оставшейся части.
def SortList(a):
    for i in range(0, len(a)):
        for j in range(len(a) - 1, i, -1):
            if a[j] < a[j-1]:
                a[j], a[j - 1] = a[j - 1], a[j]
    return a
def SortList(a):
    for i in range(len(a) - 1, -1):
        for j in range(0, i):
            if a[j] < a[j + 1]:
                a[j], a[j + 1] = a[j + 1], a[j]
    return a

 

Сортировка выборомПравить

 

def SortList(a):
    for i in range(0, len(a)):
        for j in range(i + 1, len(a)):
            if a[i] > a[j]:
                a[i], a[j] = a[j], a[i]
    return a
  1. Переменные i и j изменяются в одном направлении - увеличиваются.
  2. Сравнивая с все элементы списка, стоящие после a[i], с a[i], мы находим минимум из множества значений (a[i], a[len(a)-1]]. При следующей итерации новый минимум будет искаться из оставшихся элементов, поэтому следующий минимум будет больше предыдущего минимума.

Сортировка вставкамиПравить

Отличается от сортировки пузырьком тем, что:

  1. Переменные i и j изменяются в разных направлениях.
  2. Осуществляем меньше итераций, чем в сортировке пузырьком, так как мы не проходим уже отсортированные пары элементов, поскольку отсортировали их на более ранних итерациях цикла for.
def SortList(a):
    for i in range(1, len(a)):
        j = i
        while (j > 0) and (a[j] < a[j - 1]):
            a[i], a[j] = a[j], a[i]
            j -= 1
    return a
  1. В «range(1, len(a))» первым элементом множества значений установил 1, чтобы не проверять лишний раз условие «while j > 0 and a[j] < a[j - 1]».
  2. Условие «j > 0» требуется для того, чтобы предотвратить выход j - 1 за границы списка.

Алгоритм создания множествПравить

def NewSet(a):
    for i in range(0, len(a)):
        j = i + 1
        while j < len(a):
            if a[j] == a[i]:
                a.remove(a[j])
            else:
                j += 1
    return a

Пусть, мы должны сравнивать все элементы списка с a[j]. Из этого следует то, что не все элементы со значением a[j] были удалены. Но это противоречит тому, что написано в теле цикла:

while j < len(a):
    if a[j] == a[i]:
        a.remove(a[j])
    else:
        j += 1

Таким образом, мы должны сравнивать все элементы с a[i], стоящие после a[i].

Другие алгоритмыПравить

Разделение строки по символамПравить

sym = []
sym.append(' ')
sym.append(';')
words = []
wI = 0
s = input()
i = 0
while i < len(s):
    while (i < len(s)) and (s[i] in sym):
        i += 1
    while (i < len(s)) and not (s[i] in sym):
        sym[wI] = sym[wI] + s[i]
        i += 1
    wI += 1

Алгоритм нахождения НОКПравить

НОК - наибольший общий делитель чисел M и N.

  1. def NOK(a, b):
        while a != 0 and b != 0:
            if a > b:
                a = a % b
            else:
                b = b % a
        return a + b
    
    Выводим сумму, так не знаем в какой переменной именно хранится НОК. Значение одной из двух переменных после последней итерации будет равно 0.
  2. Ниже используется правило «Если M>N, то НОД(М, N) = НОД(М - N, N)». Докажем правило. Пусть, K - один из общих делителей двух чисел, а m и n - числа, на которые умножается K, то M = mK, N = nK. Следовательно:
    1. M - N = mK - nK
    2. M - N = K(m - n)
    def NOK(a, b):
        while a != b:
            if a > b:
                a = a - b
            else:
                b = b - a
        return a
    
    Выводим a, так как a == b после последней итерации цикла.

Выборка элементовПравить

Пусть, a - список, состоящий из чисел. Следует выбрать только те числа, которые лежат в диапазонах: [1; 10], [21; 30] и т. д. Количество интервалов определяется переменной inters.

def Get(a, inters):
    for i in range(len(a)):
        for j in range(i + 1, len(a)):
            if a[j - 1] > a[j]:
                a[j], a[j - 1] = a[j - 1], a[j]
    
    i = 1
    count = 0
    while i <= inters*20:
        j = 0
        while (j < len(a)) and (a[j] <= i + 9):
            if (a[j] >= i) and (a[j] <= i + 9):
                count += 1
            j += 1
        i += 20
    return count

Сортируем список для того, чтобы не выполнять во второй группе циклов лишние итерации.

Удаление элементовПравить

Пусть, есть список a, из которого надо удалить n элементов, начиная с i-ого элемента. Код удаления элементов будет следующий:

def Delete(a, i, n):
    b = []
    
    for i2 in range(0, len(a)):
        b.append(a[i2])
    
    for i2 in range(i, len(b) - n):
        b[i2] = b[i2 + n]
    
    return ''.join(b)[:len(b) - n:]

Сортировка по алфавитуПравить

Пусть, a - список, который следует отсортировать по алфавиту. Алгоритм:

  1. Создать список, определяющий номер каждой первой буквы каждой строки в алфавите.
  2. Отсортировать два списка.
def SortList(a):
    alph = 'abcdefgijklmnopqrstuvwxyz'
    b = []
    for s in a:
        i = 0
        while s[0].lower() != alph[i]:
            i += 1
        b.append(i)
    
    for i in range(0, len(a)):
        for j in range(i + 1, len(a)):
            if b[i] > b[j]:
                b[i], b[j] = b[j], b[i]
                a[i], a[j] = a[j], a[i]
    return a

Вариант с кэшированием уже найденных символов:

def SortList(a):
    alph = 'abcdefgijklmnopqrstuvwxyz'
    K = {}
    b = []
    
    for s in a:
        i = 0
        try:
            b.append(K[s[0]])
        except KeyError:
            while s[0].lower() != alph[i]:
                i += 1
            K[s[0]] = alph[i]
            b.append(i)
    
    for i in range(0, len(a)):
        for j in range(i + 1, len(a)):
            if b[i] > b[j]:
                b[i], b[j] = b[j], b[i]
                a[i], a[j] = a[j], a[i]
    return a

Сортировка словаряПравить

Сам словарь отсортировать невозможно напрямую.

def SortList(d):
    a = d.keys()
    alph = 'abcdefgijklmnopqrstuvwxyz'
    b = []
    for s in a:
        i = 0
        while s[0].lower() != alph[i]:
            i += 1
        b.append(i)
    
    for i in range(0, len(a)):
        for j in range(i + 1, len(a)):
            if b[i] > b[j]:
                b[i], b[j] = b[j], b[i]
                a[i], a[j] = a[j], a[i]
    return a

Поиск подстрокиПравить

def Find(Str, substr):
    k = 0 # Количество равных символов.
    if (len(Str) > len(substr)) and (len(substr) != 0):
        for i in range(0, len(Str) - len(substr) + 1):
            if k != len(substr):
                for j in range(0, len(substr)):
                    if substr[j] != Str[j + i]:
                        break
                    else:
                        k += 1
                if k == len(substr):
                    return i
                else:
                    k = 0
        return -1
    else:
        return -1

Поиск подстроки по шаблонуПравить

Для каждого символа строки Str мы задаем список допустимых для него значений.

def Find(Str, patternL):
    k = 0 # Количество равных символов.
    if (len(Str) > len(patternL)) and (len(patternL) != 0):
        for i in range(0, len(Str) - len(patternL) + 1):
            if k != len(patternL):
                for j in range(0, len(patternL)):
                    if not Str[j + i] in patternL[j]:
                        break
                    else:
                        k += 1
                if k == len(patternL):
                    return i
                else:
                    k = 0
        return -1
    else:
        return -1

Пример использования:

Find('a1b324a2b124',[['a', 'b'], ['1']])

Удаление подстрокиПравить

  1. В условии «(len(Str) > len(substr)) and (len(substr) != 0)» не пишем «and (len(Str) != 0)», так как часть условия «len(Str) > len(substr)» исключает это условие.
  2. i меняется от 0 до суммы разности длин строк и единицы, так как последнее значение в функции «range(0, len(Str) - len(substr) + 1)» не включается.
def DeleteSubstr(Str, substr):
    k = 0 # Количество равных символов.
    if (len(Str) > len(substr)) and (len(substr) != 0):
        for i in range(0, len(Str) - len(substr) + 1):
            if k != len(substr):
                for j in range(0, len(substr)):
                    if substr[j] != Str[j + i]:
                        break
                    else:
                        k += 1
                if k == len(substr):
                    b = []
                    
                    for i2 in range(0, len(Str)):
                        b.append(Str[i2])
                    
                    for i2 in range(i, len(Str) - len(substr)):
                        b[i2] = b[i2 + len(substr)]
                    
                    return ''.join(b)[:len(b) - len(substr):]
                else:
                    k = 0
        return -1
    else:
        return -1
def DeleteSubstrs(Str, substr):
    k = 0 # Количество равных символов.
    if (len(Str) > len(substr)) and (len(substr) != 0):
        for i in range(0, len(Str) - len(substr) + 1):
            if k != len(substr):
                for j in range(0, len(substr)):
                    if substr[j] != Str[j + i]:
                        break
                    else:
                        k += 1
                if k == len(substr):
                    b = []
                    
                    for i2 in range(0, len(Str)):
                        b.append(Str[i2])
                    
                    for i2 in range(i, len(Str) - len(substr)):
                        b[i2] = b[i2 + len(substr)]
                    
                    Str = ''.join(b)[:len(b) - len(substr):]
                else:
                    k = 0
        return Str
    else:
        return -1
def DeleteSubstrs(Str, substr):
    s = Str
    while DeleteSubstr(s, substr) != -1:
        s = DeleteSubstr(s, substr)
    return s

Поиск корняПравить

Нахождение квадратного корня:

import math
def Sqrt(x):
    a = 0.5*x
    if 
    while math.floor(a**2) != x:
        if a**2 > x:
            a = a*0.5
        elif a**2 < x:
            a = a*1.5
    return a

Нахождение корня n-ной степени:

import math
def Sqrt(x, n):
    a = 0.5*x
    while math.floor(a**n) != x:
        if a**n > x:
            a = a*0.5
        elif a**n < x:
            a = a*1.5
    return a

Четность и нечетность элемента в спискеПравить

Индекс, с которого начинается отсчет Формула для нечетных элементов Формула для четных элементов
четный индекс % 2 == 0 индекс % 2 != 0
нечетный индекс % 2 != 0 индекс % 2 == 0
  1. Если считать от четного индекса, то у нечетных элементов будут четные индексы, а у четных - нечетные.
  2. Если считать от нечетного индекса, то у нечетных элементов будут нечетные индексы, а у четных - четные.