使用python创建一个傻瓜证明图形计算器 - Python 2.7

时间:2015-03-15 05:02:21

标签: python python-2.7 graph pygame graphing

我正在尝试使用python和pygame创建一个傻瓜证明图形计算器。

我创建了一个适用于大多数功能的图形计算器。它需要一个用户字符串中缀表达式并将其转换为后缀以便于计算。然后我循环并将x值传入postfix表达式,以获得使用pygame进行图形化的Y值。

我遇到的第一个问题是计算不可能的事情。 (如除以零,平方根为-1,0 ^非正数)。如果发生类似这样的事情,我会输出无,并且该像素不会被添加到要绘制的点列表中。

*我已经展示了我为此所做的所有不同尝试,以帮助您了解我来自哪里。如果您只想查看我最新的代码和方法,请跳到“当前”的位置。

方法1

我的第一种方法是在我获取了所有像素值后,我会使用pygame aalines函数绘制它们。这是有效的,除非它在实际点之间缺少点时不起作用,因为它只是在点上绘制线。 (1 / x不起作用,但像0 ^ x那样)

这是1 / x使用aalines方法的样子 aalines method

方法1.1

我的下一个想法是每次打印一个无效时将线分成两行。这适用于1 / x,但我很快意识到,只有当传入的X值中的一个确切地落在Y值为None时,它才会起作用。 1 / x可能有效,但1 /(x + 0.0001)不起作用。

方法2

我的下一个方法是将每个像素x值转换为窗口中相应的x点值(例如,图形窗口上的(0,0)实际上是500x500程序窗口上的像素(249,249))。然后我会用刚刚创建的x值计算每个y值。这适用于没有斜率的任何行> 1或者< -1。

这是1 / x使用此方法的样子。 enter image description here

电流

我最新的方法应该是方法2的高级工作版本。 它有点难以解释。基本上我会在显示窗口的每一列之间取x值。对于每个像素,我会在左侧和右侧进行此操作。然后我将这两个值插入表达式以获得两个Y值。然后,我将循环遍历该列上的每个y值,并检查当前值是否介于之前计算的两个Y值之间。

  • size是一个大小为2的列表,它是程序窗口的维度。
  • xWin是一个大小为2的列表,其中包含图形窗口的x Min和x Max。
  • yWin是一个大小为2的列表,它包含图形窗口的y Min和y Max。
  • pixelToPoint是一个采用标量像素值(仅x或y)并将其转换为图形窗口上相应值的函数

pixels = []

for x in range(size[0]):
    leftX = pixelToPoint(x,size[0]+1, xWin, False)
    rightX = pixelToPoint(x+1, size[0]+1, xWin, False)

    leftY = calcPostfix(postfix, leftX)
    rightY = calcPostfix(postfix, rightX)

    for y in range(size[1]):
        if leftY != None and rightY != None:
            yPoint = pixelToPoint(y,size[1],yWin, True)

            if (rightY <= yPoint <= leftY) or (rightY >= yPoint >= leftY):
                pixels.append((x,y))
for p in pixels:
    screen.fill(BLACK, (p, (1, 1)))  

这解决了方法2中没有连接成连续线的像素的问题。但是,它不能解决方法1的问题,当绘制1 / x时,它看起来与aalines方法完全相同。

-------------------------------------------- -------------------------------------------------- ---------------------------------

我陷入困境,无法想到解决方案。我能想到解决这个问题的唯一方法是使用一大堆x值。但这种方式似乎效率很低。此外,我正在努力使我的程序尽可能可调整大小和可自定义,所以一切都必须是可变驱动的,我不知道需要什么类型的计算才能找出需要使用多少x值,具体取决于程序窗口大小和图表的窗口大小。

我不确定我是否在正确的轨道上,或者是否有完全不同的方法,但我想创建我的图形计算器,以便能够绘制任何函数(就像我的实际图形计算器)。

编辑1

我只是尝试使用与像素一样多的x值(500x500显示窗口计算250,000 y值)。

它适用于我尝试过的所有功能,但它确实很慢。计算大约需要4秒钟(根据公式而波动)。我在网上浏览了一下,发现图形计算器几乎在他们的图形中瞬间完成,但我无法弄清楚他们是如何做到的。

online graphing calcuator非常快速有效。必须有一些算法,除了使用一堆x值,而不是可以实现我想要的,因为该网站正在这样做..

2 个答案:

答案 0 :(得分:0)

你遇到的问题是,为了能够知道在两点之间你是否可以合理地绘制一条线,你必须知道该函数在该区间内是否是连续的。

这是一个复杂的问题,你可以做的是使用以下启发式。如果线的斜率与前一个线的变化太大,则猜测在区间中有一个非连续点并且不绘制线。

答案 1 :(得分:0)

另一种解决方案将基于解决方案2.

在绘制了与x轴的每个值对应的点之后,尝试绘制每个相邻的x:(x1,x2)y内的y(y1 = f(x1),y2 = f(x2))在(x1,x2)内到达x。

这可以通过二分法搜索或通过牛顿搜索启发式搜索来完成。