1 package org.woehlke.computer.kurzweil.mandelbrot.model.fractal;
2
3 import org.woehlke.computer.kurzweil.mandelbrot.model.ApplicationModel;
4 import org.woehlke.computer.kurzweil.mandelbrot.model.helper.Point;
5
6 import java.util.ArrayDeque;
7 import java.util.Deque;
8
9
10
11
12
13
14
15
16
17
18
19 public class GaussianNumberPlane {
20
21 private volatile int[][] lattice;
22
23 private volatile ComplexNumber complexNumberForJuliaSetC;
24
25 private final Point worldDimensions;
26
27 public final static int YET_UNCOMPUTED = -1;
28
29 private final static double complexWorldDimensionRealX = 3.2d;
30 private final static double complexWorldDimensionImgY = 2.34d;
31 private final static double complexCenterForMandelbrotRealX = -2.2f;
32 private final static double complexCenterForMandelbrotImgY = -1.17f;
33 private final static double complexCenterForJuliaRealX = -1.6d;
34 private final static double complexCenterForJuliaImgY = -1.17d;
35
36 private volatile ComplexNumber complexWorldDimensions;
37 private volatile ComplexNumber complexCenterForMandelbrot;
38 private volatile ComplexNumber complexCenterForJulia;
39
40 public volatile int zoomLevel;
41
42 private volatile Deque<ComplexNumber> complexCenterForZoomedMandelbrot = new ArrayDeque<>();
43
44 private volatile ComplexNumber zoomCenter;
45
46
47
48
49 public GaussianNumberPlane(ApplicationModel model) {
50 this.worldDimensions = model.getWorldDimensions();
51 this.lattice = new int[worldDimensions.getWidth()][worldDimensions.getHeight()];
52 this.complexWorldDimensions = new ComplexNumber(
53 complexWorldDimensionRealX,
54 complexWorldDimensionImgY
55 );
56 this.complexCenterForMandelbrot = new ComplexNumber(
57 complexCenterForMandelbrotRealX,
58 complexCenterForMandelbrotImgY
59 );
60 this.complexCenterForJulia = new ComplexNumber(
61 complexCenterForJuliaRealX,
62 complexCenterForJuliaImgY
63 );
64 start();
65 }
66
67 public void setModeZoom() {
68 this.setZoomLevel(1);
69 this.setZoomCenter(complexCenterForMandelbrot);
70 }
71
72 public synchronized void start(){
73 zoomLevel = 1;
74 for(int y = 0;y < this.worldDimensions.getY(); y++){
75 for(int x=0; x < worldDimensions.getX(); x++){
76 lattice[x][y] = YET_UNCOMPUTED;
77 }
78 }
79 }
80
81 public synchronized int getCellStatusFor(int x,int y){
82 return (lattice[x][y])<0?0:lattice[x][y];
83 }
84
85 private synchronized ComplexNumber getComplexNumberFromLatticeCoordsForJulia(Point turingPosition) {
86 double realX = complexCenterForJulia.getReal()
87 + (complexWorldDimensions.getReal()*turingPosition.getX())/worldDimensions.getX();
88 double imgY = complexCenterForJulia.getImg()
89 + (complexWorldDimensions.getImg()*turingPosition.getY())/worldDimensions.getY();
90 return new ComplexNumber(realX,imgY);
91 }
92
93 private synchronized ComplexNumber getComplexNumberFromLatticeCoordsForMandelbrot(Point turingPosition) {
94 double realX = (
95 complexCenterForMandelbrot.getReal()
96 + ( complexWorldDimensions.getReal() * turingPosition.getX() )
97 / worldDimensions.getX()
98 );
99 double imgY = (
100 complexCenterForMandelbrot.getImg()
101 + ( complexWorldDimensions.getImg() * turingPosition.getY() )
102 / worldDimensions.getY()
103 );
104 return new ComplexNumber(realX,imgY);
105 }
106
107 private synchronized ComplexNumber getComplexNumberFromLatticeCoordsForZoomedMandelbrot(Point turingPosition) {
108 double realX = (
109 ( complexCenterForMandelbrot.getReal() / this.getZoomLevel() )
110 + getZoomCenter().getReal()
111 + ( complexWorldDimensions.getReal() * turingPosition.getX() )
112 / ( worldDimensions.getX() * this.getZoomLevel() )
113 );
114 double imgY = (
115 ( complexCenterForMandelbrot.getImg() / this.getZoomLevel() )
116 + getZoomCenter().getImg()
117 + ( complexWorldDimensions.getImg() * turingPosition.getY() )
118 / ( worldDimensions.getY() * this.getZoomLevel() )
119 );
120 return new ComplexNumber(realX,imgY);
121 }
122
123 public synchronized boolean isInZooomedMandelbrotSet(Point turingPosition) {
124 ComplexNumber position = this.getComplexNumberFromLatticeCoordsForZoomedMandelbrot(turingPosition);
125 lattice[turingPosition.getX()][turingPosition.getY()] = position.computeMandelbrotSet();
126 return position.isInMandelbrotSet();
127 }
128
129 public synchronized boolean isInMandelbrotSet(Point turingPosition) {
130 ComplexNumber position = this.getComplexNumberFromLatticeCoordsForMandelbrot(turingPosition);
131 lattice[turingPosition.getX()][turingPosition.getY()] = position.computeMandelbrotSet();
132 return position.isInMandelbrotSet();
133 }
134
135 public synchronized void fillTheOutsideWithColors(){
136 for(int y=0;y<worldDimensions.getY();y++){
137 for(int x=0;x<worldDimensions.getX();x++){
138 if(lattice[x][y] == YET_UNCOMPUTED){
139 this.isInMandelbrotSet(new Point(x, y));
140 }
141 }
142 }
143 }
144
145 private synchronized void computeTheJuliaSetForC(ComplexNumber c) {
146 for(int y = 0; y < worldDimensions.getY(); y++) {
147 for (int x = 0; x < worldDimensions.getX(); x++) {
148 Pointer/kurzweil/mandelbrot/model/helper/Point.html#Point">Point zPoint = new Point(x, y);
149 ComplexNumber z = this.getComplexNumberFromLatticeCoordsForJulia(zPoint);
150 lattice[x][y] = z.computeJuliaSet(c);
151 }
152 }
153 }
154
155 public synchronized void computeTheJuliaSetFor(Point pointFromMandelbrotSet) {
156 ComplexNumber c = getComplexNumberFromLatticeCoordsForMandelbrot(pointFromMandelbrotSet);
157 this.complexNumberForJuliaSetC = c;
158 computeTheJuliaSetForC(c);
159 }
160
161 public void zoomIntoTheMandelbrotSet(Point zoomPoint) {
162
163 this.inceaseZoomLevel();
164 if(this.getZoomLevel() == 2){
165 ComplexNumberdelbrot/model/fractal/ComplexNumber.html#ComplexNumber">ComplexNumber complexCenter = new ComplexNumber(this.complexCenterForMandelbrot);
166 complexCenterForZoomedMandelbrot.push(complexCenter);
167 this.setZoomCenter(getComplexNumberFromLatticeCoordsForMandelbrot(zoomPoint));
168 } else {
169 this.setZoomCenter(getComplexNumberFromLatticeCoordsForZoomedMandelbrot(zoomPoint));
170 }
171 complexCenterForZoomedMandelbrot.push(this.getZoomCenter());
172
173
174 for(int y = 0; y < worldDimensions.getY(); y++){
175 for(int x = 0; x < worldDimensions.getX(); x++){
176 Pointomputer/kurzweil/mandelbrot/model/helper/Point.html#Point">Point p = new Point(x, y);
177 this.isInZooomedMandelbrotSet(p);
178 }
179 }
180 }
181
182 public void zoomOutOfTheMandelbrotSet() {
183
184 if(this.getZoomLevel()>1){
185 this.deceaseZoomLevel();
186 this.setZoomCenter(complexCenterForZoomedMandelbrot.pop());
187 }
188
189 for(int y = 0; y < worldDimensions.getY(); y++){
190 for(int x = 0; x < worldDimensions.getX(); x++){
191 Pointomputer/kurzweil/mandelbrot/model/helper/Point.html#Point">Point p = new Point(x, y);
192 this.isInZooomedMandelbrotSet(p);
193 }
194 }
195 }
196
197 public void zoomIntoTheJuliaSetFor(Point zoomPoint) {
198 ComplexNumber c = this.complexNumberForJuliaSetC;
199 computeTheJuliaSetForC(c);
200 }
201
202 public void zoomOutOfTheJuliaSet() {
203 }
204
205 public synchronized int getZoomLevel() {
206 return zoomLevel;
207 }
208
209 public synchronized int inceaseZoomLevel() {
210 return zoomLevel *= 2;
211 }
212
213 public synchronized int deceaseZoomLevel() {
214 return zoomLevel /= 2;
215 }
216
217 public synchronized void setZoomLevel(int zoomLevel) {
218 this.zoomLevel = zoomLevel;
219 }
220
221 public synchronized ComplexNumber getZoomCenter() {
222 return zoomCenter;
223 }
224
225 public synchronized void setZoomCenter(ComplexNumber zoomCenter) {
226 this.zoomCenter = zoomCenter;
227 }
228
229 }