如何逐像素绘制任意方向的椭圆?

12

我需要逐像素绘制任意大小和方向的椭圆。 绘制主轴和副轴与x和y轴对齐的椭圆似乎很容易,但是将椭圆旋转一个任意角度似乎更加棘手。 最初我认为可以绘制未旋转的椭圆并将旋转矩阵应用于每个点,但似乎由于四舍五入可能会引起误差,并且我需要相当高的精度。

我的这种方法的怀疑是正确的吗? 我如何更准确地完成此任务?

我正在使用C ++编程(尽管这不应该真正重要,因为这是一个更注重算法的问题)。

编辑:正如David指出的那样,我想知道如何进行像素插值。

3个回答

10

使用:

x = X cos(a) - Y sin(a)
y = Y cos(a) + X sin(a)

其中a是逆时针旋转的角度,(x, y)是新坐标,(X, Y)是旧坐标。

为了保持精度,应该使用浮点数。只需遍历每个点,应用变换即可。

编辑:在搜索后,这是微软的一些代码:http://research.microsoft.com/en-us/um/people/awf/graphics/bres-ellipse.html,可以绘制光栅化的圆锥曲线。


1
我相信这会带来“前向”转换的常见风险:别名会导致您在转换坐标时“跳过”像素。 - dmckee --- ex-moderator kitten
是的,这就是为什么我一直在寻找不同的方法。有没有好的处理别名的方法? - amc
是的,我的意思是,这完全取决于您用于绘图的库。但是走样会破坏任何类型的旋转。你应该问的问题是“我应该如何执行像素插值?” :) - David Titarenco
1
添加了一个链接到微软的一些有趣代码,它非常详细,所以应该很容易跟踪 :} - David Titarenco
非常感谢!那真是太棒了。 - amc
显示剩余3条评论

4

4

使用Bresenham方法绘制轴对齐椭圆,但是对绘制的椭圆进行剪切。您还需要修改轴的长度。剪切椭圆也是椭圆。 这种方法保留了Bresenham优势,可以使用水平线段绘制填充椭圆。为此,您需要一个将椭圆的轴和旋转规范映射到不同轴和剪切的函数。此处提供了在线解决方案,其中包括有关该方法的讨论和涉及的数学描述http://scratch.mit.edu/discuss/topic/94194/

这个映射关系是由Nathan Dinsmore(MIT Scratch网站上的用户nXIII)发现的。


这太棒了。应该成为最佳答案,因为它是对一个旧问题的新而更好的解决方案。 - tukra
毫无疑问这是正确的答案。但是为什么会在Scratch中实现呢 :/ - Enrico Borba
http://g6auc.me.uk/ellipses/index.html 的底部有JavaScript代码,可能更易于访问。 - Graham Toal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接