The example Calculate the probability of an event occurring in a given number of trials in C# shows how to calculate event probabilities. This example graphs the results. You can use the example to get some feel for how the probabilities change.

Enter the event probability and the maximum number of trials to perform. When you click Go, the program executes the following code.

// The probability data. private PointF[] Points = {}; // Calculate and display probabilities. private void btnGo_Click(object sender, EventArgs e) { // Make room for the probabilities. int num_events = int.Parse(txtMaxNumberEvents.Text); Points = new PointF[num_events + 1]; // Get the event probability. double event_prob = double.Parse(txtEventProb.Text.Replace("%", "")); if (txtEventProb.Text.Contains("%")) event_prob /= 100.0; // Get the probability of the event not happening. double non_prob = 1.0 - event_prob; for (int i = 0; i <= num_events; i++) { Points[i].X = i; Points[i].Y = 100 * (float)(1.0 - Math.Pow(non_prob, i)); } // Redraw. picGraph.Refresh(); }

The `Points` array holds the data for the current probability parameters. The Go button’s `Click` event handler parses the number of events you entered and makes the `Points` array big enough to hold the event probabilities. The code then parses the event probability and converts it into a decimal value (as in 0.5 instead 50%).

Next the code loops over the desired events calculating the event probabilities and saving the results in the `Points` array. For drawing convenience, the code stores the probability value as a percentage.

After it has calculated all of the event probabilities, the code refreshes the `picGraph PictureBox` to make it display the results. The following code shows how the `picGraph` control’s `Paint` event handler draws the graph.

// Draw the data. private void picGraph_Paint(object sender, PaintEventArgs e) { // Clear. e.Graphics.Clear(picGraph.BackColor); if (Points.Length < 2) return; e.Graphics.SmoothingMode = SmoothingMode.AntiAlias; // Transform from world coordinates to screen coordinates. RectangleF rect = new RectangleF(0, 0, Points.Length + 1, 100); PointF[] pts = { new PointF(0, picGraph.ClientSize.Height), new PointF(picGraph.ClientSize.Width, picGraph.ClientSize.Height), new PointF(0, 0) }; Matrix transform = new Matrix(rect, pts); using (Pen pen = new Pen(Color.Gray, 0)) { // Draw the axes. using (StringFormat sf = new StringFormat()) { sf.LineAlignment = StringAlignment.Center; for (int i = 0; i <= 100; i += 10) { // See where this should be. pts = new PointF[] { new PointF(0, i), new PointF(Points.Length, i), }; transform.TransformPoints(pts); e.Graphics.DrawLine(pen, pts[0], pts[1]); e.Graphics.DrawString(i.ToString(), this.Font, Brushes.Green, pts[0], sf); } sf.Alignment = StringAlignment.Center; sf.LineAlignment = StringAlignment.Far; int skip = (int)(Points.Length / 10); skip = 5 * (int)(skip / 5); if (skip < 1) skip = 1; for (int i = 0; i < Points.Length; i += skip) { // See where this should be. pts = new PointF[] { new PointF(i, 0), new PointF(i, 5), }; transform.TransformPoints(pts); e.Graphics.DrawLine(pen, pts[0], pts[1]); e.Graphics.DrawString(i.ToString(), this.Font, Brushes.Green, pts[0], sf); } } // Draw the graph. pen.Color = Color.Blue; e.Graphics.Transform = transform; e.Graphics.DrawLines(pen, Points); } }

This code first clears the `PictureBox`. Then if there are no data points it simply returns.

The code then creates a transformation matrix to transform the data to fit the `PictureBox`. To do that it creates a `RectangleF` representing the points’ world coordinate bounds. Those ranges from 0 to 100 in the Y direction (the percentages) and 0 to the number of events in the X direction.

The code also creates an array of points indicating where on the `PictureBox` the upper left, upper right, and lower left corners of the world coordinate bounds should be mapped. It uses the `RectangleF` and the array of points to create a `Matrix` that maps from world coordinates to `PictureBox` coordinates.

The program then draws the graph. It creates a thin pen to draw with and makes a `StringFormat` object for use when drawing text.

Next the code draws horizontal lines for every multiple 10% probability. It draws a line connecting the points `(0, i) - (Points.Length, i)` for `i` = 10, 20, 30, and so forth. To do this, the code must transform the coordinates of the points so they match up with the transformed points in the graph. It does that by calling the transformation matrix’s `TransformPoints` method.

After it draws each horizontal line, the code also draws text giving the line’s probability. It positions the text at the line’s left end point `(0, i)` and centered vertically on the line.

Next the code draws the X axis. It loops over values between 0 and the number of events drawing vertical tick marks and the event numbers.

After drawing the axes and their labels, drawing the actual graph is simple. The code applies the transformation matrix to the `Graphics` object and calls that object’s `DrawLines` method to draw the lines.

When you resize the form, the `PictureBox` control’s `Resize` event handler also refreshes the `PictureBox` so you can make the graph bigger if you like.