Find happy numbers in C#


[happy numbers]

Before I show you the code, let me explain what happy numbers are.

Happy Numbers

To find happy numbers, start with any integer. Replace it with the sum of the squares off its digits. Repeat the process until the numbers repeat or reach the value 1 (after which the 1 repeats). Happy numbers are those that reach 1. Other values are unhappy or sad numbers.

For example, the following values show the happy sequences of numbers starting with 7.

72 = 49
42 + 92 = 97
92 + 72 = 130
12 + 32 + 02 = 10
12 + 02 = 1

This program graphs the places where the loops start and their lengths for happy numbers. For example, the equations above shows that the value 7 enters a loop after 5 steps and the loop has length 1 (because 1 just repeats).

Unhappy numbers eventually enter the loop 4, 16, 37, 58, 89, 145, 42, 20, 4, …

The program graphs the numbers’ starting points in red and the lengths of the cycles in blue. You can spot the happy numbers in the list on the left by looking for the ones with length equal to 1. The list highlights prime numbers in pink so you can pick out the happy primes.

Code

When you click the Go button, the program loops through values from 1 to the maximum value that you enter in the text box. For each value, the program calls the following FindHappyLoop method.

// Return the length and start position of the number's happy loop.
private List<int> FindHappyLoop(int num,
    out int loop_start, out int loop_length)
{
    List<int> list = new List<int>();
    list.Add(num);
    for (; ; )
    {
        string str = num.ToString();
        num = 0;
        foreach (char ch in str)
        {
            int digit = int.Parse(ch.ToString());
            num += digit * digit;
        }
        if (list.Contains(num))
        {
            loop_start = list.IndexOf(num);
            loop_length = list.Count - loop_start;
            return list;
        }
        list.Add(num);
    }
}

This method creates a list to hold the values in the number’s happy sequence. It then enters an infinite loop.

Inside the loop, the code converts the number into a string and then loops through its digits. It converts each digit into a number, squares it, and adds it to the variable num.

The final value of num is the next value in the number’s happy sequence. If that number is already in the sequence, the sequence has entered a loop. In that case, the method sets the loop’s start position and length and then returns.

The rest of the program is relatively straightforward, so I won’t show it here. Download the example to see additional details such as how the program builds the list on the left and how it draws the graph.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in algorithms, mathematics | Tagged , , , , , , , | Leave a comment

Draw words on a circle in WPF and C#

[draw words]

This example shows one way that you can draw words on a circle in WPF. Note that it does not show how to draw words where each character is rotated to follow the circle’s curve. Each word is rotated as a whole. That generally produces a good result for relatively small words such as the ones drawn here.

The following text shows the program’s control hierarchy created at design time. The text includes some of the controls’ properties to make it easier to identify the controls on the picture.

Window
    Grid Background="LightGreen"
        Label Name="lblZoom" Content="100%"
        Slider Name="sliZoom"
        ScrollViewer Name="scvGraph"
            Canvas Name="canGraph" Background="White"

When you adjust the slider, the following code adjusts the program’s zoom level.

// Zoom.
private double Zoom = 1;
private void sliZoom_ValueChanged(object sender,
    RoutedPropertyChangedEventArgs e)
{
    // Make sure the control's are all ready.
    if (!IsInitialized) return;

    // Display the zoom factor as a percentage.
    lblZoom.Content = sliZoom.Value + "%";

    // Get the scale factor as a fraction 0.25 - 2.00.
    double scale = (double)(sliZoom.Value / 100.0);

    // Scale the graph.
    canGraph.LayoutTransform = new ScaleTransform(scale, scale);
}

This code checks the window’s IsInitialized property to make sure that all of the controls have been created and are ready to go. It then changes the lblZoom control to display the new zoom level. It calculates a new scale factor and sets the Graph control’s LayoutTransform to scale the Graph control by the scale factor.

That makes the Graph control scale itself and all of its contents. That control is contained in a ScaleViewer, which automatically displays scroll bars if necessary so you can view the whole Graph control. (ScaleViewer is one of my favorite WPF controls.)

The only remaining part of the program is the following code, which that draws the circles and the text along them.

