我想在C ++中使用graphics.h绘制一个圆,但不是直接使用circle()函数。我想绘制的圆圈使用较小的圆圈作为点,即较小的圆圈将构成较大圆圈的周长。所以我想,如果我做了这样的事情,它会起作用:
{
int radius = 4;
// Points at which smaller circles would be drawn
int x, y;
int maxx = getmaxx();
int maxy = getmaxy();
// Co-ordinates of center of the larger circle (centre of the screen)
int h = maxx/2;
int k = maxy/2;
//Cartesian cirle formula >> (X-h)^2 + (Y-k)^2 = radius^2
//Effectively, this nested loop goes through every single coordinate on the screen
int gmode = DETECT;
int gdriver;
initgraph(&gmode, &gdriver, "");
for(x = 0; x<maxx; x++)
{
for(y = 0; y<maxy; y++)
{
if((((x-h)*(x-h)) + ((y-k)*(y-k))) == (radius*radius))
{
circle(x, y, 5) //Draw smaller circle with radius 5
} //at points which satisfy circle equation only!
}
}
getch();
}
这是我在Turbo C ++上使用graphics.h的时候,因为这是我们在学校学习的编译器。
我知道这很古老。
所以,理论上,由于嵌套for循环检查屏幕上的所有点,并在每个满足圆方程的点上画一个小圆圈,我想我会得到一个大圆半径,输入的圆周构成我在for循环中制作的较小圆圈。
然而,当我尝试该程序时,我得到四个双曲线(都指向屏幕的中心),当我增加半径时, pointiness (缺少一个更好的词)双曲线增加,直到最后,当半径为256或更大时,顶部和底部的两个双曲线相交,在我的屏幕上形成一个大十字架,如:“就是这样,用户,我放弃!”
我达到值256,因为我注意到半径是4的倍数看起来......更好?
我在很长一段时间内寻找解决方案,但无法得到任何答案,所以我在这里。
任何建议???
编辑&gt;&gt;这是我得到的输出的粗略图表......
答案 0 :(得分:4)
您的代码中存在两个问题:
首先:您应该在调用initgraph
和getmaxx
之前致电getmaxy
,否则他们不一定会返回图形模式的正确尺寸。根据您的设置,这可能是也可能不是影响因素。
其次,最重要的是:在Turbo C ++中,int是16位。例如,这里是半径为100的圆(在上一个initgraph
订单问题修复之后):
注意四个角落的杂散圆圈。如果我们做一些调试并添加一些打印输出(一个有用的策略,你应该提交以备将来参考):
if((((x-h)*(x-h)) + ((y-k)*(y-k))) == (radius*radius))
{
printf(": (%d-%d)^2 + (%d-%d)^2 = %d^2\n", x, h, y, k, radius);
circle(x, y, 5); //Draw smaller circle with radius
} //at points which satisfy circle equation only!
您可以看到正在发生的事情(第一行是maxx和maxy,未在上面的代码段中显示):
特别是(63,139)处的圆是其中一个角。如果你做数学计算,你会看到:
(63 - 319) 2 +(139 - 239) 2 = 75536
由于你的整数是16位,75536模数65536 = 10000 =最终计算的值= 100 2 =一个圆圈,它不应该是。
一个简单的解决方案是将相关变量更改为long
:
所以:
long x, y;
...
initgraph(...);
...
long maxx = getmaxx();
long maxy = getmaxy();
...
long h = maxx / 2;
long k = maxy / 2;
然后你会得到正确的输出:
当然要注意像other answers point out一样,因为你使用的是int,所以你会错过很多分数。这可能是也可能不是,但是某些值会产生明显较差的结果(例如,半径256似乎只有4个整数解)。如果需要,您可以引入容差。您也可以使用a more direct approach,但这可能会使用笛卡尔圆公式破坏您的练习目的。如果你是这样的话,这里有一个24页的文档,其中包含一堆关于integers that are the sum of two squares的讨论,证明和属性。
我不太了解Turbo C ++是否可以让它使用32位整数,我会把它作为练习留给你。
答案 1 :(得分:1)
首先,maxx和maxy是整数,您可以使用表示屏幕边框的某些函数进行初始化,然后将它们用作函数。只需删除paranthesis:
// Co-ordinates of center of the larger circle (centre of the screen)
int h = maxx/2;
int k = maxy/2;
然后,您正在检查确切的相等性以检查点是否在圆上。由于屏幕是像素网格,因此很多点都会被遗漏。您需要添加公差,检查点与实际圆之间的最大距离。所以改变这一行:
if(((x-h)*(x-h)) + ((y-k)*(y-k)) == radius*radius)
到此:
if(abs(((x-h)*(x-h)) + ((y-k)*(y-k)) - radius*radius) < 2)
答案 2 :(得分:1)
引入一定程度的宽容度将解决问题。
但是检查图形窗口中的所有点是不明智的。你会改变一种做法吗?您可以根本不绘制所需的小圆圈:
要填充所有大圆周(半径为RBig
),您需要NCircles
半径为RSmall
的小圆圈
NCircles = round to integer (Pi / ArcSin(RSmall / RBig));
第i小圈的中心位置
cx = mx + Round(RBig * Cos(i * 2 * Pi / N));
cy = my + Round(RBig * Sin(i * 2 * Pi / N));
其中mx, my
- 大圆圈的中心