如何用 C# 实现图形绘制器

发布于 2024-10-12 01:07:54 字数 791 浏览 2 评论 0原文

所以我正在写一个图形计算器。到目前为止,我有一个半功能的绘图仪,但是,我很难在准确的图表和平滑的曲线之间取得良好的平衡。

当前的实现(半伪代码)看起来像这样:

for (float i = GraphXMin; i <= GraphXMax; i++)
{
    PointF P = new PointF(i, EvaluateFunction(Function, i)
    ListOfPoints.Add(P)
}
Graphics.DrawCurve(ListOfPoints)

问题是因为它只在每个整数值处添加一个点,当它们的转折点不落在整数上时,图形最终会扭曲(例如 sin(x)^2)。

alt text

我尝试将 i 增加一些较小的值(例如 0.1),这是可行的,但是图表看起来非常粗糙。

alt text

我正在使用 C# 和 GDI+。我将 SmoothingMethod 设置为 AntiAlias,所以这不是问题,正如您从第一张图中看到的那样。绘制具有很多点的曲线是否存在某种问题?这些点是否应该精确定位在像素上?

我确信你们中的一些人以前做过非常类似的事情,所以有什么建议吗?当您这样做时,您对用渐近线绘制函数有什么建议吗?例如 1/x^

2我并不是在寻找一个可以完成所有这些工作的库 - 我想自己编写它。

So I'm writing a graphing calculator. So far I have a semi-functional grapher, however, I'm having a hard time getting a good balance between accurate graphs and smooth looking curves.

The current implementation (semi-pseudo-code) looks something like this:

for (float i = GraphXMin; i <= GraphXMax; i++)
{
    PointF P = new PointF(i, EvaluateFunction(Function, i)
    ListOfPoints.Add(P)
}
Graphics.DrawCurve(ListOfPoints)

The problem with this is since it only adds a point at every integer value, graphs end up distorted when their turning points don't fall on integers (e.g. sin(x)^2).

alt text

I tried incrementing i by something smaller (like 0.1), which works, but the graph looks very rough.

alt text

I am using C# and GDI+. I have SmoothingMethod set to AntiAlias, so that's not the problem, as you can see from the first graph. Is there some sort of issue with drawing curves with a lot of points? Should the points perhaps be positioned exactly on pixels?

I'm sure some of you have worked on something very similar before, so any suggestions? While you're at it, do you have any suggestions for graphing functions with asymptotes? e.g. 1/x^2

P.S. I'm not looking for a library that does all this - I want to write it myself.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

噩梦成真你也成魔 2024-10-19 01:07:54

好的,我解决了问题。在绘图过程中的某个地方我使用了 int 而不是 float。

OK, I fixed the problem. Somewhere in the drawing process I was using int rather than float.

抱猫软卧 2024-10-19 01:07:54

渲染图形时,您总是会出现舍入错误,因为位图是离散的,而图形不是。

有几种应对方法:

  1. 使用抗锯齿;它只是让图表看起来更平滑。
  2. 使用非线性插值。使用线性插值从点 a 绘制到点 b 会产生角度。计算每个点的图形(不是线段!)的斜率,并将该斜率提供给插值方法(双三次曲线或贝塞尔曲线)。

使用矢量 API(例如 WPF 或 Silverlight)可能会使事情更容易实现。

照顾渐近线是相当困难的。首先,您必须找到它们,然后跳过该值,以便您可以在图表中制作“洞”。

When rendering a graph you are always making rounding errors because a bitmap is discrete and the graph isn't.

There several ways of coping:

  1. use anti-aliasing; it's just making the graph look smoother.
  2. use a non-lineair interpolation. Drawing from point a to b using a lineair interpolation causes angles. Calculate the slope of the graph (not of the line segment!) in each point and feed the slope to the interpolation method (bicubic or bezier curve)

Using vector APIs such as WPF or Silverlight might make things easier to implement.

Taking care of asymptotes is pretty hard. First you have to find them and then skip the value so you can make the 'hole' in the graph.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文