什么';用C实现椭圆方程的正确方法是什么?
我试图在由MCU供电的绘图仪上绘制椭圆,所以内存不足,最好使用整数算法 我得到了这个等式 我尝试通过以下方式在C中实现它:什么';用C实现椭圆方程的正确方法是什么?,c,geometry,render,equation,ellipse,C,Geometry,Render,Equation,Ellipse,我试图在由MCU供电的绘图仪上绘制椭圆,所以内存不足,最好使用整数算法 我得到了这个等式 我尝试通过以下方式在C中实现它: y = sqrt( (b*b) * ( 1 - ( (x*x) / (a*a) ))); 其中y、b、x和a是整数值,但结果不正确 Q1这是椭圆方程的正确实现吗? Q2还有其他方法吗?实现是正确的。我将y、b、x和a设置为双值,这修复了错误的输出 绘制椭圆(用线勾勒轮廓)的参数方程是最好的。 此处轴对齐椭圆: x=x0+a*cos(t); y=y0+b*sin(t);
y = sqrt( (b*b) * ( 1 - ( (x*x) / (a*a) )));
其中y
、b
、x
和a
是整数值,但结果不正确
Q1这是椭圆方程的正确实现吗?
Q2还有其他方法吗?实现是正确的。我将y、b、x和a设置为双值,这修复了错误的输出
x=x0+a*cos(t);
y=y0+b*sin(t);
for (x=-a;x<=a;x++)
{
y = sqrt( (b*b) - ( (x*x*b*b) / (a*a) )));
// render pixels: (x,+y) and (x,-y) or join them by line
}
其中:
是椭圆中心(x0,y0)
是半轴a、b
是角度参数t
t=
- 因此,形成一个循环,其中
以足够小的步长完成整个循环t
- 计算t的每一步的
(x,y)
- 每一步插值/渲染线(从上一步到新点)
x,y,x0,y0,a,b
是整数,请将它们转换为浮点/双精度或为cos[],sin[]创建整数表,例如:
int bits(DWORD p)
{
DWORD m=0x80000000; int b=32;
for (;m;m>>=1,b--)
if (p>=m) break;
return b;
}
DWORD sqrt(const DWORD &x)
{
DWORD m,a;
m=(bits(x)>>1); // bits(x) just return position of MSB nonzero bit can use m=16; instead
if (m) m=1<<m; else m=1;
for (a=0;m;m>>=1) { a|=m; if (a*a>x) a^=m; }
return a;
}
inttcos[360],tsin[360]代码>
其中tcos[i]=浮点数(1000.0*cos(浮点数(i)*M_PI/180.0))代码>现在只使用整数,如:
for (i=0;i<360;i++)
{
x=x0+(a*tcos(i))/1000;
y=y0+(b*tsin(i))/1000;
//...
}
如果需要整数sqrt
,则实现一个整数(而不是使用math.h
),例如:
int bits(DWORD p)
{
DWORD m=0x80000000; int b=32;
for (;m;m>>=1,b--)
if (p>=m) break;
return b;
}
DWORD sqrt(const DWORD &x)
{
DWORD m,a;
m=(bits(x)>>1); // bits(x) just return position of MSB nonzero bit can use m=16; instead
if (m) m=1<<m; else m=1;
for (a=0;m;m>>=1) { a|=m; if (a*a>x) a^=m; }
return a;
}
注意:整数除法将导致截断。您可能需要转换为浮点。sqrt
将返回一个双精度,为什么y必须是整数?请详细说明程序无法运行的原因,尤其是代码。不要在评论中发布代码,用代码编辑您的帖子。@ThomasMatthews不要大声喊叫。只需投票关闭并继续。注意:椭圆有一个双差分引擎实现(“Bresenham”)。不,它不是。如果你用therm乘以(b*b)
项,以摆脱()
,现在除法后你得到了一个不错的数字,那么它也可以用于整数(最初您得到的是小于1
的整数0
或1
)始终首先在整数的末尾进行乘法和除法。(在浮点上也是为了不降低精度)看到我的答案了吗?我为你提供了一些实现方案,其中包括你是对的,你的解决方案可能是有效的,但是我的绘图仪由一个只有几KB内存的微控制器驱动,所以我不能在绘图之前计算所有的值,因为这对更少的内存不起作用。b将始终是一个整数,因为我正在转换cm(从输入)到步骤(用于打印)。因此通常情况下,它大约在5000到1之间(如果它是0,我无论如何也不能打印椭圆)。是的,我应该在我的问题中添加此详细信息。@MattistIn,tcos
表可以只包含几个步骤(通常情况下,对于总计768B的32位整数而言,96就足够了。1000
可以是1024
,因此可以使用位移位。还有整数正弦波和余弦波近似,因此在这种情况下不需要表格。Bresenham也是一个选项,但如果需要保留像素顺序(就像绘图仪那样)如果你需要像素完美椭圆,那么#2是我能想到的唯一选择(因为你引入了额外的限制)@Mattis顺便问一下,你是如何制定运动规划的?你的MCU里有自己的插补器吗?或者每个电机都使用运动处理器?或者使用模拟控制?或者使用伺服来代替所有这些?…很高兴看到有人在这些日子里被真正的硬件弄脏了