中点椭圆算法用于在计算机图形学中绘制椭圆。
另请参阅:中点线算法,中点圆算法
中点椭圆算法通过将象限分为两个区域,在第一个象限上绘制(查找)一个椭圆点。
然后将每个点(x,y)投影到其他三个象限(-x,y),(x,-y),(-x,-y),即,它使用4向对称。
椭圆函数:
fellipse(x, y)=ry2x2+rx2y2-rx2ry2
fellipse(x, y)<0 then (x, y) is inside the ellipse.
fellipse(x, y)>0 then (x, y) is outside the ellipse.
fellipse(x, y)=0 then (x, y) is on the ellipse.
决策参数:
最初,我们在区域1中具有两个决策参数p1 0 ,在区域2中具有p2 0 。
这些参数定义为:区域1中的p1 0表示为:
p10=ry2+1/4rx2-rx2ry
中点椭圆算法:
- 沿x轴和y轴获取输入半径,并获取椭圆的中心。
- 最初,我们假设椭圆以原点和第一个点为中心:(x,y 0 )=(0,r y )。
- 获得区域1的初始决策参数为:p1 0 = r y 2 + 1 / 4r x 2 -r x 2 r y
- 对于区域1中的每个x k位置:
如果p1 k <0,则沿的下一个点是(x k + 1 ,y k )和p1 k + 1 = p1 k + 2r y 2 x k + 1 + r y 2
否则,下一点是(x k + 1 ,y k-1 )
并且p1 k + 1 = p1 k + 2r y 2 x k + 1 – 2r x 2 y k + 1 + r y 2 - 使用区域1的最后一个点(x 0 ,y 0 )获得区域2中的初始值,如下所示:p2 0 = r y 2 (x 0 +1/2) 2 + r x 2 (y 0 -1) 2- r x 2 r y 2
- 在区域2中从k = 0开始的每个y k ,执行以下任务。
如果p2 k > 0,则下一个点是(x k ,y k-1 ),并且p2 k + 1 = p2 k -2r x 2 y k + 1 + r x 2
- 否则,下一个点是(x k + 1 ,y k -1 )和p2 k + 1 = p2 k + 2r y 2 x k + 1 -2r x 2 y k + 1 + r x 2
- 现在获得三个象限中的对称点,并将坐标值绘制为:x = x + xc,y = y + yc
- 对区域1重复上述步骤,直到2r y 2 x> = 2r x 2 y
执行:
C++
// C++ program for implementing
// Mid-Point Ellipse Drawing Algorithm
#include
using namespace std;
void midptellipse(int rx, int ry,
int xc, int yc)
{
float dx, dy, d1, d2, x, y;
x = 0;
y = ry;
// Initial decision parameter of region 1
d1 = (ry * ry) - (rx * rx * ry) +
(0.25 * rx * rx);
dx = 2 * ry * ry * x;
dy = 2 * rx * rx * y;
// For region 1
while (dx < dy)
{
// Print points based on 4-way symmetry
cout << x + xc << " , " << y + yc << endl;
cout << -x + xc << " , " << y + yc << endl;
cout << x + xc << " , " << -y + yc << endl;
cout << -x + xc << " , " << -y + yc << endl;
// Checking and updating value of
// decision parameter based on algorithm
if (d1 < 0)
{
x++;
dx = dx + (2 * ry * ry);
d1 = d1 + dx + (ry * ry);
}
else
{
x++;
y--;
dx = dx + (2 * ry * ry);
dy = dy - (2 * rx * rx);
d1 = d1 + dx - dy + (ry * ry);
}
}
// Decision parameter of region 2
d2 = ((ry * ry) * ((x + 0.5) * (x + 0.5))) +
((rx * rx) * ((y - 1) * (y - 1))) -
(rx * rx * ry * ry);
// Plotting points of region 2
while (y >= 0)
{
// Print points based on 4-way symmetry
cout << x + xc << " , " << y + yc << endl;
cout << -x + xc << " , " << y + yc << endl;
cout << x + xc << " , " << -y + yc << endl;
cout << -x + xc << " , " << -y + yc << endl;
// Checking and updating parameter
// value based on algorithm
if (d2 > 0)
{
y--;
dy = dy - (2 * rx * rx);
d2 = d2 + (rx * rx) - dy;
}
else
{
y--;
x++;
dx = dx + (2 * ry * ry);
dy = dy - (2 * rx * rx);
d2 = d2 + dx - dy + (rx * rx);
}
}
}
// Driver code
int main()
{
// To draw a ellipse of major and
// minor radius 15, 10 centred at (50, 50)
midptellipse(10, 15, 50, 50);
return 0;
}
// This code is contributed
// by Akanksha Rai
C
// C program for implementing
// Mid-Point Ellipse Drawing Algorithm
#include
void midptellipse(int rx, int ry, int xc, int yc)
{
float dx, dy, d1, d2, x, y;
x = 0;
y = ry;
// Initial decision parameter of region 1
d1 = (ry * ry)
- (rx * rx * ry)
+ (0.25 * rx * rx);
dx = 2 * ry * ry * x;
dy = 2 * rx * rx * y;
// For region 1
while (dx < dy) {
// Print points based on 4-way symmetry
printf("(%f, %f)\n", x + xc, y + yc);
printf("(%f, %f)\n", -x + xc, y + yc);
printf("(%f, %f)\n", x + xc, -y + yc);
printf("(%f, %f)\n", -x + xc, -y + yc);
// Checking and updating value of
// decision parameter based on algorithm
if (d1 < 0) {
x++;
dx = dx + (2 * ry * ry);
d1 = d1 + dx + (ry * ry);
}
else {
x++;
y--;
dx = dx + (2 * ry * ry);
dy = dy - (2 * rx * rx);
d1 = d1 + dx - dy + (ry * ry);
}
}
// Decision parameter of region 2
d2 = ((ry * ry) * ((x + 0.5) * (x + 0.5)))
+ ((rx * rx) * ((y - 1) * (y - 1)))
- (rx * rx * ry * ry);
// Plotting points of region 2
while (y >= 0) {
// printing points based on 4-way symmetry
printf("(%f, %f)\n", x + xc, y + yc);
printf("(%f, %f)\n", -x + xc, y + yc);
printf("(%f, %f)\n", x + xc, -y + yc);
printf("(%f, %f)\n", -x + xc, -y + yc);
// Checking and updating parameter
// value based on algorithm
if (d2 > 0) {
y--;
dy = dy - (2 * rx * rx);
d2 = d2 + (rx * rx) - dy;
}
else {
y--;
x++;
dx = dx + (2 * ry * ry);
dy = dy - (2 * rx * rx);
d2 = d2 + dx - dy + (rx * rx);
}
}
}
// Driver code
int main()
{
// To draw a ellipse of major and
// minor radius 15, 10 centred at (50, 50)
midptellipse(10, 15, 50, 50);
return 0;
}
Java
// Java program for implementing
// Mid-Point Ellipse Drawing Algorithm
import java.util.*;
import java.text.DecimalFormat;
class GFG
{
static void midptellipse(float rx, float ry,
float xc, float yc)
{
float dx, dy, d1, d2, x, y;
x = 0;
y = ry;
// Initial decision parameter of region 1
d1 = (ry * ry) - (rx * rx * ry) +
(0.25f * rx * rx);
dx = 2 * ry * ry * x;
dy = 2 * rx * rx * y;
DecimalFormat df = new DecimalFormat("#,###,##0.00000");
// For region 1
while (dx < dy)
{
// Print points based on 4-way symmetry
System.out.println(df.format((x + xc)) +
", "+df.format((y + yc)));
System.out.println(df.format((-x + xc)) +
", "+ df.format((y + yc)));
System.out.println(df.format((x + xc)) +
", "+ df.format((-y + yc)));
System.out.println(df.format((-x + xc)) +
", "+df.format((-y + yc)));
// Checking and updating value of
// decision parameter based on algorithm
if (d1 < 0)
{
x++;
dx = dx + (2 * ry * ry);
d1 = d1 + dx + (ry * ry);
}
else
{
x++;
y--;
dx = dx + (2 * ry * ry);
dy = dy - (2 * rx * rx);
d1 = d1 + dx - dy + (ry * ry);
}
}
// Decision parameter of region 2
d2 = ((ry * ry) * ((x + 0.5f) * (x + 0.5f)))
+ ((rx * rx) * ((y - 1) * (y - 1)))
- (rx * rx * ry * ry);
// Plotting points of region 2
while (y >= 0) {
// printing points based on 4-way symmetry
System.out.println(df.format((x + xc)) +
", " + df.format((y + yc)));
System.out.println(df.format((-x + xc)) +
", "+ df.format((y + yc)));
System.out.println(df.format((x + xc)) +
", " + df.format((-y + yc)));
System.out.println(df.format((-x + xc)) +
", " + df.format((-y + yc)));
// Checking and updating parameter
// value based on algorithm
if (d2 > 0) {
y--;
dy = dy - (2 * rx * rx);
d2 = d2 + (rx * rx) - dy;
}
else {
y--;
x++;
dx = dx + (2 * ry * ry);
dy = dy - (2 * rx * rx);
d2 = d2 + dx - dy + (rx * rx);
}
}
}
// Driver code
public static void main(String args[])
{
// To draw a ellipse of major and
// minor radius 15, 10 centred at (50, 50)
midptellipse(10, 15, 50, 50);
}
}
// This code is contributed by
// Surendra_Gangwar
Python3
# Python3 program for implementing
# Mid-Point Ellipse Drawing Algorithm
def midptellipse(rx, ry, xc, yc):
x = 0;
y = ry;
# Initial decision parameter of region 1
d1 = ((ry * ry) - (rx * rx * ry) +
(0.25 * rx * rx));
dx = 2 * ry * ry * x;
dy = 2 * rx * rx * y;
# For region 1
while (dx < dy):
# Print points based on 4-way symmetry
print("(", x + xc, ",", y + yc, ")");
print("(",-x + xc,",", y + yc, ")");
print("(",x + xc,",", -y + yc ,")");
print("(",-x + xc, ",", -y + yc, ")");
# Checking and updating value of
# decision parameter based on algorithm
if (d1 < 0):
x += 1;
dx = dx + (2 * ry * ry);
d1 = d1 + dx + (ry * ry);
else:
x += 1;
y -= 1;
dx = dx + (2 * ry * ry);
dy = dy - (2 * rx * rx);
d1 = d1 + dx - dy + (ry * ry);
# Decision parameter of region 2
d2 = (((ry * ry) * ((x + 0.5) * (x + 0.5))) +
((rx * rx) * ((y - 1) * (y - 1))) -
(rx * rx * ry * ry));
# Plotting points of region 2
while (y >= 0):
# printing points based on 4-way symmetry
print("(", x + xc, ",", y + yc, ")");
print("(", -x + xc, ",", y + yc, ")");
print("(", x + xc, ",", -y + yc, ")");
print("(", -x + xc, ",", -y + yc, ")");
# Checking and updating parameter
# value based on algorithm
if (d2 > 0):
y -= 1;
dy = dy - (2 * rx * rx);
d2 = d2 + (rx * rx) - dy;
else:
y -= 1;
x += 1;
dx = dx + (2 * ry * ry);
dy = dy - (2 * rx * rx);
d2 = d2 + dx - dy + (rx * rx);
# Driver code
# To draw a ellipse of major and
# minor radius 15, 10 centred at (50, 50)
midptellipse(10, 15, 50, 50);
# This code is contributed by chandan_jnu
C#
// C# program for implementing
// Mid-Point Ellipse Drawing Algorithm
using System;
class GFG
{
static void midptellipse(double rx, double ry,
double xc, double yc)
{
double dx, dy, d1, d2, x, y;
x = 0;
y = ry;
// Initial decision parameter of region 1
d1 = (ry * ry) - (rx * rx * ry) +
(0.25f * rx * rx);
dx = 2 * ry * ry * x;
dy = 2 * rx * rx * y;
// For region 1
while (dx < dy)
{
// Print points based on 4-way symmetry
Console.WriteLine(String.Format("{0:0.000000}",
(x + xc)) + ", "+String.Format
("{0:0.000000}",(y + yc)));
Console.WriteLine(String.Format("{0:0.000000}",
(-x + xc)) + ", "+ String.Format
("{0:0.000000}",(y + yc)));
Console.WriteLine(String.Format("{0:0.000000}",
(x + xc)) + ", "+String.Format
("{0:0.000000}",(-y + yc)));
Console.WriteLine(String.Format("{0:0.000000}",
(-x + xc)) +", "+String.Format
("{0:0.000000}",(-y + yc)));
// Checking and updating value of
// decision parameter based on algorithm
if (d1 < 0)
{
x++;
dx = dx + (2 * ry * ry);
d1 = d1 + dx + (ry * ry);
}
else
{
x++;
y--;
dx = dx + (2 * ry * ry);
dy = dy - (2 * rx * rx);
d1 = d1 + dx - dy + (ry * ry);
}
}
// Decision parameter of region 2
d2 = ((ry * ry) * ((x + 0.5f) * (x + 0.5f)))
+ ((rx * rx) * ((y - 1) * (y - 1)))
- (rx * rx * ry * ry);
// Plotting points of region 2
while (y >= 0)
{
// printing points based on 4-way symmetry
Console.WriteLine(String.Format("{0:0.000000}",
(x + xc)) + ", " + String.Format
("{0:0.000000}",(y + yc)));
Console.WriteLine(String.Format("{0:0.000000}",
(-x + xc)) + ", "+ String.Format
("{0:0.000000}",(y + yc)));
Console.WriteLine(String.Format("{0:0.000000}",
(x + xc)) + ", " + String.Format
("{0:0.000000}",(-y + yc)));
Console.WriteLine(String.Format("{0:0.000000}",
(-x + xc)) + ", " + String.Format
("{0:0.000000}",(-y + yc)));
// Checking and updating parameter
// value based on algorithm
if (d2 > 0)
{
y--;
dy = dy - (2 * rx * rx);
d2 = d2 + (rx * rx) - dy;
}
else
{
y--;
x++;
dx = dx + (2 * ry * ry);
dy = dy - (2 * rx * rx);
d2 = d2 + dx - dy + (rx * rx);
}
}
}
// Driver code
static void Main()
{
// To draw a ellipse of major and
// minor radius 15, 10 centred at (50, 50)
midptellipse(10, 15, 50, 50);
}
}
// This code is contributed by mits
PHP
= 0)
{
// printing points based on 4-way symmetry
echo "( ",$x + $xc,", ", $y + $yc ," )\n";
echo "( ",-$x + $xc,", ", $y + $yc , " )\n";
echo "( ",$x + $xc,", ", -$y + $yc, " )\n";
echo "( ",-$x + $xc,", ", -$y + $yc, " )\n";
// Checking and updating parameter
// value based on algorithm
if ($d2 > 0)
{
$y--;
$dy = $dy - (2 * $rx * $rx);
$d2 = $d2 + ($rx * $rx) - $dy;
}
else
{
$y--;
$x++;
$dx = $dx + (2 * $ry * $ry);
$dy = $dy - (2 * $rx * $rx);
$d2 = $d2 + $dx - $dy + ($rx * $rx);
}
}
}
// Driver code
// To draw a ellipse of major and
// minor radius 15, 10 centred at (50, 50)
midptellipse(10, 15, 50, 50);
// This code is contributed by Ryuga
?>
(50.000000, 65.000000)
(50.000000, 65.000000)
(50.000000, 35.000000)
(50.000000, 35.000000)
(51.000000, 65.000000)
(49.000000, 65.000000)
(51.000000, 35.000000)
(49.000000, 35.000000)
(52.000000, 65.000000)
(48.000000, 65.000000)
(52.000000, 35.000000)
(48.000000, 35.000000)
(53.000000, 64.000000)
(47.000000, 64.000000)
(53.000000, 36.000000)
(47.000000, 36.000000)
(54.000000, 64.000000)
(46.000000, 64.000000)
(54.000000, 36.000000)
(46.000000, 36.000000)
(55.000000, 63.000000)
(45.000000, 63.000000)
(55.000000, 37.000000)
(45.000000, 37.000000)
(56.000000, 62.000000)
(44.000000, 62.000000)
(56.000000, 38.000000)
(44.000000, 38.000000)
(57.000000, 61.000000)
(43.000000, 61.000000)
(57.000000, 39.000000)
(43.000000, 39.000000)
(57.000000, 60.000000)
(43.000000, 60.000000)
(57.000000, 40.000000)
(43.000000, 40.000000)
(58.000000, 59.000000)
(42.000000, 59.000000)
(58.000000, 41.000000)
(42.000000, 41.000000)
(58.000000, 58.000000)
(42.000000, 58.000000)
(58.000000, 42.000000)
(42.000000, 42.000000)
(59.000000, 57.000000)
(41.000000, 57.000000)
(59.000000, 43.000000)
(41.000000, 43.000000)
(59.000000, 56.000000)
(41.000000, 56.000000)
(59.000000, 44.000000)
(41.000000, 44.000000)
(59.000000, 55.000000)
(41.000000, 55.000000)
(59.000000, 45.000000)
(41.000000, 45.000000)
(60.000000, 54.000000)
(40.000000, 54.000000)
(60.000000, 46.000000)
(40.000000, 46.000000)
(60.000000, 53.000000)
(40.000000, 53.000000)
(60.000000, 47.000000)
(40.000000, 47.000000)
(60.000000, 52.000000)
(40.000000, 52.000000)
(60.000000, 48.000000)
(40.000000, 48.000000)
(60.000000, 51.000000)
(40.000000, 51.000000)
(60.000000, 49.000000)
(40.000000, 49.000000)
(60.000000, 50.000000)
(40.000000, 50.000000)
(60.000000, 50.000000)
(40.000000, 50.000000)