Imię ..........Piotr
Nazwisko ........Lewicki
Wiek ..
Wzrost 72.4409449 inch
Waga ...2574.9728 oz
Narodowość .........Polska

01-02-2011

Smok na maturze z informatyki 2009 – Smok Heighwaya – fraktal java

Filed under: Java — Tagi: , , , — Levik @ 13:39

No i tak przyszło mi w 2009 roku pisać maturę rozszerzoną z informatyki. Zadania były jak pamiętam bardzo trudne. Wczoraj za sprawą komentarza Kamila do poprzedniego posta, wróciłem pamięcią do arkusza z przed 2 lat i smok nie wydał się taki trudny jak kiedyś :-)

Na wiki smok Heighwaya jest definiowany na płaszczyźnie zespolonej, ale w arkuszu dla maturzystów nikt by na to nie poszedł. Pomimo tego idea generowania smoka jest dość ciekawa. Pojawiają się w niej liczby pseudolosowe, co nadaje ciekawego kolorytu sprawie. No ale w matematyce raczej nie ma przypadku… Nie będę wysilał się na uczoną polemikę po prostu wklejam poniżej polecenie:

Zadanie 4. Iteracje (14 pkt)
Poniższe dwa układy równań liniowych, zastosowane wielokrotnie do przekształcania
współrzędnych punktu (x, y) (przynajmniej kilka tysięcy razy) na przemian, w losowej
kolejności, generują ciekawy obraz, znany jako smok Heighwaya. Zmienne x′ i y′ oznaczają
nowe wartości współrzędnych x i y.

Do wygenerowania obrazu smoka Heighwaya może posłużyć następujący algorytm:

1. Przyjmij dowolne wartości początkowe x i y.
2. Powtórz wielokrotnie (przynajmniej kilka tysięcy razy):
2.1. Oblicz nowe wartości x i y:

  • wybierz losowo z jednakowym prawdopodobieństwem jeden z dwóch podanych układów równań,
  • oblicz x′ i y′ , stosując wybrany układ równań.

2.2. Zaznacz na wykresie kolejny punkt (x, y).

Wykorzystując dostępne narzędzia informatyczne, wykonaj poniższe polecenia. Wyniki z podpunktów a, c, d zapisz w pliku o nazwie zad_4.txt. Wyniki do każdego podpunktu poprzedź literą oznaczającą ten podpunkt.

a) Zaczynając od x = 1 i y = 1 i wybierając za każdym razem losowo jeden z dwóch
podanych układów równań, oblicz pierwsze 5000 wartości x i y z kolejnych iteracji.

b) Na podstawie swoich obliczeń sporządź obraz smoka Heighwaya. Pomiń wyniki
ze 100 pierwszych iteracji. Zadbaj o czytelność i przejrzystość obrazu. Otrzymany
obraz zapisz w pliku o nazwie smok.*, w którym * oznacza rozszerzenie pliku zgodne
z wybranym przez Ciebie formatem pliku użytym do zapamiętania obrazu.

c) Oblicz środek masy smoka, to znaczy: średnie wartości x i y z zaokrągleniem
do jednej cyfry dziesiętnej po przecinku. Przy obliczaniu średnich pomiń wyniki
ze 100 pierwszych iteracji.

d) Oblicz rozmiary powstałego smoka, to znaczy podaj (z zaokrągleniem do jednej cyfry
dziesiętnej po przecinku) minimalne i maksymalne wartości x oraz y. Pomiń wyniki
uzyskane w pierwszych 100 iteracjach obliczeń.

Nie chciało mi się walczyć z  nudnymi podpunktami po prostu skupiłem się na narysowaniu smoka :-)





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
 
public class Dragon extends JApplet {
 
	JButton generate = new JButton("Generuj");
	DragonImage panel = new DragonImage();
	ArrayList<Pixel> pixelList = new ArrayList<Pixel>();
	JTextField textField = new JTextField();
	JTextField xCor = new JTextField();
	JTextField yCor = new JTextField();
	JLabel iterLab = new JLabel("Iteracje: ");
	JLabel xLab = new JLabel("x: ");
	JLabel yLab = new JLabel("y: ");
	JLabel zoomLab = new JLabel("zoom: ");
	double x,y;
	JSlider zoomSlider = new JSlider();
	int zoom=100;
 
