Algoritmo de dibujo de círculo de punto medio

El algoritmo de dibujo de círculo de punto medio es un algoritmo utilizado para determinar los puntos necesarios para rasterizar un círculo. 
 

Usamos el algoritmo del punto medio para calcular todos los puntos del perímetro del círculo en el primer octante y luego los imprimimos junto con sus puntos de espejo en los otros octantes. Esto funcionará porque un círculo es simétrico con respecto a su centro.

Circle octants

El algoritmo es muy similar al algoritmo de generación de línea de punto medio . Aquí, solo la condición de contorno es diferente.

Para cualquier píxel dado (x, y), el siguiente píxel a trazar es (x, y+1) o (x-1, y+1) . Esto se puede decidir siguiendo los pasos a continuación.

  1. Encuentre el punto medio p de los dos píxeles posibles, es decir (x-0.5, y+1)
  2. Si p está dentro o en el perímetro del círculo, trazamos el píxel (x, y+1), de lo contrario, si está fuera, trazamos el píxel (x-1, y+1)

Condición de contorno: se puede decidir si el punto medio se encuentra dentro o fuera del círculo mediante la fórmula: 
 

Dado un círculo con centro en (0,0) y radio r y un punto p(x,y) 
F(p) = x 2 + y 2 – r 2 
si F(p)<0, el punto está dentro del círculo
F (p)=0, el punto está en el perímetro
F(p)>0, el punto está fuera del círculo 
 

example

En nuestro programa, denotamos F(p) con P. El valor de P se calcula en el punto medio de los dos píxeles contendientes, es decir (x-0.5, y+1). Cada píxel se describe con un subíndice k.
 