// Draw some circles and text.
private void Window_Loaded(object sender, RoutedEventArgs e)
{
    // Get the Canvas geometry.
    double wid = canGraph.ActualWidth;
    double hgt = canGraph.ActualHeight;
    double cx = wid / 2;
    double cy = hgt / 2;

    // Make some centered circles.
    for (int radius = 200; radius > 0; radius -= 50)
    {
        byte b = (byte)(radius / 2 + 155);
        byte r = (byte)(b / 2);
        byte g = (byte)(b / 2);

        Ellipse ellipse = new Ellipse();
        ellipse.Fill = new SolidColorBrush(
            Color.FromArgb(255, r, g, b));
        ellipse.Stroke = Brushes.Black;
        ellipse.StrokeThickness = 3;
        Canvas.SetLeft(ellipse, cx - radius);
        Canvas.SetTop(ellipse, cy - radius);
        ellipse.Width = 2 * radius;
        ellipse.Height = 2 * radius;
        canGraph.Children.Add(ellipse);
    }

    // Make some rotated text.
    double font_size = 10;
    for (int radius = 25; radius < 200; radius += 50)
    {
        const double num_angles = 6;
        double dtheta = 360 / num_angles;
        double theta = dtheta / 2;
        for (int i = 0; i < num_angles; i++)
        {
            // Convert into a counterclocckwise angle
            // where 0 is to the right.
            double angle = 90 - theta;

            // Math.Sin and Math.Cos use radians.
            double radians = (angle - 90) / 180 * Math.PI;
            double x = cx + radius * Math.Cos(radians);
            double y = cy + radius * Math.Sin(radians);

            // Use theta for the text, not angle.
            string text = ((int)theta).ToString();

            // Draw the text.
            DrawText(canGraph, text,
                new Point(x, y), angle, font_size,
                HorizontalAlignment.Center,
                VerticalAlignment.Center);

            theta += dtheta;
        }
        font_size += 3;
    }
}

The code first uses a loop to make some concentric circles. It makes them from largest to smallest so the later circles sit above the earlier ones. If you made them in smallest-to-largest order, the later circles would hide the earlier ones.

Nxet, the program uses two nested loops to draw the text. The outer loop ranges over the radii at which the program should draw text.

The inner loop ranges over the number of angles that the program needs to draw. This example draws text at six positions around the circle. The angle theta determines the position where the text should be drawn. Shortly the code will use sines and cosines to calculate the text's positions. Because Y coordinates increase downward in WPF (and Windows Forms and most programming languages), the angles used by sines and cosines increase clockwise. To make the text increase counterclockwise, the code subtracts theta from 90 to convert it into angle. It then subtracts 90 degrees and scales the result to convert angle into radians, which is the unit that the Math.Sin and Math.Cos methods require.

The code then calculates the position where the text should be drawn and calls the DrawText method to draw the text. For information on the DrawText method, see the post Draw a graph with rotated text in WPF and C#.

When the inner loop ends, the program increases the font size by 3 points so the text in the outer circles is larger.

[example]

One of the nice things about WPF is that graphics are normally represented by objects, so you can zoom in as far as you like and still get a nice, smooth result. For example, the picture on the right shows the program zoomed in so the circle is shown at 500% of its normal scale. You can see that the edges of the circles and the text 150 are still nice and smooth. Making magnified text appear smooth is harder in Windows Forms applications.

Download the example solution to see additional details and to experiment with the program. For example, you might try to scale the text so the program draws multiples of 10 between 0 and 100 instead of displaying angles in degrees.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in algorithms, graphics, mathematics | Tagged , , , , , , , , , | Leave a comment

Draw a hyperbolic spiral in C#

[spiral]

A hyperbolic spiral, which is also called an reciprocal spiral, is the inverse of an Archimedes spiral. It uses the equation r = A / θ to generate points on a spiral.

This spiral has a couple of interesting properties. First, it is drawn backwards (in some sense). Points on the Archimedes spiral and logarithmic spiral move farther from the spiral’s center as θ in increases. Points on a hyperbolic spiral move closer to the center as θ in increases.

