Game AI & Unity/L-system algorithm
[Plants and Python][prac8] 함수와 프랙탈 2
bay07
2024. 3. 29. 10:11
#4 transform_sequence
#4
def transform_sequence(sequence, transformations):
return ''.join(transformations.get(c, c) for c in sequence)
transform_sequence(sequence, transformations) | 주어진 시퀀스를 규칙에 따라 변환한다 sequence: 변환될 시퀀스 transformations: 변환 규칙을 포함하는 딕셔너리 |
transformations.get(c, c) |
시퀀스의 문자 c에 대해 변환 사전에서 해당 문자의 변환을 찾는다 만약 변환이 없으면 원래 문자 c를 반환한다 |
for c in sequence | 시퀀스의 각 문자에 대해 반복한다 |
join() | 변환된 문자들을 이어붙여서 하나의 문자열로 만든다 |
#5 transform_multiple
#5
def transform_multiple(sequence, transformations, iterations):
for _ in range(iterations):
sequence = transform_sequence(sequence, transformations)
return sequence
transform_multiple(sequence, transformations, iterations) | 주어진 시퀀스를 지정된 횟수만큼 변환하고 최종 변환된 시퀀스를 반환한다 이전에 정의한 transform_sequence 함수를 사용하여 여러 번의 반복(iterations)을 수행하는 함수 sequence : 변환될 시퀀스 transformations : 변환 규칙을 포함하는 딕셔너리 iterations : 변환을 반복할 횟수 |
for _ in range(iterations) | 반복 |
transform_sequence(sequence, transformations) | transform_sequence 함수를 사용하여 시퀀스에 변환을 적용한다. 즉, 시퀀스의 각 문자에 대해 지정된 변환을 적용하여 새로운 시퀀스를 생성한다. |
return sequence | 변환된 시퀀스를 반환한다. |
#7 l_plot
#7
def l_plot(axiom, transformations, iterations=0, angle=45, lw=0.5):
turtle_program = transform_multiple(axiom, transformations, iterations)
coords = branching_turtle_to_coords(turtle_program, angle)
plot_coords(coords, lw=lw, bare_plot=True)
def l_plot(axiom, transformations, iterations=0, angle=45, lw=0.5) | 주어진 L-시스템의 초기 axiom에 대해 변환(transformations)을 적용한다. 이 후 해당 시스템을 거북이 그래픽으로 출력한다. axiom : L-시스템의 초기 값 transformations iterations : 반복 횟수 angle : 각도 lw : 선의 굵기 |
turtle_program = transform_multiple(axiom, transformations, iterations) | 주어진 axiom을 transform_multiple 함수를 사용하여 변환한다. 지정된 반복 횟수만큼. 이렇게 변환된 시퀀스가 거북이 프로그램을 표현한다. |
coords = branching_turtle_to_coords(turtle_program, angle) | 변환된 시퀀스를 거북이 프로그램으로 해석하여 좌표를 생성한다. |
branching_turtle_to_coords(turtle_program, angle) | 거북이 그래픽을 생성하는 데 필요한 좌표를 얻을 수 있는 함수 |
plot_coords(coords, lw=lw, bare_plot=True) | 생성된 좌표를 사용하여 거북이 그래픽을 플로팅함 lw : 선의 굵기 bare_plot : 그래픽 영역의 경계 관련 |
▷ data code 1
더보기
axiom = 'F-F-F-F'
production_rules = {'F':'F+FF-FF-F-F+F+FF-F-F+F+FF+FF-F'}
iterations = 2
angle = 90
axiom = '-F'
production_rules = {'F':'F+F-F-F+F'}
iterations = 4
angle = 90
axiom = 'F+F+F+F'
production_rules = {'F':'F+f-FF+F+FF+Ff+FF-f+FF-F-FF-Ff-FFF', 'f':'ffffff'}
iterations = 2
angle = 90
axiom = 'F-F-F-F'
production_rules = {'F':'FF-F-F-F-F-F+F'}
iterations = 4
angle = 90
axiom = 'F-F-F-F'
production_rules = {'F':'FF-F-F-F-FF'}
iterations = 4
angle = 90
axiom = 'F-F-F-F'
production_rules = {'F':'FF-F+F-F-FF'}
iterations = 3
angle = 90
axiom = 'F-F-F-F'
production_rules = {'F':'FF-F--F-F'}
iterations = 4
angle = 90
axiom = 'F-F-F-F'
production_rules = {'F':'F-FF--F-F'}
iterations = 5
angle = 90
axiom = 'F-F-F-F'
production_rules = {'F':'F-F+F-F-F'}
iterations = 4
angle = 90
▷ data code 2
더보기
axiom = 'L'
production_rules = {'L':'L+R+', 'R':'-L-R'}
iterations = 10
angle = 90
axiom = 'R'
production_rules = {'L':'R+L+R', 'R':'L-R-L'}
iterations = 6
angle = 60
axiom = 'L'
production_rules = {'L':'L+R++R-L--LL-R+', 'R':'-L+RR++R+L--L-R'}
iterations = 4
angle = 60
axiom = '-R'
production_rules = {'L':'LL-R-R+L+L-R-RL+R+LLR-L+R+LL+R-LR-R-L+L+RR-',
'R':'+LL-R-R+L+LR+L-RR-L-R+LRR-L-RL+L+R-R-L+L+RR'}
iterations = 2
angle = 90
▷ 전체 코드
더보기
import matplotlib.pyplot as plt
%matplotlib inline
nan = float('nan')
#1
def plot_coords(coords, lw=0.5, bare_plot=True):
if bare_plot:
# Turns off the axis markers.
plt.axis('off')
# Ensures equal aspect ratio.
plt.axes().set_aspect('equal', 'datalim')
# Converts a list of coordinates into
# lists of X and Y values, respectively.
X, Y = zip(*coords)
# Draws the plot.
plt.plot(X, Y, lw=lw, c='k')
#2
from math import pi, sin, cos
DEGREES_TO_RADIANS = pi / 180
def turtle_to_coords(turtle_program, turn_amount=45):
# The state variable tracks the current location and angle of the turtle.
# The turtle starts at (0, 0) facing up (90 degrees).
state = (0.0, 0.0, 90.0)
# Throughout the turtle's journey, we "yield" its location. These coordinate
# pairs become the path that plot_coords draws.
yield (0.0, 0.0)
# Loop over the program, one character at a time.
for command in turtle_program:
x, y, angle = state
# Move turtle forward
if command in 'Ff':
state = (x - cos(angle * DEGREES_TO_RADIANS),
y + sin(angle * DEGREES_TO_RADIANS),
angle)
if command == 'f':
# Insert a break in the path so that
# this line segment isn't drawn.
yield (float('nan'), float('nan'))
yield (state[0], state[1])
# Turn turtle clockwise without moving
elif command == '+':
state = (x, y, angle + turn_amount)
# Turn turtle counter-clockwise without moving
elif command == '-':
state = (x, y, angle - turn_amount)
# Note: We silently ignore unknown commands
#3
from math import isnan
def print_coords(coords):
for (x, y) in coords:
if isnan(x):
print('<gap>')
else:
print('({:.2f}, {:.2f})'.format(x, y))
#4
def transform_sequence(sequence, transformations):
return ''.join(transformations.get(c, c) for c in sequence)
#5
def transform_multiple(sequence, transformations, iterations):
for _ in range(iterations):
sequence = transform_sequence(sequence, transformations)
return sequence
#6
def branching_turtle_to_coords(turtle_program, turn_amount=45):
saved_states = list()
state = (0, 0, 90)
yield (0, 0)
for command in turtle_program:
x, y, angle = state
# Move forward (matches a-j and A-J)
if command.lower() in 'abcdefghijklmnopqrstuvwxyz':
state = (x - cos(angle * DEGREES_TO_RADIANS),
y + sin(angle * DEGREES_TO_RADIANS),
angle)
# Add a break in the line if command matches a-j
if command.islower():
yield (float('nan'), float('nan'))
yield (state[0], state[1])
# Turn clockwise
elif command == '+':
state = (x, y, angle + turn_amount)
# Turn counterclockwise
elif command == '-':
state = (x, y, angle - turn_amount)
# Remember current state
elif command == '[':
saved_states.append(state)
# Return to previous state
elif command == ']':
state = saved_states.pop()
yield (float('nan'), float('nan'))
x, y, _ = state
yield (x, y)
# Note: We silently ignore unknown commands
#7
def l_plot(axiom, transformations, iterations=0, angle=45, lw=0.5):
turtle_program = transform_multiple(axiom, transformations, iterations)
coords = branching_turtle_to_coords(turtle_program, angle)
plot_coords(coords, lw=lw, bare_plot=True)
# 예시
axiom = 'F-F-F-F'
production_rules = {'F':'F+FF-FF-F-F+F+FF-F-F+F+FF+FF-F'}
iterations = 2
angle = 90
# 함수 불러오기
# Plot the L-system fractal
l_plot(axiom, production_rules, iterations, angle)
* 참고
https://nbviewer.org/github/DanChitwood/PlantsAndPython/blob/master/PlantsAndPython6_STUDENT_Functions_and_Fractals.ipynb
https://nbviewer.org/github/DanChitwood/PlantsAndPython/tree/master/