Blender для начинающих/Python практика
![]()
Содержание コンテンツ
Blender 2.77 - теория 이론
Blender 2.77 - практика 实践
Blender 2.49 - теория 이론
Старый Blender Содержит информацию о Blender 2.49. После прочтения данной части книги Вы сможете назвать основные плюсы и минусы Blender 2.49. Blender 2.77 & 3DsMax 이론
Blender & 3DsMax Сравнение Blender, 3DsMax, Sweet Home и Art Of Illusion. После прочтения этой главы Вы будете немного знать о различиях этих программ. Программирование 이론
Дополнительное 이론
Постобработка изображений
Музыкальное сопровождение
Одни из главных классов Python: bpy.ops | bpy.data | bpy.types.ID
|
Ссылки на материалы |
---|
|
Возможно, Вас заинтересует следующее: |
О Blender 2.76 ![]() |
Скачать Blender 2.76 ![]() |
Алгебраические задачиПравить
Перестановка значений переменныхПравить
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.
- Если неравенство нестрогое, то после цикла a = a + inc*(abs(B - a) // inc + 1).
- Если неравенство строгое, то рассматриваются два случая:
- Если B % inc != 0, то a = a + inc*(abs(B - a) // inc + 1).
- Если 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)
Вычисление координат точки пересечения прямыхПравить
Пусть, прямые задаются такими уравнениями:
- y1 = k1*x + b1
- y2 = k2*x + b2
Приравняв их, получим: k1*x + b1 = k2*x + b2.
- k1*x - k2*x = b2 - b1
- 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):
- A.x - X координата точки
- A.y - Y координата точки
- button.x - X координата левого верхнего угла прямоугольника
- button.y - Y координата левого верхнего угла прямоугольника
- button.width - ширина прямоугольника
- 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
Недостатки:
- Используется два списка.
- Слишком много используется встроенных функций.
- Медленная сортировка.
Использование встроенных в Python функций не гарантирует быструю скорость работы алгоритма.
Сортировка пузырькомПравить
- Проходим по списку несколько раз, чтобы правильно отсортировать все элементы в правильном порядке. Не всегда после n-ной итерации все элементы списка будут отсортированы.
- Сначала мы ищем минимальный элемент во всем списке, потом - в его оставшейся части.
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
- Переменные i и j изменяются в одном направлении - увеличиваются.
- Сравнивая с все элементы списка, стоящие после a[i], с a[i], мы находим минимум из множества значений (a[i], a[len(a)-1]]. При следующей итерации новый минимум будет искаться из оставшихся элементов, поэтому следующий минимум будет больше предыдущего минимума.
Сортировка вставкамиПравить
Отличается от сортировки пузырьком тем, что:
- Переменные i и j изменяются в разных направлениях.
- Осуществляем меньше итераций, чем в сортировке пузырьком, так как мы не проходим уже отсортированные пары элементов, поскольку отсортировали их на более ранних итерациях цикла 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
- В «range(1, len(a))» первым элементом множества значений установил 1, чтобы не проверять лишний раз условие «while j > 0 and a[j] < a[j - 1]».
- Условие «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.
- Выводим сумму, так не знаем в какой переменной именно хранится НОК. Значение одной из двух переменных после последней итерации будет равно 0.
def NOK(a, b): while a != 0 and b != 0: if a > b: a = a % b else: b = b % a return a + b
- Ниже используется правило «Если M>N, то НОД(М, N) = НОД(М - N, N)». Докажем правило. Пусть, K - один из общих делителей двух чисел, а m и n - числа, на которые умножается K, то M = mK, N = nK. Следовательно:
- M - N = mK - nK
- M - N = K(m - n)
Выводим a, так как a == b после последней итерации цикла.def NOK(a, b): while a != b: if a > b: a = a - b else: b = b - a return a
Выборка элементовПравить
Пусть, 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 - список, который следует отсортировать по алфавиту. Алгоритм:
- Создать список, определяющий номер каждой первой буквы каждой строки в алфавите.
- Отсортировать два списка.
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']])
Удаление подстрокиПравить
- В условии «(len(Str) > len(substr)) and (len(substr) != 0)» не пишем «and (len(Str) != 0)», так как часть условия «len(Str) > len(substr)» исключает это условие.
- 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 |
- Если считать от четного индекса, то у нечетных элементов будут четные индексы, а у четных - нечетные.
- Если считать от нечетного индекса, то у нечетных элементов будут нечетные индексы, а у четных - четные.