Ejemplo n.º 1
0
def hsv_to_rgb(h, s, v):
    # h: hue: 0 to 360
    # s: saturation: 0 to 1
    # v: value: 0 to 1
    def f(n):
        k = (n + (h / 60)) % 6
        return v - (v * s * max(0, min(k, 4 - k, 1)))

    r, g, b = int(f(5) * 255), int(f(3) * 255), int(f(1) * 255)
    r, g, b = base_repr(r, base=16).zfill(2), base_repr(
        g, base=16).zfill(2), base_repr(b, base=16).zfill(2)
    return "#" + r + g + b
Ejemplo n.º 2
0
    def get_ifs(self):
        transformations = []
        prob_numerators = []
        prob_denominators = []

        for row in self.transformation_entries:
            try:
                a, b, c, d, e, f, p_num, p_den = list(
                    map(lambda entry: float(entry.get()), row))
            except ValueError:
                error_message(
                    "There was an error in parsing the IFS code input.")
                return

            transformations.append(AffineTransformation(a, b, c, d, e, f))
            prob_numerators.append(int(p_num))
            prob_denominators.append(int(p_den))

        return IteratedFunctionSystem(
            transformations), prob_numerators, prob_denominators
Ejemplo n.º 3
0
def go_button_pressed():
    user_input = transformations_frame.get_ifs()

    if user_input is None:
        return

    ifs, prob_numerators, prob_denominators = transformations_frame.get_ifs()

    gen_op = generator_var.get()

    if gen_op == "Pseudo-random number generator":
        if use_bias_var.get() == 0:
            probs = [1.0 / ifs.size] * ifs.size
        else:
            probs = [r / s for r, s in zip(prob_numerators, prob_denominators)]
        gen = example_generators.get_random_generator(ifs.size, probs)
    elif use_bias_var.get() == 0:
        gen = dict(example_generators.all_generators)[gen_op](ifs.size)
    elif lcm(prob_denominators) > len(digits):
        error_message(
            "The least common multiple of the probability denominators must not be larger than "
            + str(len(digits)) + ".")
        return
    else:
        norm_gen = dict(example_generators.all_generators)[gen_op](
            lcm(prob_denominators))
        gen = example_generators.get_biased(norm_gen, prob_numerators,
                                            prob_denominators)

    try:
        num_iters = int(num_iters_entry.get())
    except ValueError:
        error_message("Could not parse " + num_iters_entry.get() +
                      " as a number of iterations.")
        return

    img, gen_str = ifs.get_image(IMAGE_WIDTH,
                                 IMAGE_HEIGHT,
                                 num_iters,
                                 gen,
                                 colors=show_colors_var.get() == 1,
                                 first_transformations=100)

    first_transformations_label.config(state=tk.NORMAL)
    first_transformations_label.delete(0, tk.END)
    first_transformations_label.insert(0, gen_str)
    first_transformations_label.config(state=tk.DISABLED)

    fractal_label.config(image=img)
    fractal_label.image = img
