📜  中点圆图绘制算法

📅  最后修改于: 2021-04-29 18:36:17             🧑  作者: Mango

中点圆绘图算法是用于确定栅格化圆所需的点的算法。

我们使用中点算法来计算第一个八分圆中圆的所有周长点,然后将其连同其他八分圆中的镜像点一起打印。这将起作用,因为圆围绕其中心对称。

圆八分圆

该算法与中点线生成算法非常相似。在此,仅边界条件不同。

对于任何给定的像素(x,y),要绘制的下一个像素是(x,y + 1)(x-1,y + 1) 。可以按照以下步骤确定。

  1. 找出两个可能像素的中点p ,即(x-0.5,y + 1)
  2. 如果p位于圆周内或圆周上,则绘制像素(x,y + 1),否则,则绘制像素(x-1,y + 1)

边界条件:可以使用以下公式确定中点位于圆的内部还是外部:

例子

在我们的程序中,我们用P表示F(p)。P的值是在两个竞争像素(x-0.5,y + 1)的中点计算的。每个像素用下标k描述。

要绘制的第一个点在x轴上是(r,0)。 P的初始值计算如下:

例子:

输入:中心->(0,0),半径-> 3输出: (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) 例1说明

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)

C
// C program for implementing
// Mid-Point Circle Drawing Algorithm
#include
  
// 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 centred at (0, 0)
    midPointCircleDraw(0, 0, 3);
    return 0;
}


CPP
// C++ program for implementing
// Mid-Point Circle Drawing Algorithm
#include
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 centred 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 centred 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 
    # centred 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 centred at (0, 0)
        midPointCircleDraw(0, 0, 3);
    }
}
  
// This code is contributed by nitin mittal.


PHP
 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 centred at (0, 0)
    midPointCircleDraw(0, 0, 3);
      
// This code is contributed by nitin mittal.
?>


输出:

(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)

参考文献:中点圆算法
图像参考:圆的八分圆,光栅化的圆,其他图像是由极客为本文章创建的