中点圆绘图算法是用于确定栅格化圆所需的点的算法。
我们使用中点算法来计算第一个八分圆中圆的所有周长点,然后将其连同其他八分圆中的镜像点一起打印。这将起作用,因为圆围绕其中心对称。
该算法与中点线生成算法非常相似。在此,仅边界条件不同。
对于任何给定的像素(x,y),要绘制的下一个像素是(x,y + 1)或(x-1,y + 1) 。可以按照以下步骤确定。
- 找出两个可能像素的中点p ,即(x-0.5,y + 1)
- 如果p位于圆周内或圆周上,则绘制像素(x,y + 1),否则,则绘制像素(x-1,y + 1)
边界条件:可以使用以下公式确定中点位于圆的内部还是外部:
Given a circle centered at (0,0) and radius r and a point p(x,y)
F(p) = x2 + y2 – r2
if F(p)<0, the point is inside the circle
F(p)=0, the point is on the perimeter
F(p)>0, the point is outside the circle
在我们的程序中,我们用P表示F(p)。P的值是在两个竞争像素(x-0.5,y + 1)的中点计算的。每个像素用下标k描述。
Pk = (Xk — 0.5)2 + (yk + 1)2 – r2
Now,
xk+1 = xk or xk-1 , yk+1= yk +1
∴ Pk+1 = (xk+1 – 0.5)2 + (yk+1 +1)2 – r2
= (xk+1 – 0.5)2 + [(yk +1) + 1]2 – r2
= (xk+1 – 0.5)2 + (yk +1)2 + 2(yk + 1) + 1 – r2
= (xk+1 – 0.5)2 + [ – (xk – 0.5)2 +(xk – 0.5)2 ] + (yk + 1)2 – r2 + (yk + 1) + 1
= Pk + (xk+1 – 0.5)2 – (xk – 0.5)2 + 2(yk + 1) + 1
= Pk + (x2k+1 – x2k)2 + (xk+1 – xk)2 + 2(yk + 1) + 1
= Pk + 2(yk +1) + 1, when Pk <=0 i.e the midpoint is inside the circle
(xk+1 = xk)
Pk + 2(yk +1) – 2(xk – 1) + 1, when Pk>0 I.e the mid point is outside the circle(xk+1 = xk-1)
要绘制的第一个点在x轴上是(r,0)。 P的初始值计算如下:
P1 = (r – 0.5)2 + (0+1)2 – r2
= 1.25 – r
= 1 -r (When rounded off)
例子:
输入:中心->(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)
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)
参考文献:中点圆算法
图像参考:圆的八分圆,光栅化的圆,其他图像是由极客为本文章创建的