Click here to Skip to main content
15,887,980 members
Home / Discussions / Algorithms
   

Algorithms

 
AnswerRe: A simple algorithm request Pin
Dr.Walt Fair, PE24-Mar-10 15:29
professionalDr.Walt Fair, PE24-Mar-10 15:29 
AnswerRe: A simple algorithm request Pin
Luc Pattyn24-Mar-10 15:54
sitebuilderLuc Pattyn24-Mar-10 15:54 
QuestionFilling a cylinder or a tube Pin
Valeriant20-Mar-10 17:46
Valeriant20-Mar-10 17:46 
AnswerRe: Filling a cylinder or a tube Pin
Moreno Airoldi21-Mar-10 0:08
Moreno Airoldi21-Mar-10 0:08 
GeneralRe: Filling a cylinder or a tube Pin
Valeriant21-Mar-10 4:46
Valeriant21-Mar-10 4:46 
GeneralRe: Filling a cylinder or a tube Pin
Moreno Airoldi21-Mar-10 8:33
Moreno Airoldi21-Mar-10 8:33 
GeneralRe: Filling a cylinder or a tube Pin
Valeriant21-Mar-10 16:36
Valeriant21-Mar-10 16:36 
GeneralRe: Filling a cylinder or a tube Pin
Moreno Airoldi25-Mar-10 2:06
Moreno Airoldi25-Mar-10 2:06 
Ok I managed to take a couple of minutes off and write some code. Sorry it took me so long, but I'm busy as a bee these days. Smile | :)

Please consider that the code I'm presenting here is quite raw, and you'll probably want to clean it up and make a few changes.

I decided to give you a start-from-scratch idea, which is easier to implement. Please remember that drawing a good looking circle or ellipse is not necessarily an easy task. Have a look on the web, you'll see there are a bunch of good algorithms to do that.

The simplest way of drawing an ellipse is something like what you found on wikipedia. In my example you'll see a very similar approach. I just added rotation, which you need in order to draw your cylinder, and optimized the code (you don't have to go through the whole 360 degrees, but only half of it, cause the rest is specular).

private class EllipseOuterXPoints
{
    internal double left_x = double.MaxValue;
    internal double left_y = double.MaxValue;
    internal double right_x = double.MinValue;
    internal double right_y = double.MinValue;

    internal void CheckPoint(double x, double y)
    {
        if (x < left_x)
        {
            left_x = x;
            left_y = y;
        }

        if (x > right_x)
        {
            right_x = x;
            right_y = y;
        }
    }
}

private EllipseOuterXPoints DrawEllipse(Graphics g, double center_x, double center_y, double semi_minor, double semi_major, double angle)
{
    // *** Return value ***
    EllipseOuterXPoints OuterPoints = new EllipseOuterXPoints();

    // *** Rotation angle in radians, sine and cosine ***
    double beta = -angle * (Math.PI / 180);
    double sin_beta = Math.Sin(beta);
    double cos_beta = Math.Cos(beta);

    // *** Calculate increment by a rough estimation of the number of points needed (empirical!) ***
    double increment = (Math.PI * 2) / (semi_major * 2);

    // *** Draw the ellipse ***
    double sin_alpha;
    double cos_alpha;
    double x1 = 0;
    double y1 = 0;
    double x2 = 0;
    double y2 = 0;
    double prev_x1 = 0;
    double prev_y1 = 0;
    double prev_x2 = 0;
    double prev_y2 = 0;
    double first_x1 = 0;
    double first_y1 = 0;
    Pen mypen = new Pen(Color.Black);
    for (double alpha = 0; alpha < Math.PI; alpha += increment)
    {
        sin_alpha = Math.Sin(alpha);
        cos_alpha = Math.Cos(alpha);

        x1 = center_x + ((semi_major * cos_alpha * cos_beta) - (semi_minor * sin_alpha * sin_beta));
        y1 = center_y + ((semi_major * cos_alpha * sin_beta) + (semi_minor * sin_alpha * cos_beta));

        sin_alpha = Math.Sin(alpha * 2);
        cos_alpha = Math.Cos(alpha * 2);

        x2 = center_x + ((semi_major * cos_alpha * cos_beta) - (semi_minor * sin_alpha * sin_beta));
        y2 = center_y + ((semi_major * cos_alpha * sin_beta) + (semi_minor * sin_alpha * cos_beta));

        if (alpha == 0)
        {
            first_x1 = x1;
            first_y1 = y1;
        }
        else
        {
            g.DrawLine(mypen, (float)prev_x1, (float)prev_y1, (float)x1, (float)y1);
            g.DrawLine(mypen, (float)prev_x2, (float)prev_y2, (float)x2, (float)y2);
        }

        // *** Find the outer X points ***
        OuterPoints.CheckPoint(x1, y1);
        OuterPoints.CheckPoint(x2, y2);

        prev_x1 = x1;
        prev_y1 = y1;

        prev_x2 = x2;
        prev_y2 = y2;
    }
    g.DrawLine(mypen, (float)x2, (float)y2, (float)first_x1, (float)first_y1);

    // *** Return outer X points ***
    return OuterPoints;
}