Ejemplo n.º 4
0
    def num_selected(self):
        try:
            num = int(self.num_selector_entry.get())
        except ValueError as err:
            error_message("The number of transformations selected, " +
                          self.num_selector_entry.get() + ", is invalid.")
            return

        if num > len(digits):
            error_message("The number of transformations selected, " +
                          self.num_selector_entry.get() +
                          ", must not be greater than " + str(len(digits)) +
                          ".")
            return

        if num < 1:
            error_message("The number of transformations selected, " +
                          self.num_selector_entry.get() +
                          ", must not be less than 1.")
            return

        affine_val_labels = ["a", "b", "c", "d", "e", "f"]

        for w in self.affine_vals_frame.winfo_children():
            w.destroy()

        num_label = tk.Entry(self.affine_vals_frame,
                             width=8,
                             justify=tk.CENTER)
        num_label.grid(row=0, column=0)
        num_label.config(state=tk.DISABLED, disabledforeground="black")

        for col in range(len(affine_val_labels)):
            col_label = tk.Entry(self.affine_vals_frame,
                                 width=8,
                                 justify=tk.CENTER)
            col_label.grid(row=0, column=col + 1)
            col_label.insert(0, affine_val_labels[col])
            col_label.config(state=tk.DISABLED, disabledforeground="black")

        p_col_label = tk.Entry(self.affine_vals_frame,
                               width=19,
                               justify=tk.CENTER)
        p_col_label.grid(row=0,
                         column=len(affine_val_labels) + 1,
                         columnspan=3,
                         padx=(10, 0))
        p_col_label.insert(0, "p=r/s")
        p_col_label.config(state=tk.DISABLED, disabledforeground="black")

        self.transformation_entries = []

        for row in range(num):
            row_entries = []

            row_label = tk.Entry(self.affine_vals_frame,
                                 width=8,
                                 justify=tk.CENTER)
            row_label.grid(row=row + 1, column=0)
            row_label.insert(0, base_repr(row, base=num))
            row_label.config(state=tk.DISABLED, disabledforeground="black")

            for col in range(len(affine_val_labels)):
                col_entry = tk.Entry(self.affine_vals_frame,
                                     width=8,
                                     justify=tk.CENTER)
                col_entry.grid(row=row + 1, column=col + 1)

                row_entries.append(col_entry)

            p_numerator_entry = tk.Entry(self.affine_vals_frame,
                                         width=8,
                                         justify=tk.RIGHT)
            p_numerator_entry.grid(row=row + 1,
                                   column=len(affine_val_labels) + 1,
                                   padx=(10, 0))

            row_entries.append(p_numerator_entry)

            p_slash_label = tk.Label(self.affine_vals_frame, text="/")
            p_slash_label.grid(row=row + 1, column=len(affine_val_labels) + 2)

            p_denominator_entry = tk.Entry(self.affine_vals_frame,
                                           width=8,
                                           justify=tk.LEFT)
            p_denominator_entry.grid(row=row + 1,
                                     column=len(affine_val_labels) + 3)

            row_entries.append(p_denominator_entry)

            self.transformation_entries.append(row_entries)
Ejemplo n.º 5
0
    def get_image(self,
                  image_width,
                  image_height,
                  num_iters,
                  generator,
                  starting_point=Coordinate(0, 0),
                  bg_color="#000000",
                  fg_color="#00FF00",
                  colors=True,
                  first_transformations=100):
        img = PhotoImage(width=image_width, height=image_height)

        # Set background color
        img.put(bg_color, to=(0, 0, image_width, image_height))

        # Calculation of points
        all_points = [starting_point]
        all_transformations = [0]
        gen_str = ""

        current_point = starting_point

        for i in range(num_iters):
            gen_val = next(generator)
            index = int(gen_val, base=self.size)

            t = self.transformations[index]
            current_point = t.transform(current_point)

            all_points.append(current_point)
            all_transformations.append(index)
            gen_str += gen_val

        # Stretch to fit image
        min_x = min(all_points, key=lambda pt: pt.x).x
        max_x = max(all_points, key=lambda pt: pt.x).x

        min_y = min(all_points, key=lambda pt: pt.y).y
        max_y = max(all_points, key=lambda pt: pt.y).y

        fractal_width = max_x - min_x
        fractal_height = max_y - min_y

        fractal_size = max(fractal_width, fractal_height)

        drawn_points = []
        draw_colors = []

        for pt, index in zip(all_points, all_transformations):
            new_x = ((pt.x - min_x) / fractal_size) * image_width
            new_y = ((pt.y - min_y) / fractal_size) * image_height

            new_y = image_height - new_y

            drawn_points.append(Coordinate(new_x, new_y))
            draw_colors.append(hsv_to_rgb(index * 360 / self.size, 1, 1))

        # Draw points
        if colors:
            for pt, dot_color in zip(drawn_points, draw_colors):
                img.put(dot_color, (round(pt.x), round(pt.y)))
        else:
            for pt in drawn_points:
                img.put(fg_color, (round(pt.x), round(pt.y)))

        return img, gen_str[:first_transformations]