Skip to content

Commit

Permalink
Reset iterations when reloading config
Browse files Browse the repository at this point in the history
 - Reset the iterations being rendered when loading a new config. It was
   kind of ridiculous to render a potentially unknown config at whatever
   the previous number of iterations was.

 - Added a quick script that generates a random l-system config. Mostly
   just looks like a twisted strand of hair, but that doesn't mean it
   isn't interesting.
  • Loading branch information
yalue committed Jun 7, 2022
1 parent 6113ba1 commit 98bf5b6
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 8 deletions.
107 changes: 107 additions & 0 deletions generate_l_system.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
symbols = ['S']

# Generates a replacement rule. Returns ["rule string", [new used_symbols]]
def random_replacement_rule(all_symbols, used_symbols, rule_symbols)
# We can't redefine rule symbols.
return ["", used_symbols, rule_symbols] if used_symbols.length == rule_symbols.length
start = used_symbols.sample()
start = used_symbols.sample() while rule_symbols.include?(start)
rule_symbols << start
replacement_size = [2, 3, 3, 3, 4, 5].sample()
replacement = ""
replacement_size.times do
# Only choose a new symbol 1/3rd of the time. (Tehcnically less, since all
# symbols will include the used ones.
if (used_symbols.length < 3) || (rand() < 0.3)
symbol = all_symbols.sample()
used_symbols << symbol if !used_symbols.include?(symbol)
else
symbol = used_symbols.sample()
end
if rand() < 0.01
# 1% of the time do a push & pop
replacement += "(" + symbol + ")"
else
replacement += symbol
end
end
rule_string = start + " " + replacement
[rule_string, used_symbols, rule_symbols]
end

def get_move_action()
"move_forward %.03f" % [rand()]
end

def get_rotate_action()
action = ["rotate", "pitch", "roll"].sample()
angle = 180.0 - (360.0 * rand())
"%s %.03f" % [action, angle]
end

def get_setcolor_action()
channel = ["r", "g", "b"].sample()
"set_color_%s %.03f" % [channel, rand()]
end

# Returns an array of random action strings, NOT including push and pop.
def generate_random_actions()
moves = ["move"] * 6
rotates = ["rotate"] * 4
set_colors = ["set_color"] * 2
action_types = moves + rotates + set_colors
actions_not_move = rotates + set_colors
to_return = []
action_count = rand(8)
prev_was_move = false
action_count.times do
if prev_was_move
action_type = actions_not_move.sample()
else
action_type = action_types.sample()
end
prev_was_move = false
if action_type == "move"
prev_was_move = true
to_return << get_move_action()
elsif action_type == "rotate"
to_return << get_rotate_action()
elsif action_type == "set_color"
to_return << get_setcolor_action()
end
end
to_return
end

# Don't include the start symbol in all_symbols
all_symbols = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".chars
used_symbols = ["S"]
rule_symbols = []
puts "init S"
10.times do
tmp = random_replacement_rule(all_symbols, used_symbols, rule_symbols)
puts tmp[0]
used_symbols = tmp[1]
rule_symbols = tmp[2]
end

puts "\nactions
(
push_color 0.0
push_position 0.0
)
pop_color 0.0
pop_position 0.0
"

used_symbols.each do |s|
# Only generate actions for about 1/3rd of the symbols
next if rand() < 0.3
puts "#{s}"
actions = generate_random_actions()
actions.each {|a| puts a}
puts ""
end

26 changes: 18 additions & 8 deletions l_system_3d.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,19 @@ static int IncreaseIterations(ApplicationState *s) {
return 1;
}

// Sets the current number of iterations to 0. Used after reloading the config.
static int SetIterationsTo0(ApplicationState *s) {
free(s->l_system_string);
s->l_system_string = (uint8_t *) strdup(s->config->init);
if (!s->l_system_string) {
printf("Failed copying the initial L-system string.\n");
return 0;
}
s->l_system_length = strlen(s->config->init);
s->l_system_iterations = 0;
return 1;
}

// Reduces the L-system iterations by one. Unfortunately, this is implemented
// by recomputing the entire thing. Does nothing if we're already at 0
// iterations.
Expand All @@ -194,14 +207,7 @@ static int DecreaseIterations(ApplicationState *s) {
return 1;
}
target_iterations = s->l_system_iterations - 1;
free(s->l_system_string);
s->l_system_string = (uint8_t *) strdup(s->config->init);
if (!s->l_system_string) {
printf("Failed copying the initial L-system string.\n");
return 0;
}
s->l_system_length = strlen(s->config->init);
s->l_system_iterations = 0;
if (!SetIterationsTo0(s)) return 0;
for (i = 0; i < target_iterations; i++) {
if (!IncreaseIterations(s)) return 0;
}
Expand All @@ -222,6 +228,10 @@ static void ReloadConfig(ApplicationState *s) {
s->config = new_config;
DestroyLSystemConfig(old_config);
printf("Config %s updated OK.\n", s->config_file_path);
if (!(SetIterationsTo0(s) && GenerateVertices(s))) {
printf("Failed re-generating image.\n");
exit(1);
}
}

static void PrintMemoryUsage(ApplicationState *s) {
Expand Down

0 comments on commit 98bf5b6

Please sign in to comment.