	public void init(){
		try {
			SwingUtilities.invokeAndWait(new Runnable() {
				public void run() {
					setLayout(null);
					setSize(650, 410);
 
					iterLab.setBounds(418,40,50,20);
					add(iterLab);		
					xLab.setBounds(455,70,50,20);
					add(xLab);
					yLab.setBounds(455,100,50,20);
					add(yLab);
					zoomLab.setBounds(430,130,80,20);
					add(zoomLab);
 
					textField.setBounds(470,40,75,25);
					add(textField);
					xCor.setBounds(470,70,35,25);
					add(xCor);
					yCor.setBounds(470,100,35,25);
					add(yCor);
					generate.setBounds(470, 10, 100, 25);
					generate.addActionListener(new GenButtonListener());
					add(generate);
 
					zoomSlider = new JSlider(1, 1000,100);
					zoomSlider.setBounds(430, 150, 200, 20);
					add(zoomSlider);
					zoomSlider.addChangeListener(new ZoomSliderListener());
 
					add(panel);
					panel.setBounds(5, 5, 400, 400);
					panel.setBackground(Color.white);
					panel.repaint();
				}
			});
		} catch(Exception e){
			JOptionPane.showMessageDialog(null,e.toString(),"Błąd",JOptionPane.ERROR_MESSAGE);
		}
	}
 
	class ZoomSliderListener implements ChangeListener {
		public void stateChanged(ChangeEvent arg0) {
			zoom = zoomSlider.getValue();
			zoomLab.setText("zoom: "+zoom);
			panel.repaint();
		}
	}
 
	class GenButtonListener implements ActionListener{
		public void actionPerformed(ActionEvent arg0) {
			if(xCor.getText().equals("") || yCor.getText().equals("") || textField.getText().equals("") || Integer.parseInt(textField.getText())<100){
				JOptionPane.showMessageDialog(null,"iteracje > 100"+'\n'+"x,y dowolne","Błąd - błędne dane wejściowe",JOptionPane.ERROR_MESSAGE);
			}else{
				int option=0;
				double xp=0,yp=0;
				x = Double.parseDouble(xCor.getText());
				y = Double.parseDouble(yCor.getText());
 
				pixelList.clear();
 
				for(int i=0;i<Integer.parseInt(textField.getText());i++){
					option = (int)Math.round(Math.random());
					if(option==1){
						xp=-0.4*x-1;
						yp=-0.4*y+0.1;
						pixelList.add(new Pixel(xp, yp));
						x=xp;
						y=yp;
					}else{
						xp=0.76*x-0.4*y;
						yp=0.4*x+0.76*y;
						pixelList.add(new Pixel(xp, yp));
						x=xp;
						y=yp;
					}
				}
				for(int i=0;i<100;i++)
					pixelList.remove(0);
 
				panel.repaint();
			}
		}
 
	}
 
	class DragonImage extends JPanel {
 
		public void paint(Graphics g){
			super.paint(g);
			int dx = panel.getWidth()/2;
			int dy = panel.getHeight()/2;
 
			g.setColor(Color.white);
			g.fillRect(0, 0, 300, 300);
 
			g.setColor(Color.LIGHT_GRAY);
			for(int i=1;i<8;i++)
				g.drawLine(50*i, 0, 50*i, 450);
			for(int i=1;i<8;i++)
				g.drawLine(0, 50*i, 450, 50*i);
 
			g.setColor(Color.red);
			for(Pixel pixel:pixelList){
				g.fillRect((int)(pixel.x*zoom)+dx, (int)(pixel.y*zoom)+dy, 1, 1);
			}
		}
	}
 
	class Pixel {
		double x,y;
 
		Pixel(double X,double Y){
			x=X; y=Y;
		}
 
		public void set(double X,double Y){
			x=X; y=Y;
		}
	}
}

Pozdrawiam!!! Piter!

1 Komentarz »

  1. Ciekawe zadanie! Ciekawy jestem czy sam, będąc w liceum dałbym radę coś takiego napisać. Co do samej implementacji – wykonywanie logiki+rysowania w wątku obsługującym zdarzenie nie jest dobrym pomysłem. Przy większych n powoduje to brzydkie zawieszanie się GUI

    Komentarz by Mateusz — 28-11-2011 @ 10:56

Dodaj komentarz

Obraz CAPTCHY

- by levik@wp.pl L3VIK -

Jesteś gościem numer - Twój adres IP to: 38.107.179.214