3
\$\begingroup\$

Trying to generate fractals image with given IFS equations. I have two classes:

  • Shape - Gives co-ordinate to form a shape.
  • Ifs - Takes the given IFS equations and generates a fractal image.

Code:

ifs.py

class Shape:
    @staticmethod
    def square():
        x1 = np.concatenate(
            (
                np.linspace(0, 1, 100),
                np.ones(100),
                np.linspace(0, 1, 100),
                np.zeros(100),
            )
        )
        y1 = np.concatenate(
            (
                np.zeros(100),
                np.linspace(0, 1, 100),
                np.ones(100),
                np.linspace(0, 1, 100),
            )
        )
        return x1, y1

    @staticmethod
    def triangle():
        x1 = np.concatenate(
            (
                np.linspace(0, 1, 100),
                np.linspace(1, 0.5, 100),
                np.linspace(0.5, 0, 100),
            )
        )
        y1 = np.concatenate(
            (np.zeros(100), np.linspace(0, 1, 100), np.linspace(1, 0, 100))
        )
        return x1, y1

    @staticmethod
    def line():
        x1 = np.linspace(0, 1, 100)
        y1 = np.zeros(100)
        return x1, y1


class Ifs:
    def __init__(self):
        self._equationList = []

    def AddEquations(self, EqnLst):
        for eqn in EqnLst:
            *coef, e, f = eqn
            self._equationList.append((np.array(coef), np.array([e, f])))

    def __str__(self):
        out = ""
        for idx, (coef, intercept) in enumerate(self._equationList, 1):
            a, b, c, d = coef
            e, f = intercept
            out = (
                out
                + f"""equation = {idx}: [[a = {a} b = {b}]   [e = {e}
               [c = {c} d = {d}]]   f = {f}]\n\n"""
            )   
        return out

    def deterministic(self, shape=Shape.square(), iterations=6):
        arr = np.column_stack(shape)
        for i in range(iterations):
            allEquations = []
            for coef, intercept in self._equationList:
                coef_ = coef.reshape(-1, 2)
                transformed_arr = (coef_ * arr[:, None]).sum(
                    axis=2
                ) + intercept[None, :]
                allEquations.append(transformed_arr)
            arr = np.vstack(allEquations)
        self.Values = arr
        return arr

    def plot(self):
        x, y = zip(*self.Values)
        plt.scatter(x, y, 1)
        plt.show()

Sample run: I have given equations of Sierpinski Gasket

  • python3 ifs.py for what it's worth, this is how I run my code.
i = Ifs()

# There are 6 values in each equation a, b, c, d, e and f.
# where [a, b, c, d] is called coef
#[e, f] is called intercept

lst = [
       [ 0.5, 0, 0, 0.5, 0, 0],
       [0.5, 0, 0, 0.5, 0.5, 0],
       [0.5, 0, 0, 0.5, 0, 0.5]
      ]
       
i.AddEquations(lst)
i.deterministic(Shape.triangle())
i.plot()
print(i)

Output to console:

equation = 1: [[a = 0.5 b = 0.0]   [e = 0
               [c = 0.0 d = 0.5]]   f = 0]

equation = 2: [[a = 0.5 b = 0.0]   [e = 0.5
               [c = 0.0 d = 0.5]]   f = 0.0]

equation = 3: [[a = 0.5 b = 0.0]   [e = 0.0
               [c = 0.0 d = 0.5]]   f = 0.5]

Image of fractal generated:

enter image description here


I feel there's a lot of room to improve this code. I looking for suggestions to improve the Ifs class be it a way of storing equations or improving deterministic function. Shape is written by another user I might not have the power to change it but I can put forward your valuable suggestions to the author.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.