First point you should note is the "magic" taking place here:

// *** Calculate increment by a rough estimation of the number of points needed (empirical!) ***
double increment = (Math.PI * 2) / (semi_major * 2);


This is what allows you to draw a decent-looking ellipse. The number of points you calculate on the circumference is derived by a brute empirical calculation based on the major axis length. Not that fine, not that beautiful, but it works. Smile | :)

Secondly, note that while I draw the ellipse I keep a record of the leftmost and rightmost points (this is based only on the X axis, since I didn't manage rotation on the Y axis!). These are the outer points you will connect to create your cylinder.

So, just call this code inside a Paint event with something like:

private void picCanvas_Paint(object sender, PaintEventArgs e)
{
    EllipseOuterXPoints OuterPoints1 = DrawEllipse(e.Graphics, picCanvas.Size.Width / 2, picCanvas.Size.Height / 4, picCanvas.Size.Height / 8, picCanvas.Size.Width / 4, 10);
    EllipseOuterXPoints OuterPoints2 = DrawEllipse(e.Graphics, picCanvas.Size.Width / 2, (picCanvas.Size.Height / 4) * 3, picCanvas.Size.Height / 8, picCanvas.Size.Width / 4, 10);

    Pen mypen = new Pen(Color.Black);
    e.Graphics.DrawLine(mypen, (float)OuterPoints1.left_x, (float)OuterPoints1.left_y, (float)OuterPoints2.left_x, (float)OuterPoints2.left_y);
    e.Graphics.DrawLine(mypen, (float)OuterPoints1.right_x, (float)OuterPoints1.right_y, (float)OuterPoints2.right_x, (float)OuterPoints2.right_y);
}


And there is your (hopefully) good looking cylinder!
Have a look at the result here[^].

I think this is all you need to get you started. Good luck! Smile | :)
2+2=5 for very large amounts of 2
(always loved that one hehe!)

GeneralRe: Filling a cylinder or a tube Pin
Valeriant25-Mar-10 19:34
Valeriant25-Mar-10 19:34 
GeneralRe: Filling a cylinder or a tube Pin
Moreno Airoldi25-Mar-10 22:24
Moreno Airoldi25-Mar-10 22:24 
GeneralRe: Filling a cylinder or a tube Pin
Moreno Airoldi2-Apr-10 23:02
Moreno Airoldi2-Apr-10 23:02 
GeneralRe: Filling a cylinder or a tube Pin
Valeriant6-Apr-10 2:21
Valeriant6-Apr-10 2:21 
GeneralRe: Filling a cylinder or a tube Pin
Moreno Airoldi6-Apr-10 4:11
Moreno Airoldi6-Apr-10 4:11 
GeneralRe: Filling a cylinder or a tube Pin
Andy_L_J25-Mar-10 19:50
Andy_L_J25-Mar-10 19:50 
GeneralRe: Filling a cylinder or a tube Pin
Moreno Airoldi25-Mar-10 22:27
Moreno Airoldi25-Mar-10 22:27 
QuestionFirewall Bypass via Compression Encoding Pin
Khalib Ismail19-Mar-10 16:05
Khalib Ismail19-Mar-10 16:05 
AnswerRe: Firewall Bypass via Compression Encoding Pin
Michel Godfroid1-Apr-10 6:12
Michel Godfroid1-Apr-10 6:12 
Question2D collision detection between a square and rectangle [modified] Pin
venomation8-Mar-10 13:10
venomation8-Mar-10 13:10 
AnswerRe: 2D collision detection between a square and rectangle Pin
Luc Pattyn8-Mar-10 13:42
sitebuilderLuc Pattyn8-Mar-10 13:42 
GeneralRe: 2D collision detection between a square and rectangle Pin
venomation8-Mar-10 13:53
venomation8-Mar-10 13:53 
GeneralRe: 2D collision detection between a square and rectangle Pin
venomation8-Mar-10 14:49
venomation8-Mar-10 14:49 
QuestionDesigning Parallel Algorithms Pin
ProtoBytes2-Mar-10 7:43
ProtoBytes2-Mar-10 7:43 
AnswerRe: Designing Parallel Algorithms Pin
Chris Losinger5-Mar-10 8:51
professionalChris Losinger5-Mar-10 8:51 
AnswerRe: Designing Parallel Algorithms [Modified - Spell Checked] [modified] Pin
ProtoBytes5-Mar-10 11:57
ProtoBytes5-Mar-10 11:57 
GeneralRe: Designing Parallel Algorithms [Modified - Spell Checked] Pin
Chris Losinger8-Mar-10 4:27
professionalChris Losinger8-Mar-10 4:27 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.