When you click and draw on this program’s form, the code draws other curves related to yours to produce a kaleidoscope effect. For example, it might draw a mirror image of what you draw or it might repeat your drawing rotated by multiples of 30 degrees.

`MouseDown`, `MouseMove`, and `MouseUp` event handlers do most of the work. The program stores drawing information in a `List<List<Point>>`. Each item in the list gives a list of points to draw to make a curve. The `MouseDown`, `MouseMove`, and `MouseUp` event handlers create the lists of points.

The `MouseMove` event handler refreshes the program’s `PictureBox`, which uses the following event handler to draw your curves and the modified versions.

// Draw the polylines. private void picCanvas_Paint(object sender, PaintEventArgs e) { e.Graphics.SmoothingMode = SmoothingMode.AntiAlias; // Make a list of transformations, starting with the identity. List<Matrix> matrices = new List<Matrix>(); matrices.Add(new Matrix()); // Make transformation matrices for the selected style. int wid = picCanvas.ClientSize.Width; int hgt = picCanvas.ClientSize.Height; Rectangle src_rect = new Rectangle(0, 0, wid, hgt); if (mnuStyleReflectX.Checked || mnuStyleReflectXY.Checked) { // Reflect across X axis. Point[] pts = { new Point(wid, 0), new Point(0, 0), new Point(wid, hgt) }; Matrix mat = new Matrix(src_rect, pts); matrices.Add(mat); } if (mnuStyleReflectY.Checked || mnuStyleReflectXY.Checked) { // Reflect across Y axis. Point[] pts = { new Point(0, hgt), new Point(wid, hgt), new Point(0, 0) }; Matrix mat = new Matrix(src_rect, pts); matrices.Add(mat); } if (mnuStyleReflectXY.Checked) { // Reflect across X and Y axes. Point[] pts = { new Point(wid, hgt), new Point(0, hgt), new Point(wid, 0) }; Matrix mat = new Matrix(src_rect, pts); matrices.Add(mat); } if (mnuStyleRotate2.Checked) { // Rotate 180 degrees. Matrix mat = new Matrix(); mat.RotateAt(180, new PointF(wid / 2, hgt / 2)); matrices.Add(mat); } if (mnuStyleRotate4.Checked) { // Rotate 90 degrees three times. for (int i = 1; i <= 3; i++) { Matrix mat = new Matrix(); mat.RotateAt(i * 90, new PointF(wid / 2, hgt / 2)); matrices.Add(mat); } } if (mnuStyleRotate8.Checked) { // Rotate 45 degrees seven times. for (int i = 1; i <= 7; i++) { Matrix mat = new Matrix(); mat.RotateAt(i * 45, new PointF(wid / 2, hgt / 2)); matrices.Add(mat); } } // Loop through all of the transformations. foreach (Matrix mat in matrices) { e.Graphics.Transform = mat; foreach (List<Point> pline in Polylines) { e.Graphics.DrawLines(Pens.Blue, pline.ToArray()); } } }

The code makes a `List<Matrix>` to store transformation matrices. It initializes the list by adding the identity transformation, which leaves the drawing unchanged. Then depending on the kaleidoscope style you selected from the program’s menu, the code adds other transformation matrices to the list.

After is has made the list of transformations, the program loops through them. For each transformation, the program loops through the `List<List<Point>>` connecting the points to draw the curves you made. The result is several transformed copies of your curves, making a kaleidoscopic result.

You can easily modify the program by adding other transformations, drawing in different colors, or by adding other changes.