]> git.saurik.com Git - wxWidgets.git/blame - demos/fractal/fractal.cpp
wxStaticBitmapBase::DoGetBestSize
[wxWidgets.git] / demos / fractal / fractal.cpp
CommitLineData
025e88c5
JS
1///////////////////////////////////////////////////////////////////////////////
2// Name: fractal.cpp
3// Purpose: demo of wxConfig and related classes
4// Author: Andrew Davison
5// Modified by:
6// Created: 05.04.94
7// RCS-ID: $Id$
8// Copyright: (c) 1994 Andrew Davison
9// Licence: wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12
13/*
14Date: Tue, 5 Apr 1994 12:01:18 +1000
15From: Andrew Davison <andrewd@au.com.sfe>
16To: wxwin-users@ed.aiai
17Subject: Fractal mountains
18
19Hi,
20
21This is a quick port of a fractal mountain generator originally
22done for MS-Windows. On a Sun the colours look a little washed
23out and there is not as much snow or high mountains (maybe the
24random number generators fault). The viewing plane is not
25quite right as the original code used SetViewportOrg() which there
26doesn't seem to be an equivalent of under wxWindows, and my quick
27hack doesn't fix.
28*/
29
30#ifdef __GNUG__
31#pragma implementation
32#pragma interface
33#endif
34
35#include "wx/wxprec.h"
36
c4b77901
JS
37#ifdef __BORLANDC__
38 #pragma hdrstop
39#endif
40
025e88c5
JS
41#ifndef WX_PRECOMP
42 #include "wx/wx.h"
43#endif //precompiled headers
44
45#include <stdlib.h>
46#include <math.h>
47#include <time.h>
48
49#define Random(x) (rand() % x)
50#define Randomize() (srand((unsigned int)time(NULL)))
51
52static int detail = 9; // CHANGE THIS... 7,8,9 etc
53
54static bool running = FALSE;
55static wxMenuBar *menuBar = NULL;
56
57// Define a new application type
58class MyApp: public wxApp
59{ public:
60 bool OnInit();
61};
62
63IMPLEMENT_APP(MyApp)
64
65// Define a new frame type
66class MyFrame: public wxFrame
67{
68public:
69 MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos, const wxSize& size);
70
71 void OnCloseWindow(wxCloseEvent& event);
72 void OnExit(wxCommandEvent& event);
73DECLARE_EVENT_TABLE()
74};
75
76// Define a new canvas which can receive some events
77class MyCanvas: public wxWindow
78{
79public:
80 MyCanvas(wxFrame *frame);
81 void Draw(wxDC& dc);
82
83private:
84 void OnPaint(wxPaintEvent& event);
85 void Fractal(wxDC& dc, int X1, int Y1, int X2, int Y2, int Z1, int Z2, int Z3, int Z4, int Iteration, double Std, double Ratio);
86 wxPen SnowPen, MtnPen, GreenPen;
87 wxBrush WaterBrush;
88 int Sealevel;
89
90DECLARE_EVENT_TABLE()
91};
92
93// `Main program' equivalent, creating windows and returning main app frame
94bool MyApp::OnInit()
95{
96 // Create the main frame window
f37c24e0 97 MyFrame *frame = new MyFrame(NULL, _T("Fractal Mountains for wxWindows"), wxPoint(-1, -1), wxSize(640, 480));
025e88c5
JS
98
99 // Make a menubar
100 wxMenu *file_menu = new wxMenu;
f37c24e0 101 file_menu->Append(wxID_EXIT, _T("E&xit"));
025e88c5 102 menuBar = new wxMenuBar;
f37c24e0 103 menuBar->Append(file_menu, _T("&File"));
025e88c5
JS
104 frame->SetMenuBar(menuBar);
105
106 int width, height;
107 frame->GetClientSize(&width, &height);
108
109 (void) new MyCanvas(frame);
110
111 // Show the frame
112 frame->Show(TRUE);
113
114 return TRUE;
115}
116
117BEGIN_EVENT_TABLE(MyFrame, wxFrame)
118 EVT_CLOSE(MyFrame::OnCloseWindow)
119 EVT_MENU(wxID_EXIT, MyFrame::OnExit)
120END_EVENT_TABLE()
121
122// My frame constructor
123MyFrame::MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos, const wxSize& size):
c4b77901 124 wxFrame(frame, -1, title, pos, size, wxDEFAULT_FRAME_STYLE | wxFULL_REPAINT_ON_RESIZE)
025e88c5
JS
125{
126}
127
128// Intercept menu commands
babd36de 129void MyFrame::OnExit(wxCommandEvent& WXUNUSED(event))
025e88c5
JS
130{
131 this->Destroy();
132}
133
babd36de 134void MyFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
025e88c5
JS
135{
136 static bool destroyed = FALSE;
137 if (destroyed)
138 return;
139
140 this->Destroy();
141
142 destroyed = TRUE;
143}
144
145BEGIN_EVENT_TABLE(MyCanvas, wxWindow)
146 EVT_PAINT(MyCanvas::OnPaint)
147END_EVENT_TABLE()
148
149// Define a constructor for my canvas
150MyCanvas::MyCanvas(wxFrame *frame):
151 wxWindow(frame, -1)
152{
153 wxColour wxCol1(255,255,255);
154 SnowPen = wxPen(wxCol1, 2, wxSOLID);
155
156 wxColour wxCol2(128,0,0);
157 MtnPen = wxPen(wxCol2, 1, wxSOLID);
158
159 wxColour wxCol3(0,128,0);
160 GreenPen = wxPen(wxCol3, 1, wxSOLID);
161
162 wxColour wxCol4(0,0,128);
163 WaterBrush = wxBrush(wxCol4, wxSOLID);
164}
165
babd36de 166void MyCanvas::OnPaint(wxPaintEvent& WXUNUSED(event))
025e88c5
JS
167{
168 wxPaintDC dc(this);
169 Draw(dc);
170}
171
172void MyCanvas::Draw(wxDC& dc)
173{
174 if (running) return;
175
176 running = TRUE;
177 menuBar->EnableTop(0, FALSE);
178
179 Randomize();
180
181 int Left, Top, Right, Bottom;
182 GetClientSize(&Right, &Bottom);
183
184 Right *= 3; Right /= 4;
185 Bottom *= 3; Bottom /= 4;
186 Left = 0;
187 Top = Bottom/8;
188
189 wxPoint Water[4];
190 Water[0].x = Left; Water[0].y = Top;
191 Water[1].x = Right; Water[1].y = Top;
192 Water[2].x = Right+Bottom/2; Water[2].y = Bottom;
193 Water[3].x = Bottom/2; Water[3].y = Bottom;
194
195 dc.SetBrush(WaterBrush);
196 dc.DrawPolygon(4, Water);
197
198 double H = 0.75;
199 double Scale = Bottom;
200 double Ratio = 1.0 / pow(2.0, H);
201 double Std = Scale * Ratio;
202 Sealevel = Random(18) - 8;
203
204 Fractal(dc, Left, Top, Right, Bottom, 0, 0, 0, 0, detail, Std, Ratio);
205
206 menuBar->EnableTop(0, TRUE);
207 running = FALSE;
208}
209
210void MyCanvas::Fractal(wxDC& dc, int X1, int Y1, int X2, int Y2, int Z1, int Z2, int Z3, int Z4, int Iteration, double Std, double Ratio)
211{
212 int Xmid = (X1 + X2) / 2;
213 int Ymid = (Y1 + Y2) / 2;
214 int Z23 = (Z2 + Z3) / 2;
215 int Z41 = (Z4 + Z1) / 2;
216 int Newz = (int)((Z1 + Z2 + Z3 + Z4) / 4 + (double)(Random(17) - 8) / 8.0 * Std);
217
218 if (--Iteration)
219 {
220 int Z12 = (Z1 + Z2) / 2;
221 int Z34 = (Z3 + Z4) / 2;
222 double Stdmid = Std * Ratio;
223
224 Fractal(dc, Xmid, Y1, X2, Ymid, Z12, Z2, Z23, Newz, Iteration, Stdmid, Ratio);
225 Fractal(dc, X1, Y1, Xmid, Ymid, Z1, Z12, Newz, Z41, Iteration, Stdmid, Ratio);
226 Fractal(dc, Xmid, Ymid, X2, Y2, Newz, Z23, Z3, Z34, Iteration, Stdmid, Ratio);
227 Fractal(dc, X1, Ymid, Xmid, Y2, Z41, Newz, Z34, Z4, Iteration, Stdmid, Ratio);
228 }
229 else
230 {
231 if (Newz <= Sealevel)
232 {
233 wxPoint P[4];
234 P[0].x = Y1 / 2 + X1; P[0].y = Y1 + Z1;
235 P[1].x = Y1 / 2 + X2; P[1].y = Y1 + Z2;
236 P[2].x = Y2 / 2 + X2; P[2].y = Y2 + Z3;
237 P[3].x = Y2 / 2 + X1; P[3].y = Y2 + Z4;
238
239 dc.SetPen(* wxBLACK_PEN);
240 dc.SetBrush(* wxBLACK_BRUSH);
241
242 dc.DrawPolygon(4, P);
243
244 if (Z1 >= -(60+Random(25)))
245 dc.SetPen(GreenPen);
246 else if (Z1 >= -(100+Random(25)))
247 dc.SetPen(MtnPen);
248 else
249 dc.SetPen(SnowPen);
250
251 dc.DrawLine(Ymid/2+X2, Ymid+Z23, Ymid/2+X1, Ymid+Z41);
252 }
253 }
254}
255