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