// Mandelbrot 0.1: A demonstration of Qt# // // Copyright 2002 Marcus Urban // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // NOTE: // Variables with names like PlotXMin are in the cartesian coordinate plane. // Those with names like ImageXMin was in a translated coordinate system // where (0, 0) is the upper-left corner. using System; using Qt; // This struct is a simple implementation of complex numbers. // It was originally in a separate file because it is useful // in its own right. It is included here file only to make the // compilation process simpler of new users. public struct Complex { private double re, im; //private int x; public Complex (double re, double im) { this.re = re; this.im = im; } public static implicit operator Complex (double re) { return new Complex (re, 0.0); } public double Re { get { return re; } } public double Im { get { return im; } } public static double Abs (Complex a) { return Math.Abs (a.re) >= Math.Abs (a.im) ? Math.Abs (a.re) * Math.Sqrt( 1.0 + (a.im/a.re)*(a.im/a.re) ) : Math.Abs (a.im) * Math.Sqrt( 1.0 + (a.re/a.im)*(a.re/a.im) ); } public static Complex operator + (Complex a, Complex b) { return new Complex (a.re + b.re, a.im + b.im); } public static Complex operator - (Complex a, Complex b) { return new Complex (a.re - b.re, a.im - b.im); } public static Complex operator * (Complex a, Complex b) { return new Complex ( a.re*b.re - a.im*b.im, a.im*b.re + a.re*b.im ); } // Division isn't pretty. Do it later. public override string ToString () { return this.re.ToString () + "+" + this.im.ToString () + "i"; } } public class Mandelbrot { public static int Iterations ( Complex c ) { const int MaximumIterations = 16; Complex value = c; int currentDepth = 1; while ( Complex.Abs(value) < 2.0 && currentDepth <= MaximumIterations ) { ++currentDepth; value = (value * value) + c; } return currentDepth; } public static void Main (string[] args) { TTQApplication app = new TTQApplication (args); ImageDialog dialog = new ImageDialog (null, "Mandelbrot", false, 0); dialog.Show (); app.SetMainWidget (dialog); app.Exec (); } } public class ImageDialog : TTQDialog { const double DefaultPlotXMin = -2.0; const double DefaultPlotXMax = 2.0; const double DefaultPlotYMin = -1.5; const double DefaultPlotYMax = 1.5; TTQHBoxLayout dialogLayout; TTQGridLayout gridLayout; TTQVBoxLayout leftLayout; TTQHBoxLayout buttonLayout; TTQPushButton redrawButton; TTQLabel pixmapLabel; TTQSizePolicy fixedSizePolicy; TTQLabel XMinLabel, XMaxLabel, YMinLabel, YMaxLabel; TTQLineEdit editXMin, editXMax, editYMin, editYMax; public ImageDialog (TTQWidget parent, string name, bool modal, WidgetFlags fl): base (parent, name, modal, fl) { if (name == string.Empty) SetName ("imageDialog"); SetCaption ("Mandelbrot Image"); dialogLayout = new TTQHBoxLayout (this, 11, 6); gridLayout = new TTQGridLayout (null, 1, 1, 0, 6, "gridLayout"); leftLayout = new TTQVBoxLayout (null, 0, 6, "leftLayout"); fixedSizePolicy = new TTQSizePolicy (); fixedSizePolicy.SetHorData (TTQSizePolicy.SizeType.Fixed); fixedSizePolicy.SetVerData (TTQSizePolicy.SizeType.Fixed); XMinLabel = new TTQLabel ("Xmin", this); XMinLabel.SetSizePolicy (fixedSizePolicy); gridLayout.AddWidget (XMinLabel, 0, 0); XMaxLabel = new TTQLabel ("Xmax", this); XMaxLabel.SetSizePolicy(fixedSizePolicy); gridLayout.AddWidget (XMaxLabel, 1, 0); YMinLabel = new TTQLabel ("Ymin", this); YMinLabel.SetSizePolicy (fixedSizePolicy); gridLayout.AddWidget (YMinLabel, 2, 0); YMaxLabel = new TTQLabel ("Ymax", this); YMaxLabel.SetSizePolicy (fixedSizePolicy); gridLayout.AddWidget (YMaxLabel, 3, 0); TTQDoubleValidator validator = new TTQDoubleValidator (this); editXMin = new TTQLineEdit (this, "editXMin"); editXMin.SetText (Convert.ToString (DefaultPlotXMin)); editXMin.SetValidator (validator); gridLayout.AddWidget (editXMin, 0, 1); editXMax = new TTQLineEdit (this, "editXMax"); editXMax.SetText (Convert.ToString(DefaultPlotXMax)); editXMax.SetValidator (validator); gridLayout.AddWidget (editXMax, 1, 1); editYMin = new TTQLineEdit (this, "editYMin"); editYMin.SetText (Convert.ToString(DefaultPlotYMin)); editYMin.SetValidator (validator); gridLayout.AddWidget (editYMin, 2, 1); editYMax = new TTQLineEdit (this, "editYMax"); editYMax.SetText (Convert.ToString(DefaultPlotYMax)); editYMax.SetValidator (validator); gridLayout.AddWidget (editYMax, 3, 1); leftLayout.AddLayout (gridLayout); TTQSpacerItem spacer1 = new TTQSpacerItem (0, 0, 0, 0); leftLayout.AddItem (spacer1); buttonLayout = new TTQHBoxLayout (null, 0, 6, "buttonLayout"); TTQSpacerItem spacer2 = new TTQSpacerItem (0, 0, 0, 0); buttonLayout.AddItem (spacer2); redrawButton = new TTQPushButton ("Redraw", this); redrawButton.SetDefault (true); buttonLayout.AddWidget (redrawButton); TTQSpacerItem spacer3 = new TTQSpacerItem (0, 0, 0, 0); buttonLayout.AddItem (spacer3); leftLayout.AddLayout (buttonLayout); dialogLayout.AddLayout (leftLayout); TTQSpacerItem spacer4 = new TTQSpacerItem (0, 0, 0, 0); dialogLayout.AddItem (spacer4); pixmapLabel = new TTQLabel (this, "pixmapLabel", 0); pixmapLabel.SetScaledContents (true); dialogLayout.AddWidget (pixmapLabel); TTQObject.Connect (redrawButton, TQT_SIGNAL ("clicked()"), this, TQT_SLOT ("Redraw()")); Redraw (); } TTQImage MandelbrotImage () { int depth; double real, imag; double PlotXMin = Convert.ToDouble ( editXMin.Text () ); double PlotXMax = Convert.ToDouble ( editXMax.Text () ); double PlotYMin = Convert.ToDouble ( editYMin.Text () ); double PlotYMax = Convert.ToDouble ( editYMax.Text () ); int ImageXMax = pixmapLabel.Width (); int ImageYMax = pixmapLabel.Height (); TTQImage image = new TTQImage (ImageXMax, ImageYMax, 32, 0); for (int x = 0; x <= ImageXMax - 1; x+=1) { for (int y = 0; y <= ImageYMax - 1; y+=1) { real = (PlotXMax - PlotXMin)/ImageXMax * x + PlotXMin; imag = (PlotYMin - PlotYMax)/ImageYMax * y + PlotYMax; depth = Mandelbrot.Iterations ( new Complex (real, imag) ); image.SetPixel ( x, y, (uint) depth*16 ); } } return image; } public void Redraw () { TTQSize s = pixmapLabel.BaseSize (); pixmapLabel.Resize (400,300); TTQApplication.SetOverrideCursor ( new TTQCursor( (int) CursorShape.WaitCursor )); TTQImage image = MandelbrotImage (); TTQPixmap pixmap = new TTQPixmap (image); pixmapLabel.SetPixmap( pixmap); image.Dispose (); pixmap.Dispose (); this.AdjustSize (); TTQApplication.RestoreOverrideCursor (); } }