P k = (X k — 0.5) 2 + (y k + 1) 2 – r 2 
Ahora, 
x k+1 = x k o x k-1 , y k+1 = y k +1
∴ P k+1 = (x k+1 – 0,5) 2 + (y k+1 +1) 2 – r 2 
= (x k+1 – 0,5) 2 + [(y k +1) + 1] 2 – r 2 
= ( x k+1 – 0.5) 2 + (y k +1)2 + 2(y k + 1) + 1 – r 2 
= (x k+1 – 0,5) 2 + [ – (x k – 0,5) 2 +(x k – 0,5) 2 ] + (y k + 1) 2 – r 2 + 2(y k + 1) + 1
= PAGS k + (x k+1 – 0.5) 2 – (x k – 0.5) 2 + 2(y k + 1) + 1 
= PAGS k + ( x 2 k+1 – x 2 k ) – (x k+1 – x k) + 2(y k + 1) + 1 
= P k + 2(y k +1) + 1, cuando P k <=0 es decir, el punto medio está dentro del círculo 
(x k+1 = x k
P k + 2(y k +1) – 2(x k – 1) + 1, cuando P k >0 Es decir, el punto medio está fuera del círculo (x k+1 = x k -1) 
 

El primer punto a trazar es (r, 0) en el eje x. El valor inicial de P se calcula de la siguiente manera:
 

P1 = (r – 0,5) 2 + (0+1) 2 – r 2 
= 1,25 – r 
= 1 -r (cuando se redondea)
 

Ejemplos: 
 

Input : Centre -> (0, 0), Radius -> 3
Output : (3, 0) (3, 0) (0, 3) (0, 3)
         (3, 1) (-3, 1) (3, -1) (-3, -1)
         (1, 3) (-1, 3) (1, -3) (-1, -3)
         (2, 2) (-2, 2) (2, -2) (-2, -2)

first point to be plotted

 
Input : Centre -> (4, 4), Radius -> 2
Output : (6, 4) (6, 4) (4, 6) (4, 6)
         (6, 5) (2, 5) (6, 3) (2, 3)
         (5, 6) (3, 6) (5, 2) (3, 2)

CPP

// C++ program for implementing
// Mid-Point Circle Drawing Algorithm
#include<iostream>
using namespace std;
 
// Implementing Mid-Point Circle Drawing Algorithm
void midPointCircleDraw(int x_centre, int y_centre, int r)
{
    int x = r, y = 0;
     
    // Printing the initial point on the axes
    // after translation
    cout << "(" << x + x_centre << ", " << y + y_centre << ") ";
     
    // When radius is zero only a single
    // point will be printed
    if (r > 0)
    {
        cout << "(" << x + x_centre << ", " << -y + y_centre << ") ";
        cout << "(" << y + x_centre << ", " << x + y_centre << ") ";
        cout << "(" << -y + x_centre << ", " << x + y_centre << ")\n";
    }
     
    // Initialising the value of P
    int P = 1 - r;
    while (x > y)
    {
        y++;
         
        // Mid-point is inside or on the perimeter
        if (P <= 0)
            P = P + 2*y + 1;
        // Mid-point is outside the perimeter
        else
        {
            x--;
            P = P + 2*y - 2*x + 1;
        }
         
        // All the perimeter points have already been printed
        if (x < y)
            break;
         
        // Printing the generated point and its reflection
        // in the other octants after translation
        cout << "(" << x + x_centre << ", " << y + y_centre << ") ";
        cout << "(" << -x + x_centre << ", " << y + y_centre << ") ";
        cout << "(" << x + x_centre << ", " << -y + y_centre << ") ";
        cout << "(" << -x + x_centre << ", " << -y + y_centre << ")\n";
         
        // If the generated point is on the line x = y then
        // the perimeter points have already been printed
        if (x != y)
        {
            cout << "(" << y + x_centre << ", " << x + y_centre << ") ";
            cout << "(" << -y + x_centre << ", " << x + y_centre << ") ";
            cout << "(" << y + x_centre << ", " << -x + y_centre << ") ";
            cout << "(" << -y + x_centre << ", " << -x + y_centre << ")\n";
        }
    }
}
 
// Driver code
int main()
{
    // To draw a circle of radius 3 centered at (0, 0)
    midPointCircleDraw(0, 0, 3);
    return 0;
}

C

// C program for implementing
// Mid-Point Circle Drawing Algorithm
#include<stdio.h>
 
// Implementing Mid-Point Circle Drawing Algorithm
void midPointCircleDraw(int x_centre, int y_centre, int r)
{
    int x = r, y = 0;
     
    // Printing the initial point on the axes
    // after translation
    printf("(%d, %d) ", x + x_centre, y + y_centre);
     
    // When radius is zero only a single
    // point will be printed
    if (r > 0)
    {
        printf("(%d, %d) ", x + x_centre, -y + y_centre);
        printf("(%d, %d) ", y + x_centre, x + y_centre);
        printf("(%d, %d)\n", -y + x_centre, x + y_centre);
    }
     
    // Initialising the value of P
    int P = 1 - r;
    while (x > y)
    {
        y++;
         
        // Mid-point is inside or on the perimeter
        if (P <= 0)
            P = P + 2*y + 1;
             
        // Mid-point is outside the perimeter
        else
        {
            x--;
            P = P + 2*y - 2*x + 1;
        }
         
        // All the perimeter points have already been printed
        if (x < y)
            break;
         
        // Printing the generated point and its reflection
        // in the other octants after translation
        printf("(%d, %d) ", x + x_centre, y + y_centre);
        printf("(%d, %d) ", -x + x_centre, y + y_centre);
        printf("(%d, %d) ", x + x_centre, -y + y_centre);
        printf("(%d, %d)\n", -x + x_centre, -y + y_centre);
         
        // If the generated point is on the line x = y then
        // the perimeter points have already been printed
        if (x != y)
        {
            printf("(%d, %d) ", y + x_centre, x + y_centre);
            printf("(%d, %d) ", -y + x_centre, x + y_centre);
            printf("(%d, %d) ", y + x_centre, -x + y_centre);
            printf("(%d, %d)\n", -y + x_centre, -x + y_centre);
        }
    }
}
 
// Driver code
int main()
{
    // To draw a circle of radius 3 centered at (0, 0)
    midPointCircleDraw(0, 0, 3);
    return 0;
}

Java

// Java program for implementing
// Mid-Point Circle Drawing Algorithm
class GFG {
     
    // Implementing Mid-Point Circle
    // Drawing Algorithm
    static void midPointCircleDraw(int x_centre,
                            int y_centre, int r)
    {
         
        int x = r, y = 0;
     
        // Printing the initial point
        // on the axes after translation
        System.out.print("(" + (x + x_centre)
                + ", " + (y + y_centre) + ")");
     
        // When radius is zero only a single
        // point will be printed
        if (r > 0) {
             
            System.out.print("(" + (x + x_centre)
                + ", " + (-y + y_centre) + ")");
                 
            System.out.print("(" + (y + x_centre)
                 + ", " + (x + y_centre) + ")");
                  
            System.out.println("(" + (-y + x_centre)
                   + ", " + (x + y_centre) + ")");
        }
     
        // Initialising the value of P
        int P = 1 - r;
        while (x > y) {
             
            y++;
         
            // Mid-point is inside or on the perimeter
            if (P <= 0)
                P = P + 2 * y + 1;
         
            // Mid-point is outside the perimeter
            else {
                x--;
                P = P + 2 * y - 2 * x + 1;
            }
         
            // All the perimeter points have already
            // been printed
            if (x < y)
                break;
         
            // Printing the generated point and its
            // reflection in the other octants after
            // translation
            System.out.print("(" + (x + x_centre)
                    + ", " + (y + y_centre) + ")");
                     
            System.out.print("(" + (-x + x_centre)
                    + ", " + (y + y_centre) + ")");
                     
            System.out.print("(" + (x + x_centre) +
                    ", " + (-y + y_centre) + ")");
                     
            System.out.println("(" + (-x + x_centre)
                    + ", " + (-y + y_centre) + ")");
         
            // If the generated point is on the
            // line x = y then the perimeter points
            // have already been printed
            if (x != y) {
                 
                System.out.print("(" + (y + x_centre)
                      + ", " + (x + y_centre) + ")");
                       
                System.out.print("(" + (-y + x_centre)
                      + ", " + (x + y_centre) + ")");
                       
                System.out.print("(" + (y + x_centre)
                      + ", " + (-x + y_centre) + ")");
                       
                System.out.println("(" + (-y + x_centre)
                    + ", " + (-x + y_centre) +")");
            }
        }
    }
     
    // Driver code
    public static void main(String[] args) {
         
        // To draw a circle of radius
        // 3 centered at (0, 0)
        midPointCircleDraw(0, 0, 3);
    }
}
 
// This code is contributed by Anant Agarwal.

Python3

# Python3 program for implementing
# Mid-Point Circle Drawing Algorithm
 
def midPointCircleDraw(x_centre, y_centre, r):
    x = r
    y = 0
     
    # Printing the initial point the
    # axes after translation
    print("(", x + x_centre, ", ",
               y + y_centre, ")",
               sep = "", end = "")
     
    # When radius is zero only a single
    # point be printed
    if (r > 0) :
     
        print("(", x + x_centre, ", ",
                  -y + y_centre, ")",
                  sep = "", end = "")
        print("(", y + x_centre, ", ",
                   x + y_centre, ")",
                   sep = "", end = "")
        print("(", -y + x_centre, ", ",
                    x + y_centre, ")", sep = "")
     
    # Initialising the value of P
    P = 1 - r
 
    while x > y:
     
        y += 1
         
        # Mid-point inside or on the perimeter
        if P <= 0:
            P = P + 2 * y + 1
             
        # Mid-point outside the perimeter
        else:        
            x -= 1
            P = P + 2 * y - 2 * x + 1
         
        # All the perimeter points have
        # already been printed
        if (x < y):
            break
         
        # Printing the generated point its reflection
        # in the other octants after translation
        print("(", x + x_centre, ", ", y + y_centre,
                            ")", sep = "", end = "")
        print("(", -x + x_centre, ", ", y + y_centre,
                             ")", sep = "", end = "")
        print("(", x + x_centre, ", ", -y + y_centre,
                             ")", sep = "", end = "")
        print("(", -x + x_centre, ", ", -y + y_centre,
                                        ")", sep = "")
         
        # If the generated point on the line x = y then
        # the perimeter points have already been printed
        if x != y:
         
            print("(", y + x_centre, ", ", x + y_centre,
                                ")", sep = "", end = "")
            print("(", -y + x_centre, ", ", x + y_centre,
                                 ")", sep = "", end = "")
            print("(", y + x_centre, ", ", -x + y_centre,
                                 ")", sep = "", end = "")
            print("(", -y + x_centre, ", ", -x + y_centre,
                                            ")", sep = "")
                             
# Driver Code
if __name__ == '__main__':
     
    # To draw a circle of radius 3
    # centered at (0, 0)
    midPointCircleDraw(0, 0, 3)
 
 
# Contributed by: SHUBHAMSINGH10
# Improved by: siddharthx_07

C#

// C# program for implementing Mid-Point
// Circle Drawing Algorithm
using System;
 
class GFG {
     
    // Implementing Mid-Point Circle
    // Drawing Algorithm
    static void midPointCircleDraw(int x_centre,
                            int y_centre, int r)
    {
         
        int x = r, y = 0;
     
        // Printing the initial point on the
        // axes after translation
        Console.Write("(" + (x + x_centre)
                + ", " + (y + y_centre) + ")");
     
        // When radius is zero only a single
        // point will be printed
        if (r > 0)
        {
             
            Console.Write("(" + (x + x_centre)
                + ", " + (-y + y_centre) + ")");
                 
            Console.Write("(" + (y + x_centre)
                + ", " + (x + y_centre) + ")");
                 
            Console.WriteLine("(" + (-y + x_centre)
                + ", " + (x + y_centre) + ")");
        }
     
        // Initialising the value of P
        int P = 1 - r;
        while (x > y)
        {
             
            y++;
         
            // Mid-point is inside or on the perimeter
            if (P <= 0)
                P = P + 2 * y + 1;
         
            // Mid-point is outside the perimeter
            else
            {
                x--;
                P = P + 2 * y - 2 * x + 1;
            }
         
            // All the perimeter points have already
            // been printed
            if (x < y)
                break;
         
            // Printing the generated point and its
            // reflection in the other octants after
            // translation
            Console.Write("(" + (x + x_centre)
                    + ", " + (y + y_centre) + ")");
                     
            Console.Write("(" + (-x + x_centre)
                    + ", " + (y + y_centre) + ")");
                     
            Console.Write("(" + (x + x_centre) +
                    ", " + (-y + y_centre) + ")");
                     
            Console.WriteLine("(" + (-x + x_centre)
                    + ", " + (-y + y_centre) + ")");
         
            // If the generated point is on the
            // line x = y then the perimeter points
            // have already been printed
            if (x != y)
            {
                Console.Write("(" + (y + x_centre)
                    + ", " + (x + y_centre) + ")");
                         
                Console.Write("(" + (-y + x_centre)
                    + ", " + (x + y_centre) + ")");
                         
                Console.Write("(" + (y + x_centre)
                    + ", " + (-x + y_centre) + ")");
                         
                Console.WriteLine("(" + (-y + x_centre)
                    + ", " + (-x + y_centre) +")");
            }
        }
    }
     
    // Driver code
    public static void Main()
    {
         
        // To draw a circle of radius
        // 3 centered at (0, 0)
        midPointCircleDraw(0, 0, 3);
    }
}
 
// This code is contributed by nitin mittal.

PHP

<?php
// PHP program for implementing
// Mid-Point Circle Drawing Algorithm
 
// Implementing Mid-Point
// Circle Drawing Algorithm
function midPointCircleDraw($x_centre,
                            $y_centre,
                            $r)
{
    $x = $r;
    $y = 0;
     
    // Printing the initial
    // point on the axes
    // after translation
    echo "(",$x + $x_centre,",", $y + $y_centre,")";
     
    // When radius is zero only a single
    // point will be printed
    if ($r > 0)
    {
        echo "(",$x + $x_centre,",", -$y + $y_centre,")";
        echo "(",$y + $x_centre,",", $x + $y_centre,")";
        echo "(",-$y + $x_centre,",", $x + $y_centre,")","\n";
    }
     
    // Initializing the value of P
    $P = 1 - $r;
    while ($x > $y)
    {
        $y++;
         
        // Mid-point is inside
        // or on the perimeter
        if ($P <= 0)
            $P = $P + 2 * $y + 1;
             
        // Mid-point is outside
        // the perimeter
        else
        {
            $x--;
            $P = $P + 2 * $y -
                  2 * $x + 1;
        }
         
        // All the perimeter points
        // have already been printed
        if ($x < $y)
            break;
         
        // Printing the generated
        // point and its reflection
        // in the other octants
        // after translation
        echo "(",$x + $x_centre,",", $y + $y_centre,")";
        echo "(",-$x + $x_centre,",", $y + $y_centre,")";
        echo "(",$x +$x_centre,",", -$y + $y_centre,")";
        echo "(",-$x + $x_centre,",", -$y + $y_centre,")","\n";
         
        // If the generated point is
        // on the line x = y then
        // the perimeter points have
        // already been printed
        if ($x != $y)
        {
            echo "(",$y + $x_centre,",", $x + $y_centre,")";
            echo "(",-$y + $x_centre,",", $x + $y_centre,")";
            echo "(",$y + $x_centre,",", -$x + $y_centre,")";
            echo "(",-$y + $x_centre,",", -$x + $y_centre,")","\n";
        }
    }
}
 
    // Driver code
    // To draw a circle of radius
    // 3 centered at (0, 0)
    midPointCircleDraw(0, 0, 3);
     
// This code is contributed by nitin mittal.
?>

Javascript

<script>
// javascript program for implementing
// Mid-Point Circle Drawing Algorithm   
// Implementing Mid-Point Circle
    // Drawing Algorithm
    function midPointCircleDraw(x_centre , y_centre , r) {
 
        var x = r, y = 0;
 
        // Printing the initial point
        // on the axes after translation
        document.write("(" + (x + x_centre) + ", " + (y + y_centre) + ")");
 
        // When radius is zero only a single
        // point will be printed
        if (r > 0) {
 
            document.write("(" + (x + x_centre) + ", " + (-y + y_centre) + ")");
 
            document.write("(" + (y + x_centre) + ", " + (x + y_centre) + ")");
 
            document.write("(" + (-y + x_centre) + ", " + (x + y_centre) + ")<br/>");
        }
 
        // Initialising the value of P
        var P = 1 - r;
        while (x > y) {
 
            y++;
 
            // Mid-point is inside or on the perimeter
            if (P <= 0)
                P = P + 2 * y + 1;
 
            // Mid-point is outside the perimeter
            else {
                x--;
                P = P + 2 * y - 2 * x + 1;
            }
 
            // All the perimeter points have already
            // been printed
            if (x < y)
                break;
 
            // Printing the generated point and its
            // reflection in the other octants after
            // translation
            document.write("(" + (x + x_centre) + ", " + (y + y_centre) + ")");
 
            document.write("(" + (-x + x_centre) + ", " + (y + y_centre) + ")");
 
            document.write("(" + (x + x_centre) + ", " + (-y + y_centre) + ")");
 
            document.write("(" + (-x + x_centre) + ", " + (-y + y_centre) + ")<br/>");
 
            // If the generated point is on the
            // line x = y then the perimeter points
            // have already been printed
            if (x != y) {
 
                document.write("(" + (y + x_centre) + ", " + (x + y_centre) + ")");
 
                document.write("(" + (-y + x_centre) + ", " + (x + y_centre) + ")");
 
                document.write("(" + (y + x_centre) + ", " + (-x + y_centre) + ")");
 
                document.write("(" + (-y + x_centre) + ", " + (-x + y_centre) + ")<br/>");
            }
        }
    }
 
    // Driver code
     
 
        // To draw a circle of radius
        // 3 centered at (0, 0)
        midPointCircleDraw(0, 0, 3);
 
// This code is contributed by umadevi9616
</script>

Producción: 
 

(3, 0) (3, 0) (0, 3) (0, 3)
(3, 1) (-3, 1) (3, -1) (-3, -1)
(1, 3) (-1, 3) (1, -3) (-1, -3)
(2, 2) (-2, 2) (2, -2) (-2, -2)

Complejidad de tiempo: O(x – y)
Espacio auxiliar: O(1) 
Referencias: Algoritmo de círculo de punto medio  
Referencias de imagen: octantes de un círculo , círculo rasterizado , las otras imágenes fueron creadas para este artículo por el geek
Gracias Tuhina Singh y Teva Zanker por mejorando este artículo. 
Este artículo es una contribución de Nabaneet Roy . Si te gusta GeeksforGeeks y te gustaría contribuir, también puedes escribir un artículo usando write.geeksforgeeks.org o enviar tu artículo por correo a review-team@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.
Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.
 

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *