1 module rip.draw.ifs;
2 
3 private
4 {
5 	import std.random;
6 
7 	import rip.concepts.color;
8 	import rip.concepts.surface;
9 	import rip.concepts.templates;
10 	import rip.draw.primitives;
11 }
12 
13 // Одно уравнение итерируемой системы функций
14 class Equation
15 {
16 	private
17 	{
18 		float a;
19 		float b;
20 		float c;
21 		float d;
22 		float e;
23 		float f;
24 	}
25 
26 	// Коэффициент a
27 	mixin(addTypedGetter!("a", "getA"));
28 
29 	// Коэффициент b
30 	mixin(addTypedGetter!("b", "getB"));
31 
32 	// Коэффициент c
33 	mixin(addTypedGetter!("c", "getC"));
34 
35 	// Коэффициент d
36 	mixin(addTypedGetter!("d", "getD"));
37 
38 	// Коэффициент e
39 	mixin(addTypedGetter!("e", "getE"));
40 
41 	// Коэффициент f
42 	mixin(addTypedGetter!("e", "getF"));
43 
44 	// Установить коэффициент a
45 	void setA(T)(T a)
46 		if (allArithmetic!T)
47 	{
48 		this.a = cast(float) a;
49 	}
50 
51 	// Установить коэффициент b
52 	void setB(T)(T b)
53 		if (allArithmetic!T)
54 	{
55 		this.b = cast(float) b;
56 	}
57 
58 	// Установить коэффициент c
59 	void setC(T)(T c)
60 		if (allArithmetic!T)
61 	{
62 		this.c = cast(float) c;
63 	}
64 
65 	// Установить коэффициент d
66 	void setD(T)(T d)
67 		if (allArithmetic!T)
68 	{
69 		this.d = cast(float) d;
70 	}
71 
72 	// Установить коэффициент e
73 	void setE(T)(T e)
74 		if (allArithmetic!T)
75 	{
76 		this.e = cast(float) e;
77 	}
78 
79 	// Установить коэффициент f
80 	void setF(T)(T f)
81 		if (allArithmetic!T)
82 	{
83 		this.f = cast(float) f;
84 	}
85 }
86 
87 // Представление системы уравнений в виде ассоциативного массива 
88 // (в роли ключа - вероятность применения уравнения, в ролди значения - одно уравнение системы)
89 template EquationSystem(T)
90 	if (allArithmetic!T)
91 {
92 	alias EquationSystem = Equation[T];
93 }
94 
95 // Класс для итерируемой системы функций 
96 class IFS(T)
97 {
98 	private
99 	{
100 		Surface surface;
101 		RGBColor color;
102 		EquationSystem!T equationSystem;
103 		ulong numberOfGeneration;
104 
105 		float x;
106 		float y;
107 	}
108 
109 	// Универсальный конструктор класса
110 	this(U, V, W)(Surface surface, RGBColor color, EquationSystem!T equationSystem, 
111 		U x, V y, W numberOfGeneration)
112 		if (allArithmetic!(T, U, V, W))
113 	{
114 		this.surface = surface;
115 		this.color = color;
116 		this.equationSystem = equationSystem;
117 		this.numberOfGeneration = cast(ulong) numberOfGeneration;
118 
119 		this.x = cast(float) x;
120 		this.y = cast(float) y;
121 	}
122 
123 	// Выполнить команды рисования итерируемой системы функций
124 	EquationSystem!T execute()
125 	{
126 		for (ulong i = 0; i < numberOfGeneration; i++)
127 		{
128 			drawPoint(surface, color, x, y);
129 
130 			auto d = dice(equationSystem.keys);
131 			Equation eq = equationSystem[d];
132 
133 			auto mul0 = eq.getA!float * x + eq.getB!float * y;
134 			auto mul1 = eq.getC!float * x + eq.getD!float * y;
135 
136 			x = mul0 + eq.getE!float;
137 			y = mul1 + eq.getF!float;
138 		}
139 		
140 		return equationSystem;
141 	}
142 }