diff --git a/Game_of_Life/MainForm1.Designer.cs b/Game_of_Life/MainForm1.Designer.cs index 7b9dc6e..d91525b 100644 --- a/Game_of_Life/MainForm1.Designer.cs +++ b/Game_of_Life/MainForm1.Designer.cs @@ -35,6 +35,8 @@ partial class MainForm1 this.debugLabel = new System.Windows.Forms.Label(); this.scalingSlider = new System.Windows.Forms.TrackBar(); this.buttonRepopulate = new System.Windows.Forms.Button(); + this.zoomInButton = new System.Windows.Forms.Button(); + this.zoomOutButton = new System.Windows.Forms.Button(); ((System.ComponentModel.ISupportInitialize)(this.pictureBox)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.scalingSlider)).BeginInit(); this.SuspendLayout(); @@ -67,11 +69,10 @@ partial class MainForm1 this.scalingSlider.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.scalingSlider.Location = new System.Drawing.Point(12, 405); this.scalingSlider.Maximum = 500; - this.scalingSlider.Minimum = 10; this.scalingSlider.Name = "scalingSlider"; this.scalingSlider.Size = new System.Drawing.Size(178, 45); + this.scalingSlider.SmallChange = 2; this.scalingSlider.TabIndex = 2; - this.scalingSlider.Value = 10; this.scalingSlider.ValueChanged += new System.EventHandler(this.scalingSlider_Changed); // // buttonRepopulate @@ -85,12 +86,36 @@ partial class MainForm1 this.buttonRepopulate.UseVisualStyleBackColor = true; this.buttonRepopulate.Click += new System.EventHandler(this.buttonRepopulate_Click); // + // zoomInButton + // + this.zoomInButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.zoomInButton.Location = new System.Drawing.Point(12, 373); + this.zoomInButton.Name = "zoomInButton"; + this.zoomInButton.Size = new System.Drawing.Size(24, 26); + this.zoomInButton.TabIndex = 4; + this.zoomInButton.Text = "+"; + this.zoomInButton.UseVisualStyleBackColor = true; + this.zoomInButton.Click += new System.EventHandler(this.zoomInButton_Click); + // + // zoomOutButton + // + this.zoomOutButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.zoomOutButton.Location = new System.Drawing.Point(42, 373); + this.zoomOutButton.Name = "zoomOutButton"; + this.zoomOutButton.Size = new System.Drawing.Size(24, 26); + this.zoomOutButton.TabIndex = 5; + this.zoomOutButton.Text = "-"; + this.zoomOutButton.UseVisualStyleBackColor = true; + this.zoomOutButton.Click += new System.EventHandler(this.zoomOutButton_Click); + // // MainForm1 // this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.BackColor = System.Drawing.Color.Black; this.ClientSize = new System.Drawing.Size(800, 450); + this.Controls.Add(this.zoomOutButton); + this.Controls.Add(this.zoomInButton); this.Controls.Add(this.buttonRepopulate); this.Controls.Add(this.scalingSlider); this.Controls.Add(this.debugLabel); @@ -110,4 +135,6 @@ partial class MainForm1 private Label debugLabel; private TrackBar scalingSlider; private Button buttonRepopulate; + private Button zoomInButton; + private Button zoomOutButton; } \ No newline at end of file diff --git a/Game_of_Life/MainForm1.cs b/Game_of_Life/MainForm1.cs index b2a71b6..d6ebada 100644 --- a/Game_of_Life/MainForm1.cs +++ b/Game_of_Life/MainForm1.cs @@ -8,26 +8,38 @@ namespace Game_of_Life; public partial class MainForm1 : Form { private int scalingFactor = 10; + private int scalingAbsolute = 0; + private int scalingMax; Pixelmap pixelmap; - private int height; - private int width; + private int fieldHeight; + private int fieldWidth; public MainForm1() { InitializeComponent(); - height = 1800; - width = 3200; + fieldHeight = 1800; + fieldWidth = 3200; + if (fieldWidth % 2 == 0) + { + scalingMax = fieldWidth - 2; + } + else + { + scalingMax = fieldWidth - 1; + } + - pixelmap = new Pixelmap(height, width, scalingFactor); + scalingSlider.Minimum = 0; + scalingSlider.Maximum = scalingMax; + + pixelmap = new Pixelmap(fieldHeight, fieldWidth, scalingFactor); Random rand = new Random(); for (int i = 0; i < 4000; i++) { - pixelmap.setPixel(rand.Next(width), rand.Next(height), rand.Next(3)); + pixelmap.setPixel(rand.Next(fieldWidth), rand.Next(fieldHeight), rand.Next(3)); } - - debugLabel.Text = $"Scaling Factor: {scalingFactor.ToString()}\n{((double)10 / (double)scalingFactor)} - Dimensions: {Math.Floor(pictureBox.Size.Height * ((double)10 / (double)scalingFactor)).ToString()}x{Math.Floor(pictureBox.Size.Width * ((double)10 / (double)scalingFactor)).ToString()}"; } private void pictureBox1_Paint(object sender, System.Windows.Forms.PaintEventArgs e) @@ -35,8 +47,6 @@ public partial class MainForm1 : Form int height = pictureBox.Size.Height; int width = pictureBox.Size.Width; - debugLabel.Text = $"Scaling Factor: {scalingFactor.ToString()}\n{((double)10 / (double)scalingFactor)} - Dimensions: {Math.Floor(height * ((double)10 / (double)scalingFactor)).ToString()}x{Math.Floor(width * ((double)10 / (double)scalingFactor)).ToString()}"; - Graphics graphics = e.Graphics; pictureBox.SizeMode = PictureBoxSizeMode.AutoSize; @@ -48,6 +58,8 @@ public partial class MainForm1 : Form private void pictureBox1_MouseWheel(object sender, MouseEventArgs e) { scalingFactor += e.Delta/16; + scalingAbsolute += e.Delta / 16; + if (scalingFactor < 10) { scalingFactor = 10; @@ -56,17 +68,46 @@ public partial class MainForm1 : Form scalingFactor = 500; } - scalingSlider.Value = scalingFactor; + if (scalingAbsolute < 0) + { + scalingAbsolute = 0; + } + + if (scalingAbsolute > scalingMax) + { + scalingAbsolute = scalingMax; + } + + if (scalingAbsolute % 2 != 0) + { + scalingAbsolute += 1; + scalingSlider.Value = scalingAbsolute; + } + if (scalingAbsolute > (fieldWidth - 10)) + { + scalingAbsolute = (fieldWidth - 12); + if (scalingAbsolute % 2 != 0) + { + scalingAbsolute += 1; + scalingSlider.Value = scalingAbsolute; + } + } + + scalingSlider.Value = scalingAbsolute; pixelmap.setScalingFactor(scalingFactor); - debugLabel.Text = $"Scaling Factor: {scalingFactor.ToString()}\n{((double)10 / (double)scalingFactor)} - Dimensions: {Math.Floor(pictureBox.Size.Height * ((double)10 / (double)scalingFactor)).ToString()}x{Math.Floor(pictureBox.Size.Width * ((double)10 / (double)scalingFactor)).ToString()}"; + pixelmap.setScalingAbsolute(scalingAbsolute); pictureBox.Refresh(); } private void scalingSlider_Changed(object sender, EventArgs e) { - scalingFactor = scalingSlider.Value; - pixelmap.setScalingFactor(scalingFactor); - debugLabel.Text = $"Scaling Factor: {scalingFactor.ToString()}\n{((double)10 / (double)scalingFactor)} - Dimensions: {Math.Floor(pictureBox.Size.Height * ((double)10 / (double)scalingFactor)).ToString()}x{Math.Floor(pictureBox.Size.Width * ((double)10 / (double)scalingFactor)).ToString()}"; + scalingAbsolute = scalingSlider.Value; + if (scalingAbsolute % 2 != 0) + { + scalingAbsolute += 1; + scalingSlider.Value = scalingAbsolute; + } + pixelmap.setScalingAbsolute(scalingAbsolute); pictureBox.Refresh(); } @@ -77,7 +118,7 @@ public partial class MainForm1 : Form for (int i = 0; i < 4000; i++) { - pixelmap.setPixel(rand.Next(width), rand.Next(height), rand.Next(3)); + pixelmap.setPixel(rand.Next(fieldWidth), rand.Next(fieldHeight), rand.Next(3)); } pictureBox.Refresh(); } @@ -87,4 +128,56 @@ public partial class MainForm1 : Form pixelmap.cyclePixel(MousePosition.X, MousePosition.Y); pictureBox.Refresh(); } + + private void zoomInButton_Click(object sender, EventArgs e) + { + scalingAbsolute += 4; + while (scalingAbsolute % 4 != 0) + { + scalingAbsolute += 1; + scalingSlider.Value = scalingAbsolute; + } + if (scalingAbsolute < 0) + { + scalingAbsolute = 0; + } + if (scalingAbsolute > (fieldWidth - 10)) + { + scalingAbsolute = (fieldWidth - 12); + while (scalingAbsolute % 4 != 0) + { + scalingAbsolute += 1; + scalingSlider.Value = scalingAbsolute; + } + } + + scalingSlider.Value = scalingAbsolute; + pixelmap.setScalingAbsolute(scalingAbsolute); + } + + private void zoomOutButton_Click(object sender, EventArgs e) + { + scalingAbsolute -= 4; + while (scalingAbsolute % 4 != 0) + { + scalingAbsolute += 1; + scalingSlider.Value = scalingAbsolute; + } + if (scalingAbsolute < 0) + { + scalingAbsolute = 0; + } + if (scalingAbsolute > (fieldWidth - 10)) + { + scalingAbsolute = (fieldWidth - 12); + while (scalingAbsolute % 4 != 0) + { + scalingAbsolute += 1; + scalingSlider.Value = scalingAbsolute; + } + } + + scalingSlider.Value = scalingAbsolute; + pixelmap.setScalingAbsolute(scalingAbsolute); + } } diff --git a/Game_of_Life/Pixelmap.cs b/Game_of_Life/Pixelmap.cs index eca3124..af90c5e 100644 --- a/Game_of_Life/Pixelmap.cs +++ b/Game_of_Life/Pixelmap.cs @@ -4,27 +4,30 @@ public class Pixelmap { private int height; private int width; - private Color[,] map; + private int[,] map; private int scalingFactor; private int[] midPoint; private int viewWidth; private int viewHeight; + private int scalingAbsolute; + private Color[] colors = {Color.Black, Color.White, Color.OrangeRed}; public Pixelmap(int height, int width, int scalingFactor) { this.height = height; this.width = width; - map = new Color[width, height]; + map = new int[width, height]; for (int w = 0; w < width; w++) { for (int h = 0; h < height; h++) { - map[w, h] = Color.Black; + map[w, h] = 0; } } this.scalingFactor = scalingFactor; - this.midPoint = new int[] { (width / 2), (height / 2) }; + this.midPoint = new int[] { width / 2, height / 2 }; + this.scalingAbsolute = 0; } public void setScalingFactor(int scalingFactor) @@ -32,43 +35,42 @@ public class Pixelmap this.scalingFactor = scalingFactor; } + public void setScalingAbsolute(int scalingAbsolute) + { + this.scalingAbsolute = scalingAbsolute; + } + public void clear() { - map = new Color[width, height]; + map = new int[width, height]; for (int w = 0; w < width; w++) { for (int h = 0; h < height; h++) { - map[w, h] = Color.Black; + map[w, h] = 0; } } } public void setPixel(int x, int y, int val) { - Color col = Color.Black;; - if (val == 1) - { - col = Color.White; - } else if (val == 2) - { - col = Color.Chocolate; - } - map[x, y] = col; + val = val >= 3 ? 0 : val; + map[x, y] = val; } public void cyclePixel(int x, int y) { - float zoomFactor = ((float)10 / (float)scalingFactor); float aspectRatio = (float)viewHeight / (float)viewWidth; - int borderWidth = (int)Math.Ceiling((float)width * zoomFactor); - int borderHeight = (int)Math.Ceiling((float)width * zoomFactor * aspectRatio); + // set width and needed height of the border of the viewable area + int borderWidth = width - scalingAbsolute; + int borderHeight = (int)Math.Ceiling((float)borderWidth * aspectRatio); + // scaling factors for both dimensions float scaleWidth = (float)viewWidth / (float)borderWidth; float scaleHeight = (float)viewHeight / (float)borderHeight; - + // set both left and right bound for the area being viewed int leftBound = (int)Math.Floor(midPoint[0] - ((float)borderWidth / (float)2)); if (leftBound < 0) { @@ -81,64 +83,37 @@ public class Pixelmap upperBound = 0; } - int scalePixelWidth; - if (scaleWidth < 1) - { - scalePixelWidth = 1; - } - else - { - scalePixelWidth = (int)scaleWidth; - } - - int scalePixelHeight; - if (scaleHeight < 1) - { - scalePixelHeight = 1; - } - else - { - scalePixelHeight = (int)scaleHeight; - } - - float xTrans = (float)x / scaleWidth; - float yTrans = (float)y / scaleHeight; - - setPixel((int)(xTrans + leftBound), (int)(yTrans + upperBound), 1); - } - - public Bitmap ToBitmap() - { - Bitmap b = new Bitmap(width, height); - - for (int w = 0; w < width; w++) - { - for (int h = 0; h < height; h++) - { - b.SetPixel(w, h, map[w,h]); - } - } - - return b; + float xTrans = (float)(x-scaleWidth) / scaleWidth; + float yTrans = (float)(y-scaleHeight) / scaleHeight; + int pixelX = (int)Math.Ceiling(xTrans + (float)leftBound); + int pixelY = (int)Math.Ceiling(yTrans + (float)upperBound); + int val = map[pixelX, pixelY] + 1; + setPixel(pixelX, pixelY, val); } public Graphics paintOnGraphics(Graphics g, int viewWidth, int viewHeight) { + g.Clear(Color.Black); + Color penColor = Color.FromArgb(125, Color.Beige); Pen linePen = new Pen(penColor, 1); this.viewHeight = viewHeight; this.viewWidth = viewWidth; - float zoomFactor = ((float)10 / (float)scalingFactor); + int[] viewMid = { viewWidth / 2, viewHeight / 2 }; + float aspectRatio = (float)viewHeight / (float)viewWidth; - int borderWidth = (int)Math.Ceiling((float)width * zoomFactor); - int borderHeight = (int)Math.Ceiling((float)width * zoomFactor * aspectRatio); + // set width and needed height of the border of the viewable area + int borderWidth = width - scalingAbsolute; + int borderHeight = (int)Math.Ceiling((float)borderWidth * aspectRatio); + // scaling factors for both dimensions float scaleWidth = (float)viewWidth / (float)borderWidth; float scaleHeight = (float)viewHeight / (float)borderHeight; + // ensure that pixel width and height are always at least 1px int scalePixelWidth; if (scaleWidth < 1) { @@ -159,7 +134,7 @@ public class Pixelmap scalePixelHeight = (int)Math.Ceiling(scaleHeight); } - + // set both left and right bound for the area being viewed int leftBound = (int)Math.Ceiling(midPoint[0] - ((float)borderWidth / (float)2)); if (leftBound < 0) { @@ -171,6 +146,7 @@ public class Pixelmap rightBound = width; } + // set both upper and lower bound for the area being viewed int upperBound = (int)Math.Ceiling(midPoint[1] - ((float)borderHeight / (float)2)); if (upperBound < 0) { @@ -186,12 +162,44 @@ public class Pixelmap { for (int h = upperBound; h < lowerBound; h++) { - Color pixelColor = map[w, h]; + int deltaW = w - midPoint[0]; + int deltaH = h - midPoint[1]; + + Color pixelColor = colors[map[w, h]]; if (!pixelColor.Equals(Color.Black)) { + int x = (int)(viewMid[0] + (deltaW * scaleWidth)); + int y = (int)(viewMid[1] + (deltaH * scaleHeight)); + int pixelWidth = (int)scalePixelWidth; + int pixelHeight = (int)scalePixelHeight; + + if (x < 0) + { + int deltaX = 0 - x; + x = 0; + pixelWidth = scalePixelWidth - deltaX; + } + else if (x + (int)scalePixelWidth > viewWidth) + { + int deltaX = viewWidth - x; + pixelWidth = deltaX; + } + + if (y < 0) + { + int deltaY = 0 - y; + y = 0; + pixelHeight = scalePixelHeight - deltaY; + } + else if (y + (int)scalePixelHeight > viewHeight) + { + int deltaY = viewHeight - y; + pixelWidth = deltaY; + } + Brush pixelBrush = new SolidBrush(pixelColor); g.FillRectangle(pixelBrush, - new Rectangle((int)(((float)w - (float)leftBound) * scaleHeight), (int)(((float)h - (float)upperBound) * scaleHeight), (int)scalePixelWidth, (int)scalePixelHeight)); + new Rectangle(x, (int)(viewMid[1] + (deltaH * scaleHeight)), (int)scalePixelWidth, (int)scalePixelHeight)); } } }