Почему мой класс рисования графиков рисует секунду, а не секрет или кроватку? - PullRequest
3 голосов
/ 10 марта 2019

Я написал класс для графического калькулятора в Pygame, который по сути просто делает набросок функции. Я работал над пользовательским интерфейсом для него, но обнаружил, что он не работает для обратных тригонометрических функций cosec или cot (1/(math.sin(x)) и 1/(math.tan(x)) в python соответственно), хотя он работает в течение секунды (1/(math.cos(x))) .

Я использовал ключевое слово lambda для ввода этих функций в класс. Например: c = Curve(lambda x: x**2, (255, 0, 0))

Я все еще работаю над его улучшением, в настоящее время он еще не закончен, и, скорее всего, он еще не подтвержден пользователем. Но, что бы я ни пытался, я не могу понять, почему я не могу заставить cosec или кроватку работать с ним.

Любая помощь будет оценена, спасибо.

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]

EDIT:

Теперь я обнаружил, что класс работает, если в функцию добавить любое значение x, даже если это значение очень мало, например: cosec(x+0.0000000000001)

Прошу прощения за качество изображения.

Graphical Calculator

1 Ответ

1 голос
/ 10 марта 2019

Теперь я смог решить проблему, так как это стало результатом того, как я проверял правильность функции ввода с помощью предложения:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...