]> git.saurik.com Git - wxWidgets.git/blame - demos/fractal/fractal.cpp
Docstring typos
[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
be5a51fb 26doesn't seem to be an equivalent of under wxWidgets, and my quick
b713f891 27hack doesn't fix.
025e88c5
JS
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
b713f891
WS
45#include "wx/math.h"
46
025e88c5 47#include <stdlib.h>
025e88c5
JS
48#include <time.h>
49
50#define Random(x) (rand() % x)
51#define Randomize() (srand((unsigned int)time(NULL)))
52
e0e31ccd 53static int detail = 9; // CHANGE THIS... 7,8,9 etc
025e88c5 54
b713f891 55static bool running = false;
025e88c5
JS
56static wxMenuBar *menuBar = NULL;
57
58// Define a new application type
59class MyApp: public wxApp
e0e31ccd
WS
60{
61public:
62 bool OnInit();
025e88c5
JS
63};
64
65IMPLEMENT_APP(MyApp)
66
67// Define a new frame type
68class MyFrame: public wxFrame
69{
70public:
e0e31ccd 71 MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos, const wxSize& size);
025e88c5 72
e0e31ccd 73 void OnCloseWindow(wxCloseEvent& event);
025e88c5 74 void OnExit(wxCommandEvent& event);
e0e31ccd
WS
75
76 DECLARE_EVENT_TABLE()
025e88c5
JS
77};
78
79// Define a new canvas which can receive some events
80class MyCanvas: public wxWindow
81{
82public:
e0e31ccd
WS
83 MyCanvas(wxFrame *frame);
84 void Draw(wxDC& dc);
025e88c5
JS
85
86private:
e0e31ccd
WS
87 void OnPaint(wxPaintEvent& event);
88 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);
89 wxPen SnowPen, MtnPen, GreenPen;
90 wxBrush WaterBrush;
91 int Sealevel;
025e88c5
JS
92
93DECLARE_EVENT_TABLE()
94};
95
96// `Main program' equivalent, creating windows and returning main app frame
97bool MyApp::OnInit()
98{
99 // Create the main frame window
e0e31ccd 100 MyFrame *frame = new MyFrame(NULL, _T("Fractal Mountains for wxWidgets"), wxDefaultPosition, wxSize(640, 480));
025e88c5
JS
101
102 // Make a menubar
103 wxMenu *file_menu = new wxMenu;
f37c24e0 104 file_menu->Append(wxID_EXIT, _T("E&xit"));
025e88c5 105 menuBar = new wxMenuBar;
f37c24e0 106 menuBar->Append(file_menu, _T("&File"));
025e88c5
JS
107 frame->SetMenuBar(menuBar);
108
109 int width, height;
110 frame->GetClientSize(&width, &height);
111
112 (void) new MyCanvas(frame);
113
114 // Show the frame
e0e31ccd 115 frame->Show(true);
025e88c5 116
e0e31ccd 117 return true;
025e88c5
JS
118}
119
120BEGIN_EVENT_TABLE(MyFrame, wxFrame)
121 EVT_CLOSE(MyFrame::OnCloseWindow)
122 EVT_MENU(wxID_EXIT, MyFrame::OnExit)
123END_EVENT_TABLE()
124
125// My frame constructor
126MyFrame::MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos, const wxSize& size):
e0e31ccd 127 wxFrame(frame, wxID_ANY, title, pos, size, wxDEFAULT_FRAME_STYLE | wxFULL_REPAINT_ON_RESIZE )
025e88c5
JS
128{
129}
130
131// Intercept menu commands
babd36de 132void MyFrame::OnExit(wxCommandEvent& WXUNUSED(event))
025e88c5
JS
133{
134 this->Destroy();
135}
136
babd36de 137void MyFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
025e88c5 138{
e0e31ccd 139 static bool destroyed = false;
025e88c5
JS
140 if (destroyed)
141 return;
142
143 this->Destroy();
144
e0e31ccd 145 destroyed = true;
025e88c5
JS
146}
147
148BEGIN_EVENT_TABLE(MyCanvas, wxWindow)
149 EVT_PAINT(MyCanvas::OnPaint)
150END_EVENT_TABLE()
151
152// Define a constructor for my canvas
153MyCanvas::MyCanvas(wxFrame *frame):
e0e31ccd 154 wxWindow(frame, wxID_ANY)
025e88c5
JS
155{
156 wxColour wxCol1(255,255,255);
157 SnowPen = wxPen(wxCol1, 2, wxSOLID);
158
159 wxColour wxCol2(128,0,0);
160 MtnPen = wxPen(wxCol2, 1, wxSOLID);
161
162 wxColour wxCol3(0,128,0);
163 GreenPen = wxPen(wxCol3, 1, wxSOLID);
164
165 wxColour wxCol4(0,0,128);
166 WaterBrush = wxBrush(wxCol4, wxSOLID);
167}
168
babd36de 169void MyCanvas::OnPaint(wxPaintEvent& WXUNUSED(event))
025e88c5
JS
170{
171 wxPaintDC dc(this);
e0e31ccd
WS
172 PrepareDC(dc);
173 Draw(dc);
025e88c5
JS
174}
175
176void MyCanvas::Draw(wxDC& dc)
177{
178 if (running) return;
b713f891 179
e0e31ccd
WS
180 running = true;
181 menuBar->EnableTop(0, false);
182
183 Randomize();
025e88c5 184
e0e31ccd
WS
185 dc.SetBackground(*wxLIGHT_GREY_BRUSH);
186 dc.Clear();
025e88c5 187
e0e31ccd
WS
188 int Left, Top, Right, Bottom;
189 GetClientSize(&Right, &Bottom);
025e88c5 190
e0e31ccd
WS
191 Right *= 3; Right /= 4;
192 Bottom *= 3; Bottom /= 4;
193 Left = 0;
194 Top = Bottom/8;
025e88c5 195
e0e31ccd
WS
196 wxPoint Water[4];
197 Water[0].x = Left; Water[0].y = Top;
198 Water[1].x = Right; Water[1].y = Top;
199 Water[2].x = Right+Bottom/2; Water[2].y = Bottom;
200 Water[3].x = Bottom/2; Water[3].y = Bottom;
025e88c5 201
e0e31ccd
WS
202 dc.SetBrush(WaterBrush);
203 dc.DrawPolygon(4, Water);
025e88c5 204
e0e31ccd
WS
205 double H = 0.75;
206 double Scale = Bottom;
207 double Ratio = 1.0 / pow(2.0, H);
208 double Std = Scale * Ratio;
209 Sealevel = Random(18) - 8;
025e88c5 210
e0e31ccd 211 Fractal(dc, Left, Top, Right, Bottom, 0, 0, 0, 0, detail, Std, Ratio);
025e88c5 212
e0e31ccd
WS
213 menuBar->EnableTop(0, true);
214 running = false;
025e88c5
JS
215}
216
217void 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)
218{
e0e31ccd
WS
219 int Xmid = (X1 + X2) / 2;
220 int Ymid = (Y1 + Y2) / 2;
221 int Z23 = (Z2 + Z3) / 2;
222 int Z41 = (Z4 + Z1) / 2;
223 int Newz = (int)((Z1 + Z2 + Z3 + Z4) / 4 + (double)(Random(17) - 8) / 8.0 * Std);
224
225 if (--Iteration)
226 {
227 int Z12 = (Z1 + Z2) / 2;
228 int Z34 = (Z3 + Z4) / 2;
229 double Stdmid = Std * Ratio;
230
231 Fractal(dc, Xmid, Y1, X2, Ymid, Z12, Z2, Z23, Newz, Iteration, Stdmid, Ratio);
232 Fractal(dc, X1, Y1, Xmid, Ymid, Z1, Z12, Newz, Z41, Iteration, Stdmid, Ratio);
233 Fractal(dc, Xmid, Ymid, X2, Y2, Newz, Z23, Z3, Z34, Iteration, Stdmid, Ratio);
234 Fractal(dc, X1, Ymid, Xmid, Y2, Z41, Newz, Z34, Z4, Iteration, Stdmid, Ratio);
235 }
236 else
237 {
238 if (Newz <= Sealevel)
239 {
240 wxPoint P[4];
241 P[0].x = Y1 / 2 + X1; P[0].y = Y1 + Z1;
242 P[1].x = Y1 / 2 + X2; P[1].y = Y1 + Z2;
243 P[2].x = Y2 / 2 + X2; P[2].y = Y2 + Z3;
244 P[3].x = Y2 / 2 + X1; P[3].y = Y2 + Z4;
245
246 dc.SetPen(* wxBLACK_PEN);
247 dc.SetBrush(* wxBLACK_BRUSH);
248
249 dc.DrawPolygon(4, P);
250
251 if (Z1 >= -(60+Random(25)))
252 dc.SetPen(GreenPen);
253 else if (Z1 >= -(100+Random(25)))
254 dc.SetPen(MtnPen);
255 else
256 dc.SetPen(SnowPen);
257
258 dc.DrawLine(Ymid/2+X2, Ymid+Z23, Ymid/2+X1, Ymid+Z41);
259 }
260 }
025e88c5
JS
261}
262