Example #1
0
        // Use the idea from the code in following links
        // https://en.wikipedia.org/wiki/Xiaolin_Wu%27s_line_algorithm
        // https://rosettacode.org/wiki/Xiaolin_Wu%27s_line_algorithm#C.23
        public void XiaolinWu(Line line2D, Color color)
        {
            Point p1 = line2D.p1;
            Point p2 = line2D.p2;

            if (line2D.isPoint())
            {
                bitmap.SetPixel(p1.X, p1.Y, color);
                return;
            }

            int   Dx = p2.X - p1.X;
            int   Dy = p2.Y - p1.Y;
            int   x_incre, y_incre;
            float gradient;

            // if Dy, Dx is negative -> change step in each increment to -1
            y_incre = Dy < 0 ? -1 : 1;
            x_incre = Dx < 0 ? -1 : 1;

            // x incre faster than y incre
            if (Math.Abs(Dx) > Math.Abs(Dy))
            {
                gradient = Math.Abs(Dy) / (float)Math.Abs(Dx) * y_incre;

                int   x_draw  = p1.X;
                float float_y = p1.Y;

                while (x_draw != p2.X)
                {
                    float f_part_y  = float_y - (float)Math.Floor(float_y);
                    float rf_part_y = 1 - f_part_y;

                    int y_draw = (int)Math.Floor(float_y);
                    if (y_draw >= 0 && y_draw < bitmap.Height)
                    {
                        int alpha = (int)Math.Round(rf_part_y * 255);

                        bitmap.SetPixel(x_draw, y_draw,
                                        Color.FromArgb(alpha, color));
                    }
                    if (y_draw + y_incre >= 0 && y_draw + y_incre < bitmap.Height)
                    {
                        int alpha = (int)Math.Round(f_part_y * 255);

                        bitmap.SetPixel(x_draw, y_draw + y_incre,
                                        Color.FromArgb(alpha, color));
                    }

                    x_draw  += x_incre;
                    float_y += gradient;
                }
            }
            // y incre faster than x incre
            else
            {
                gradient = Math.Abs(Dx) / (float)Math.Abs(Dy) * x_incre;

                int   y_draw  = p1.Y;
                float float_x = p1.X;

                while (y_draw != p2.Y)
                {
                    float f_part_x  = float_x - (float)Math.Floor(float_x);
                    float rf_part_x = 1 - f_part_x;

                    int x_draw = (int)Math.Floor(float_x);
                    if (x_draw >= 0 && x_draw < bitmap.Width)
                    {
                        int alpha = (int)Math.Round(rf_part_x * 255);

                        bitmap.SetPixel(x_draw, y_draw,
                                        Color.FromArgb(alpha, color));
                    }
                    if (x_draw + x_incre >= 0 && x_draw + x_incre < bitmap.Width)
                    {
                        int alpha = (int)Math.Round(f_part_x * 255);

                        bitmap.SetPixel(x_draw + x_incre, y_draw,
                                        Color.FromArgb(alpha, color));
                    }

                    y_draw  += y_incre;
                    float_x += gradient;
                }
            }
        }