Like a logarithmic spiral, the hyperbolic spiral doesn’t reach the spiral’s center when θ is 0. In fact, this spiral isn’t defined when θ is 0 because calculating r for that value would force you to divide by zero.

Earlier examples calculated values for r until they were larger than the distance to the farthest corner of the drawing area. We can still use that technique but with two caveats. First, in this program θ must decrease instead of increasing to produce increasingly larger values of r. Second, the program should beware of setting θ equal to 0. The example program doesn’t worry about that because r grows big enough to stop the program’s loop before that happens, but you should be aware of this issue in case you encounter it in some other program.

The earlier logarithmic spiral example calculated a maximum value for θ to make the spiral begin at (or at least very close to) the spiral’s center. This example can make a similar calculation.

This time, suppose we want generate a minimum r value of 2 so the spiral begins 2 pixels away from the center. (This spiral becomes increasingly dense as it approaches its center, so I want to leave a small hole in the middle so whole things isn’t a big blob of solid color. Setting r = 2, the spiral’s equation becomes 2 = A / &theta’. Solving for θ gives max_theta = A / 2.

The following code fragment shows how this example generates a spiral’s points.

// Return points that define a spiral.
private List<PointF> GetSpiralPoints(
    float dtheta, PointF center, float A,
    float angle_offset, float max_r)
{
    // Get the points.
    float max_theta = A / 2f;
    List<PointF> points = new List<PointF>();
    for (float theta = max_theta; ; theta -= dtheta)
    {
        // Calculate r.
        float r = A / theta;

        // Convert to Cartesian coordinates.
        float x, y;
        PolarToCartesian(r, theta + angle_offset, out x, out y);

        // Center.
        x += center.X;
        y += center.Y;

        // Create the point.
        points.Add(new PointF((float)x, (float)y));

        // If we have gone far enough, stop.
        if (r > max_r) break;
    }
    return points;
}

This method calculates max_theta as described above and makes a list to hold the spiral’s points. It then enters a loop where variable theta runs downward from max_theta. Inside the loop, the code calculates the value r, converts the result into Cartesian coordinates, and adds the point to the points list.

When r is larger than the distance to the farthest corner of the drawing area, the method breaks out of its loop and returns the spiral’s points.

Download the program to see additional details.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in algorithms, graphics, mathematics | Tagged , , , , , , , , , | Leave a comment

Review posted: “The Modern C# Challenge”

The Modern C# Challenge: Become an expert C# programmer by solving interesting programming problems

[The Modern C# Challenge]

Clock End Gooner has posted a review of my latest book, The Modern C# Challenge: Become an expert C# programmer by solving interesting programming problems. Please following this link to learn more about the book and to see the review.

Fun, Interesting, Challenging, Useful

The book contains 100 interesting programming challenges that you can use to test your C# programming skills. The problems use a wide variety of important programming techniques and many of the example solutions demonstrate key concepts such as protecting against overflow, caching data (dynamic programming), randomization, simulation, parallel processing, and more!

More info at Amazon

More info at C# Helper


Follow me on Twitter   RSS feed   Donate




Posted in books, combinatorics, cryptography, geometry, mathematics | Leave a comment

Draw a logarithmic spiral in C#

[spiral]

The post Draw an Archimedes spiral in C# uses the equation r = A˙θ to generate the points on a spiral. This example is almost exactly the same except it uses the equation to r = A˙eB˙θ to generate its points.

That equation leads to another small issue. When θ is 0, the eB˙θ becomes 1 so r = A. That means the spiral isn’t at its center point.

You can generate points closer to the center if you consider negative values for θ. The question then becomes, “How small does θ need to be?”

If we set θ small enough to make r equal to 0.1, then the resulting point will be less than one pixel away from the spiral’s center. To do that, we solve the equation 0.1 = A˙eB˙min_theta for min_theta. The result is min_theta = ln(0.1 / A) / B.

The new example is almost exactly the same as the previous example’s version. The only real change is in the GetSpiralPoints method, which uses the following code fragment to generate points on a spiral.

// Return points that define a spiral.
private List GetSpiralPoints(...)
{
    ...
    for (float theta = min_theta; ; theta += dtheta)
    {
        // Calculate r.
        float r = (float)(A * Math.Exp(B * theta));

        ...

        // If we have gone far enough, stop.
        if (r > max_r) break;
    }
    return points;
}

This code calculates min_theta as described above. It then makes variable theta loop starting from min_theta. The code uses the new formula to calculate r.

As in the previous example, the loop continues until the calculated value for r exceeds the maximum necessary value, at which point the method breaks out of its loop and returns the spiral’s points.

The rest of the example is the same as the previous one. Download the program and see the previous example for additional details.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in algorithms, graphics, mathematics | Tagged , , , , , , , , , | Leave a comment

Draw a filled spiral in C#

[spiral]

My post Draw an Archimedes spiral in C# explained how to draw multiple Archimedes spirals starting at a common center point. This post shows how you can fill the spaces between the spirals with colors.

The basic idea is to make a polygon that follows the points along one spiral and then comes back along the reversed points from an adjacent spiral. That much would be interesting enough, but there are three details involving alignment, ending distance, and filling that make this extra tricky.

Alignment

[spiral]

In the previous example, each spiral expands until it its radius was larger than the distance from the spiral’s center to the farthest corner of the drawing area. Because the spirals use different offsets, they span different angles. That means the end of one spiral may be far from the beginning of the next. The picture on the right shows the result. It’s interesting, but not what we’re after.

One solution is to calculate the largest angle max_theta that any spiral must reach to surround the drawing area. Then you can generate points on each spiral until the variable theta plus the spiral’s offset exceeds max_theta.

The equation for an Archimedes spiral is r = A * θ, so solving for θ gives θ = r / A. If we plug in the distance to the farthest corner of the drawing area, we get max_theta = max_distance / A.

Now if each spiral ends when its theta + offset values exceeds max_theta, then the spiral ends will be near each other so they should form usable polygons. That leads to the second problem.

Ending Distance

[spiral]

In the earlier example, a spiral expanded until its radius was larger than the distance from the spiral’s center to the farthest corner of the drawing area. The picture on the right shows what happens if the spirals are only extended that far. This problem actually has two features.

First, some of the spirals don’t go far enough. If you look closely at the picture, you can probably guess that purple band should extend and cut into the drawing rectangle again in its lower left corner. The problem is that this spiral starts pointing upward, so doesn’t go as far around the circle as the red band, which starts pointing to the right.

A second potential problem is that the filled areas must include the area outside of the outermost spiral. If not only need to extend the second spiral to define the outer
edge of the purple band, we also need to extend the second and possibly third spirals to define the outer edges of the other bands.

We can do all of that quite easily by adding 2 π to max_theta to make every spiral take another lap around the center.

Filling

[spiral]

The final problem deals with the way the bands are filled. The obvious approach is to fill the area between spiral i and spiral i + 1. You can use the modulus operator (%) to wrap around to the beginning when you reach the last spiral. Unfortunately, even though the spirals all start at the same center, the first spiral isn’t adjacent to the last one. If you fill the area between those two spirals, you get the picture on the right.

The example solves this problem by simply creating one extra spiral outside all of the others. For example, if you want to draw three spirals, then the program creates four. Then, instead of filling the area between the first and last spirals, it fills the area between spiral number three and spiral number four.

The Program

This example uses the GetSpiralPoints method to generate the points on a spiral. That method is similar to the one used by the previous example. The only difference is that the previous version expands the spiral until r is big enough to cover the drawing rectangle, while the new version expands the spiral until theta reaches max_theta. See the previous example for a description of that method.

This example’s other main piece of code is the following Paint event handler.

// Draw the spiral(s).
private void picSpiral_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.Clear(picSpiral.BackColor);
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
    try
    {
        float A = float.Parse(txtA.Text);
        int num_spirals = int.Parse(txtNumSpirals.Text);

        // Angular spacing between different spirals.
        float d_start = (float)(2 * Math.PI / num_spirals);

        // The angle where the next spiral starts.
        float start_angle = 0;

        // Center point.
        PointF center = new PointF(
            picSpiral.ClientSize.Width / 2,
            picSpiral.ClientSize.Height / 2);

        // Draw axes.
        e.Graphics.DrawLine(Pens.Black,
            center.X, 0,
            center.X, picSpiral.ClientSize.Height);
        e.Graphics.DrawLine(Pens.Black,
            0, center.Y,
            picSpiral.ClientSize.Width, center.Y);

        // Draw the spiral on only part of the PictureBox.
        Rectangle rect = new Rectangle(25, 50, 150, 150);

        // Find the maximum distance to the rectangle's corners.
        float max_dist = Distance(center, rect);

        // Calculate the maximum theta value that we need to go to.
        float max_theta = max_dist / A + 2 * (float)Math.PI;

        // Get points defining the spirals.
        List<List<PointF>> spiral_points = new List<List<PointF>>();

        // Get the spirals' points.
        for (int i = 0; i < num_spirals + 1; i++)
        {
            spiral_points.Add(GetSpiralPoints(
                center, A, start_angle, max_theta));
            start_angle += d_start;
        }

        // Fill the areas between the spirals.
        for (int i = 0; i <= num_spirals; i++)
        {
            // Make a list holding the next spiral's points.
            List<PointF> points = new List<PointF>(spiral_points[i]);

            // Add the following spiral's points reversed.
            List<PointF> points2 =
                new List<PointF>(spiral_points[i + 1]);
            points2.Reverse();
            points.AddRange(points2);

            e.Graphics.FillPolygon(
                SpiralBrushes[i % SpiralBrushes.Length],
                points.ToArray());

            // Optional: Outline the spiral's polygon.
            using (Pen pen = new Pen(Color.Black, 1))
            {
                e.Graphics.DrawLines(pen, points.ToArray());
            }
        }

        // Draw the target rectangle.
        e.Graphics.DrawRectangle(Pens.Black, rect);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

This method reads the parameters that you entered and calculates the angular offsets between the spirals as in the previous example. It also finds the drawing area’s center point, draws axes, and creates a drawing rectangle as before.

The program then finds the maximum distance from the spiral’s center to the corners of the drawing area. Next, it plugs r = max_dist in the equation r = a * theta and solves for theta. That gives it the largest value of theta that it needs to use. It saves that value in max_theta.

Next, the code creates a list of lists to hold the points for the spirals. It then enters a loop where it calls GetSpiralPoints to find each spiral’s points and it adds them to the list. Notice that in this loop i runs from 0 to num_spirals so it creates num_spirals + 1 spirals.

After it has all of the spirals’ points, the method uses a loop to fill the spaces between them as. As described earlier, it fills the areas between adjacent spirals up to the extra spiral that it created at the end of the others.

To fill an area, the code makes a new points list initialized with the points for spiral number i. It then creates another list points2 holding the next spiral’s points, reverses that list, and add it to the end of the points list. The code then fills that area and optionally outlines it.

The program includes a few other details that are relatively straightforward. Download the example program to see those details.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in algorithms, graphics, mathematics | Tagged , , , , , , , , , , | 2 Comments

New Book: The Modern C# Challenge

[books]

My latest book, The Modern C# Challenge, is now available. It’s a collection of 100 programming challenges that let you test your ability in a wide variety of programming topics, many of which are not usually covered in traditional programming books. Example solutions are included for all of the problems and many demonstrate important programming concepts that can help you get the best performance out of your normal programming challenges.

To learn more about the book at Amazon, look below the buying options tabs for the “Key Features” heading and click the “Read more” link. The book is available for Kindle now and should be available in paperback on February 11, 2019.

Here’s the table of contents in brief.

  1. Mathematics
  2. Geometry
  3. Dates and Times
  4. Randomization
  5. Strings
  6. Files and Directories
  7. Advanced C# and .NET Features
  8. Simulations
  9. Cryptography

Some of the topics include files and directories, geometry, simulations, randomization, the yield keyword, factoring, prime factors, simulations, dynamic programming, statistics, combinations, permutations, recursion, Fibonacci numbers, binomial coefficients, greatest common divisors and least common multiples, amicable numbers, root finding, solving systems of linear equations, calculating areas, Monte Carlo simulation, convexity testing, working times with time zones, random walks, Roman numerals, generating passwords, making thumbnails, and cryptography.


Follow me on Twitter   RSS feed   Donate




Posted in algorithms, books, files, mathematics, puzzles | Tagged , , , , , , , , , , , , , , , , , , , , , , , | 1 Comment

Draw an Archimedes spiral in C#

[spiral]

An archimedes spiral is defined by the polar coordinate equation r = A * θ. It’s just as simple as that, and this would be a significantly shorter post except for one question: how do you know how big you need to make θ to make the spiral fill the drawing area? You cannot simply continue drawing the spiral until it leaves the drawing area because it comes back as it cuts through the drawing area’s corners.

For example, in the picture at the top of this post, the red spiral leaves the black rectangle, cuts back into it before reaching the next corner, leaves again shortly after that corner, misses a corner entirely, cuts the next two corners, and then grows too large to intersect the rectangle after that.

The distance from a point on the spiral to the spiral’s center is simply r. In the Archimedes spiral, r increases as θ increases, so once r is too big to intersect the drawing area, it never goes back, and that gives us the test we need. Simply find the corner of the drawing area that is farthest from the spiral’s center. When r is greater than the distance to that corner, the spiral has gone far enough.

The example program uses the following method to generate a spiral’s points.

// Return points that define a spiral.
private List<PointF> GetSpiralPoints(
    PointF center, float A,
    float angle_offset, float max_r)
{
    // Get the points.
    List<PointF> points = new List<PointF>();
    const float dtheta = (float)(5 * Math.PI / 180);    // Five degrees.
    for (float theta = 0; ; theta += dtheta)
    {
        // Calculate r.
        float r = A * theta;

        // Convert to Cartesian coordinates.
        float x, y;
        PolarToCartesian(r, theta + angle_offset, out x, out y);

        // Center.
        x += center.X;
        y += center.Y;

        // Create the point.
        points.Add(new PointF((float)x, (float)y));

        // If we have gone far enough, stop.
        if (r > max_r) break;
    }
    return points;
}

This method uses a loop to generate the points on the spiral. It calculates r, uses the PolarToCartesian method to convert the polar coordinates (r, θ) into Cartesian coordinates (x, y), adds the spiral’s center to the point to translate it into the correct position, and then adds the new point to the list.

Notice that the code adds the angle offset to theta when it calls PolarToCartesian. That makes the spiral start in a particular direction so the program can draw multiple interlaced spirals.

Next, if r is greater than the distance to the farthest corner of the drawing rectangle max_r, the code breaks out of its loop and returns the spiral’s points.

The following code shows the PolarToCartesian method.

// Convert polar coordinates into Cartesian coordinates.
private void PolarToCartesian(float r, float theta,
    out float x, out float y)
{
    x = (float)(r * Math.Cos(theta));
    y = (float)(r * Math.Sin(theta));
}

This method simply converts polar coordinates into Cartesian coordinates.

The only remaining code of any real interest is the following

// Pens to use for different spirals.
private Pen[] SpiralPens =
{
    Pens.Red, Pens.Green, Pens.Purple,
    Pens.Blue, Pens.Magenta, 
};

// Draw the spiral(s).
private void picSpiral_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.Clear(picSpiral.BackColor);
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
    try
    {
        float A = float.Parse(txtA.Text);
        int num_spirals = int.Parse(txtNumSpirals.Text);

        // Angular spacing between different spirals.
        float d_start = (float)(2 * Math.PI / num_spirals);

        // The angle where the next spiral starts.
        float start_angle = 0;

        // Center point.
        PointF center = new PointF(
            picSpiral.ClientSize.Width / 2,
            picSpiral.ClientSize.Height / 2);

        // Draw axes.
        e.Graphics.DrawLine(Pens.Black,
            center.X, 0,
            center.X, picSpiral.ClientSize.Height);
        e.Graphics.DrawLine(Pens.Black,
            0, center.Y,
            picSpiral.ClientSize.Width, center.Y);

        // Draw the spiral on only part of the PictureBox.
        Rectangle rect = new Rectangle(25, 50, 150, 150);

        // Find the maximum distance to the rectangle's corners.
        float max_r = Distance(center, rect);

        // Draw the spirals.
        for (int i = 0; i < num_spirals; i++)
        {
            List<PointF> points =
                GetSpiralPoints(center, A, start_angle, max_r);
            e.Graphics.DrawLines(SpiralPens[i % SpiralPens.Length],
                points.ToArray());
            start_angle += d_start;
        }

        // Draw the target rectangle.
        e.Graphics.DrawRectangle(Pens.Black, rect);
    }
        catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

This code defines an array of colors to use when drawing spirals.

The picSpiral control’s Paint event draws the spirals. It gets the user-entered parameters. It then divides 2π radians by the number of spirals to get the angular spacing between the interlocked spirals.

The code finds the center of the PictureBox and uses it as the center of its spirals. It then draws axes running through that center and makes a test rectangle where it will fit the spirals.

Next, the code calls the Distance method to find the distance to the drawing area’s farthest corner. It then enters a loop to draw each of the spirals, increasing each one’s angle offset by d_start so they start out pointing in different directions. The code calls the GetSpiralPoints method to get the spiral’s points and then uses the Graphics object’s DrawLines method to draw the spiral.

The code finishes by drawing the target rectangle so you can see that the spirals are big enough to cover the rectangle.

The program includes a few other details such as the Distance method that are relatively straightforward. Download the example program to see additional details.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in algorithms, graphics, mathematics | Tagged , , , , , , , , , | 2 Comments

Make a custom component in C#


[custom component]

There are a couple of ways that you can approach this problem. In this post, I’ll describe two: subclassing from Component and making a control that is invisible at runtime.

Subclassing From Component

To make a true component, simply make a class that inherits from the System.ComponentModel.Component class. If you’re using a newer version of Visual Studio, open the Project menu, select Add Component, enter a component name (I called this one MyComponent), and click Add.

If you’re using an older version of Visual Studio, then the Project menu may not have an Add Component command. In that case, simply create a new class and make it inherit from System.ComponentModel.Component.

To change the icon that the component displays in the Component Tray, add a ToolboxBitmap attribute and specify the name of the 16×16 pixel image file that the component should use.

You can include the image file in a couple of ways. For this example, I embedded the file in the project. To do that, open the Project menu, select Add Existing Item, select the file, and click Add. Then select the file in Project Explorer and set its Build Action property to Embedded Resource.

When you build the project, the component will add itself to the Form Designer’s Toolbox. Unfortunately, it won’t display its toolbox icon. (Yeah, I know.) To make it display its icon in the Toolbox, you must add it to the Toolbox manually.

To do that, right-click on the Toolbox and select Choose Items. Click the Browse button and select the compiled project that contains the component. (You may need to uncheck the component in the Choose Toolbox Items dialog first and then re-add the compiled project. This doesn’t seem to work very reliably, at least for me. Perhaps it works in newer versions of Visual Studio.)

The following code shows the example’s MyComponent class.

using System.ComponentModel;
using System.Windows.Forms;

namespace howto_custom_component
{
    [System.Drawing.ToolboxBitmap(typeof(MyComponent), "Small Smiley.png")]
    public class MyComponent : Component
    {
        public void SayHello()
        {
            MessageBox.Show("Hello", "MyComponent", MessageBoxButtons.OK);
        }
    }
}

In addition to the ToolboxBitmap attribute, this code defines a SayHello method that simply displays a message box.

Making a Control that is Invisible at Runtime

Another approach is to make a control that behaves sort of like a component. With this approach, the control displays itself on the form at design time but is invisible at runtime. (Sort of like a VB 6 component, if you can remember that far back.)

To do that, open the Project menu and select Add User Control. Enter a name for the control (I used the name Smiler) and click Add. Then, on the Control Designer, add any constituent controls that you want the custom component to contain.

To make the component display something at design time, set its BackgroundImage property to an image. Set its Size property to match the image’s size. In this example, I used a 32×32 pixel image, so I set the Size property to 32, 32.

Next, add code similar to the following to handle the control’s Resize event.

// Size the control to fit its background image.
private void Smiler_Resize(object sender, EventArgs e)
{
    Size = BackgroundImage.Size;
}

This code sets the control’s size to match that of its background image. When you add a Smiler to a form at design time, it will always have this size.

Next, add a Load event handler similar to the following to the control class.

// Hide the control at runtime.
private void Smiler_Load(object sender, EventArgs e)
{
    if (!DesignMode) Visible = false;
}

This method checks the component’s inherited DesignTime property to see if the control is running at design time or runtime. Those are the times for the form containing the control. When you place a control on a form, that’s design time. When you run the program, that’s runtime.

If the control is in runtime, the code sets its Visible property to false to hide it.

The example’s also defines the following SayHi method.

// Display a hello message box.
public void SayHi()
{
    MessageBox.Show("Hi", "Hi", MessageBoxButtons.OK);
}

This method simply displays a message box that says, “Hi.”

Using the Component

When you build the solution, the component or control should appear in the Form Designer’s Toolbox. You can then place them on the form as usual.

NOTE: When you download the example project, you must build it before the component and control will be usable.

The example program displays a button that executes the following code.

private void btnSayHi_Click(object sender, EventArgs e)
{
    smiler1.SayHi();
    myComponent1.SayHello();
}

This code calls a Smiler control’s SayHi method and then calls a MyComponent object’s SayHello method.

The left part of the picture at the top of this post you can see the form in the Form Designer. On the form, you can see the Smiler control named smiler1. Below the form, you can see the MyComponent component named myComponent1 in the Component Tray.

On the right side of the picture, you can see the form at runtime. Here the smiler1 control is invisible. (The MyComponent component is also invisible, but that’s less impressive. You would expect a component to be hidden at runtime.)

In the middle of the picture, you can see the smiler1 control’s dialog.

Download the example program to experiment with it and to see additional details.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in controls | Tagged , , , , , , , | 1 Comment

Tile a board with randomly colored trominoes in C#

[example]

The post Tile a board with colored trominoes in C#explains how to color a tromino filing so no two adjacent trominoes share the same color. That example basically tried every possible color for each of the trominoes until it found one that worked.

Unfortunately, that approach makes the algorithm prefer colors near the beginning of the color list. That’s not a big problem with the trominoes because the tiling pattern requires the program to use a lot of colors, but the result can look strange when you color some other maps. In those cases, the coloring uses the first few colors the most and only occasionally uses the other colors. For example, the result might be a map that uses lots of yellow and blue areas and only one or two red areas.

This example examines the allowed colors in random order so it will use more of the colors that are later in the list of allowed colors. The program also uses more colors than the previous version, so the trominoes look more randomly colored.

The only change to the program is in the following code snippet where the program tries different colors for a tromino.

// Try each of the colors for this Chair.
Chair this_chair = Chairs[start_chair];
int[] color_nums =
    Enumerable.Range(0, Chair.BgBrushes.Length).ToArray();
color_nums.Randomize();
foreach (int color_num in color_nums)
{
    if (this_chair.ColorAllowed(color_num))
    {
        this_chair.BgBrushNum = color_num;
        if (FindColoring(start_chair + 1)) return true;
    }
}

This code creates an array named color_nums that contains the numbers 0, 1, 2, up to one less than the number of colors in the Chair.BgBrushes array. It then uses the Randomize extension method described shortly to randomize the color_nums array. The code then loops through the randomized colors and tries each until it finds one that works.

The following code shows the Randomize extension method.

// Randomize an array.
public static void Randomize<T>(this T[] items)
{
    // For each spot in the array, pick
    // a random item to swap into that spot.
    for (int i = 0; i < items.Length - 1; i++)
    {
        int j = Rand.Next(i, items.Length);
        T temp = items[i];
        items[i] = items[j];
        items[j] = temp;
    }
}

This method loops through the spots in the array. For each spot, it picks a random following spot and swaps the items in those two positions. When it is done, each of the array’s items may have been swapped into any of the array’s positions with equal probability.

See the previous example and download this example’s program to see additional details.


Download Example   Follow me on Twitter   RSS feed   Donate




Posted in algorithms, drawing, graphics, mathematics, recursion | Leave a comment