我在Pygame中为一个图形计算器编写了一个类,它实际上只是一个函数的草图。我一直在为它开发一个UI,但发现它不适用于倒三角函数cosec或cot(python中分别为1/(math.sin(x))
和1/(math.tan(x))
),尽管它确实适用于sec(1/(math.cos(x))
)。
我一直在使用lambda
关键字将这些函数输入到类中。例如:c = Curve(lambda x: x**2, (255, 0, 0))
我仍在努力改进它,它目前还没有完成,而且肯定还没有用户证明。但是,无论我尝试什么,我都不明白为什么我不能让cosec或cot与之合作。
任何帮助都将不胜感激,谢谢。
class Curve(object):
def __init__(self, func, colour, width=1):
self.function = func
self.colour = colour
self.width = width
def render(self, colour=None, width=None):
if self.function is None:
return
if colour is not None:
self.colour = colour
if width is not None:
self.width = width
try:
self.function(0)
except (NameError, TypeError, AttributeError, ZeroDivisionError):
return
for x in range(0, WIDTH):
try:
fx = self.function((x / camera_pos[2]) + camera_pos[0])
fx1 = self.function(((x + 1) / camera_pos[2]) + camera_pos[0])
except (OverflowError, ValueError, ZeroDivisionError):
continue
if type(fx) == complex or type(fx1) == complex:
continue
if 0 < transform_point(-fx, "y") < HEIGHT or 0 < transform_point(-fx1, "y") < HEIGHT:
pygame.draw.line(SCREEN, self.colour, (x, transform_point(-fx, "y")),
(x + 1, transform_point(-fx1, "y")), self.width)
transform_point()
函数将笛卡尔坐标映射到屏幕上的位置。camera_pos = [-400, -300, 1] # [x, y, zoom]
def transform_point(value, axis):
if str(axis).lower() == "x":
return (value - camera_pos[0]) * camera_pos[2]
elif str(axis).lower() == "y":
return (value - camera_pos[1]) * camera_pos[2]
编辑:
我现在发现,如果在函数中向x添加任何值,即使该值非常小,例如:
cosec(x+0.0000000000001)
我对图像质量很抱歉。
最佳答案
我现在已经能够解决这个问题,因为我是如何用子句检查输入函数的有效性的:
try:
self.function(0)
except (NameError, TypeError, AttributeError, ZeroDivisionError):
return
在这里,我通过尝试计算f(0)来确保该函数是可执行的,以便在呈现曲线时不会发生错误。但是由于cosec(x)和cot(x)f(0)是未定义的,类没有试图呈现曲线。这就解释了为什么在x上加上一个量,就可以提取它。
为了解决这个问题,我把代码改成了这个,它分别处理零除法错误。
try:
self.function(0)
except (NameError, TypeError, AttributeError):
return
except ZeroDivisionError:
pass