Example #2
0
        // Use the idea from the code in following links
        // https://csustan.csustan.edu/~tom/Lecture-Notes/Graphics/Bresenham-Line/Bresenham-Line.pdf
        public void Bresenham(Line line2D, Color color)
        {
            Point p1 = line2D.p1;
            Point p2 = line2D.p2;

            if (line2D.isPoint())
            {
                bitmap.SetPixel(p1.X, p1.Y, color);
                return;
            }

            int Dx = p2.X - p1.X;
            int Dy = p2.Y - p1.Y;
            int x_increment, y_increment, x_draw, y_draw;

            // if Dy, Dx is negative -> change step in each increment to -1
            // if slope > 1 or < -1, swap Dx with Dy, x with y
            if (Dy < 0)
            {
                Dy          = -Dy;
                y_increment = -1;
            }
            else
            {
                y_increment = 1;
            }

            if (Dx < 0)
            {
                Dx          = -Dx;
                x_increment = -1;
            }
            else
            {
                x_increment = 1;
            }

            // Explain Bresenham algorithm
            // From Point(x_i, y_i) next to Point(x_(i+1), y)
            // Need to know y near y_i or y_i + 1
            // d1 = y - y_i
            // d2 = (y_i + 1) - y
            // if d1 - d2 < 0, y = y_i
            // otherwise y = y_i + 1
            //
            // d1 - d2 = 2y - 2y_i - 1
            // as know Point(x_(i+1), y) on the line,
            // so y = (Dy/Dx) * x_(i+1) + b with b = y_0 - (Dy/Dx) * x0 and x_(i+1) = x_i + 1
            // d1 - d2 = 2(Dy/Dx) * x_i - 2y_i + (2b - 1 + 2(Dy/Dx))
            //
            // p_i = Dx * (d1 - d2)
            // d1 - d2 < 0 <=> p_i < 0 (Use p_i to avoid divide to Dx)
            // p_i = 2Dy * x_i - 2Dx * y_i + (2b * Dx - Dx + 2Dy)
            //
            // p_(i+1) - p_i = 2Dy - 2Dx * (y_(i+1) - y_i)
            //
            // with p_i < 0
            //      y_(i+1) = y_i
            //      p_(i+1) = p_i + 2Dy
            // with p_i >= 0
            //      y_(i+1) = y_i + 1
            //      p_(i+1) = p_i + 2Dy - 2Dx
            //
            // p_0 = 2Dy * x_0 - 2Dx * y_0 + (2b * Dx - Dx + 2Dy)
            // with b = y_0 - (Dy/Dx) * x0
            // p_0 = 2Dy - Dx

            // value of x, y actually draw
            x_draw = p1.X;
            y_draw = p1.Y;
            bitmap.SetPixel(x_draw, y_draw, color);

            // error_step is p_i
            int error_step;

            if (Dx > Dy)
            {
                // init error_step with p_0
                error_step = 2 * Dy - Dx;
                while (x_draw != p2.X)
                {
                    x_draw += x_increment;
                    if (error_step < 0)
                    {
                        error_step += 2 * Dy;
                    }
                    else
                    {
                        y_draw     += y_increment;
                        error_step += 2 * Dy - 2 * Dx;
                    }
                    bitmap.SetPixel(x_draw, y_draw, color);
                }
            }
            else
            {
                error_step = 2 * Dx - Dy;
                while (y_draw != p2.Y)
                {
                    if (error_step < 0)
                    {
                        error_step += 2 * Dx;
                    }
                    else
                    {
                        x_draw     += x_increment;
                        error_step += 2 * Dx - 2 * Dy;
                    }
                    y_draw += y_increment;
                    bitmap.SetPixel(x_draw, y_draw, color);
                }
            }
        }
Example #3
0
        // Bresenham and MidPoint draw line is actually the same
        public void MidPoint(Line line2D, Color color)
        {
            Point p1 = line2D.p1;
            Point p2 = line2D.p2;

            if (line2D.isPoint())
            {
                bitmap.SetPixel(p1.X, p1.Y, color);
                return;
            }

            int Dx = p2.X - p1.X;
            int Dy = p2.Y - p1.Y;
            int x_increment, y_increment, x_draw, y_draw;

            // if Dy, Dx is negative -> change step in each increment to -1
            // if slope > 1 or < -1, swap Dx with Dy, x with y
            if (Dy < 0)
            {
                Dy          = -Dy;
                y_increment = -1;
            }
            else
            {
                y_increment = 1;
            }

            if (Dx < 0)
            {
                Dx          = -Dx;
                x_increment = -1;
            }
            else
            {
                x_increment = 1;
            }

            // Explain MidPoint algorithm
            // in Bresenham algorithm, use d1 - d2 to determine y_(i+1)
            // in MidPoint, use y_i + 1/2
            //
            // F(x, y) = Ax + By + C, A > 0
            // F(x, y) < 0 above the line
            //         > 0 below the line
            //
            // mid point is Point(x_(i+1), y_i + 1/2)
            // p_i = 2F(x_(i+1), y_i + 1/2)
            // p_i < 0, line in half below mid point
            // p_i > 0, line in half above mid point
            //
            // p_(i+1) = p_i + 2Dy - 2Dx * (y_(i+1) - y_i)
            // p_0 = 2Dy - Dx
            // same as Bresenham

            // value of x, y actually draw
            x_draw = p1.X;
            y_draw = p1.Y;
            bitmap.SetPixel(x_draw, y_draw, color);

            // error_step is p_i
            int error_step;

            if (Dx > Dy)
            {
                // init error_step with p_0
                error_step = 2 * Dy - Dx;
                while (x_draw != p2.X)
                {
                    x_draw += x_increment;
                    if (error_step < 0)
                    {
                        error_step += 2 * Dy;
                    }
                    else
                    {
                        y_draw     += y_increment;
                        error_step += 2 * Dy - 2 * Dx;
                    }
                    bitmap.SetPixel(x_draw, y_draw, color);
                }
            }
            else
            {
                error_step = 2 * Dx - Dy;
                while (y_draw != p2.Y)
                {
                    if (error_step < 0)
                    {
                        error_step += 2 * Dx;
                    }
                    else
                    {
                        x_draw     += x_increment;
                        error_step += 2 * Dx - 2 * Dy;
                    }
                    y_draw += y_increment;
                    bitmap.SetPixel(x_draw, y_draw, color);
                }
            }
        }