What does 2 copy ge { dup 0 rlineto } mean here?
В качестве предложения THEN оператора if
или ifelse
оно означает «if (stack (top-1)> stack (top)) draw_horizontal_line ((current_x, current_y) -> (current_x + stack (top), current_y). Процедура -body { dup 0 rlineto }
- это закрытие рекурсии: часть, которая решает, когда остановиться и что делать вместо рекурсии. rlineto
рисует относительную линию. относительно текущая точка, то есть текущая точка находится там, где последний оператор построения пути (например, moveto
, lineto
, но не rotate
и не stroke
) оставил ее.
How does ifelse work here and what is the condition?
ifelse
всегда работает одинаково: логический тип тело процедуры тело процедуры ifelse: выполнить тело первой процедуры, если логическое значение истинно, в противном случае выполнить вторую. Условие представляет собой результат с логическим значением оператора gt
, примененного к 2 числам в стеке. Поскольку gt
использует свои аргументы, добавление 2 copy
означает, что данные не теряются, когда gt
это делает.
What does 3 div do here?
Поскольку второй аргумент (вершина стека) управляет общим размером фигуры, он также контролирует «размер» частичной фигуры, представленной объединенными командами рисования всех дочерних вызовов. 3 div
означает, что на каждом уровне рекурсии «размер» рисунка меньше «размера» его родительского элемента, на 1/3 меньше. В листовых вызовах, где выполняется условие a> = b, b используется как длина отдельных линейных сегментов, составляющих изображение. Это означает, что a - это не длина строки как таковая, а пороговое значение. Как только b при спуске к b / 3, b / 9, b / 27, b / 81 встречает или пересекает порог a, тогда пора выключить машину для клонирования и попросить всех взять свои карандаши.
What does the 2 copy KochR statement perform here?
Эта строка выполняет рекурсивный вызов процедуры kochR, используя тот же порог и уменьшенный размер из двух аргументов, которые были переданы текущему вызову. Использование 2 copy
означает, что два значения сохраняются в стеке до тех пор, пока pop pop
не опустится ниже.
Вот приблизительный перевод на C, предполагающий наличие доступной графической библиотеки, которая реализует модель изображения Adobe (также называемую моделью Stencil-Mask или Path-Paint). Параметры представляют собой размер сегментов линии и общий размер фигуры соответственно. Таким образом, максимальный уровень рекурсии косвенно контролируется уравнением a> = b * (1/3) ^ R.
void kochR(double a, double b) {
if (a >= b) {
// line from currentpoint to currentpoint+(b,0)
// ie. line of length b along current x-axis
rlineto(b, 0);
} else {
b /= 3;
kochR(a, b); // recurse with reduced length
rotate(60); // rotate x-axis CCW by 60 degrees
kochR(a, b);
rotate(-120); // rotate x-axis CW by 120 degrees
kochR(a, b);
rotate(60);
kochR(a, b);
}
}
int main(void) {
moveto(0,0);
kochR(27, 81);
moveto(0, 27);
kochR(9, 81);
moveto(0, 54);
kochR(3, 81);
moveto(0, 81);
kochR(1, 81);
stroke();
}
Таким образом, вы должны увидеть из этого, что весь 2 copy
материал - это средство, которое Postscript должен «поддерживать» 2 безымянных переменных. Каждая строка соответствует вызову процедуры, которая потребляет 2 переменные из стека. Вы должны увидеть, что последний pop pop
будет ненужным, если вы также опустите последний 2 copy
в последнем «вызове процедуры». С точки зрения программирования postscript это все довольно простые вещи. Но способ ограничения рекурсии довольно сложен.
Кстати, если вам нравятся такие фракталы (а я люблю), вы обязательно должны увидеть http://en.wikipedia.org/wiki/L-system. Это потрясающе.
Одной из популярных библиотек C, реализующих модель изображений Adobe, является Cairo Graphics, но я оставлю задачу создания рабочей программы. как упражнение для читателя. :)
person
luser droog
schedule
12.09.2012
KochR
, а все остальныеkochR
. Вы правильно скопировали код? - person Kurt Pfeifle   schedule 12.09.2012