функция рисования со сгибом и добавлением строки?

У меня есть вопрос о рекурсивной функции для рисования изображения

Да, это домашнее задание, но я не знаю, как нарисовать это изображение. Что у меня есть до сих пор:

  • Функция, которая дает мне список точек (x/y) из кривой ((list (x1/y2) (x2/y2)...(xn/yn))
  • Например, чтобы получить координату x, мне нужно написать point-x (first lis)
  • Функция, которую я назвал (zipWith f xs ys), принимает два списка (xs ys) применяет функцию f и создает список (например, (zipWith + (list 1 2 3) (list 10 20 30)) -> (list 11 22 33))
  • Функция make-tuple, которая берет два списка и превращает их в кортеж (например:
    (make-tuple (list 1 2 3) (list 4 5 6)) -> (tuple (list 1 2 3) (list 4 5 6))
    Чтобы получить первый кортеж, мне нужно написать (xs1 (tuple (list 1 2 3) (list 4 5 6)) -> (list 1 2 3)

Теперь к фактической функции:

Мы должны использовать функцию add-line, которая рисует линию из одной точки в другую.
Параметры image number number number number string
Другими словами: empty-image x1 y1 x2 y2 "black"
Итак, она начинается с empty-image и рисует линию от (x1/y1) до (x2/y2) с цвет "black"

И мы должны использовать fold для написания функции. Итак, моя попытка:

;Signature
(: render ((list-of point) -> image))

(define render
  (lambda (xs)
    (let((tuple-list (zipWith make-tuple xs (rest xs))))
      (fold empty-image
            add-line
            tuple-list))))

Что я пытался сделать, так это взять список точек и составить список с кортежем точек
(list (tuple (x1/y1) (x2/y2)) (tuple (x2/y2) (x3/y3))...(tuple (xn/yn) (xn/yn)))
Теперь я хочу применить add-line с fold к списку кортежей. Так что я говорю, давайте возьмем первый кортеж (мои две точки) и применим их к функции add-line. Затем берем следующий кортеж и также применяем эти точки к функции add-line (и так далее), пока мой список не опустеет.

Теперь проблема в том, что схема говорит, что add-line ожидает 6 параметров, но находит только 2. Я знаю свою проблему, потому что add-line не знаю, где взять остальные параметры. Итак, я попытался:

(define render
  (lambda (xs)
    (let((tuple-list (zipWith make-tuple xs (rest xs))))
      (fold empty-image (add-line 
                         empty-image
                         (point-x (xs1 (first tuple-list)))
                         (point-y (xs1 (first tuple-list)))
                         (point-x (xs2 (first tuple-list)))
                         (point-y (xs2 (first tuple-list)))
                         "black")
            tuple-list))))

и знайте, что там написано "вызов функции: ожидалась функция после открывающей скобки, но получено изображение"

И снова я знаю свою ошибку, add-line рисует одну линию, а fold пытается применить это изображение к списку, но нужна функция, а не изображение. Итак, мой вопрос:

Как я могу написать рекурсивную функцию render с add-line и fold, которая рисует первую линию, затем получает следующие точки и рисует следующую линию в сочетании с первой?
(например, рекурсивная функция add-line, которая снова вызывает себя после рисую линию)


person Donnie    schedule 28.06.2015    source источник


Ответы (1)


Вы не говорите конкретно, какой язык вы используете, но это выглядит подозрительно:

 (fold empty-image (add-line ...))

В Racket способ использования fold:

 (foldl f base l)

Здесь f — функция. В вашем коде у вас есть empty-image.

Вам нужно определить функцию, скажем, f, которая использует кортеж для добавления строки на «текущее» изображение:

 ; f : tuple image -> image
 (define (f t img)
     (add-line img
               (point-x (xs1 t))
               (point-y (xs1 t))
               (point-x (xs2 t))
               (point-y (xs2 t))
               "black"))

а потом

(foldl f empty-image tuple-list)

Возможно, вам придется настроить одну или две вещи, чтобы заставить ее работать.

person soegaard    schedule 28.06.2015