Я начинаю свой путь к рекурсии и пытаюсь создать фрактальный класс, который рекурсивно работает внутри своего конструктора. Предполагается, что этот класс берет родительский эллипс, размещает 4 меньших дочерних эллипса по его окружности, а затем продолжает рекурсию до максимальной глубины, размещая 4 дочерних эллипса на каждом из предыдущих дочерних элементов.

Мой текущий прогресс создает 1 родительский эллипс и 4 дочерних элемента (после вызова метода рисования в массиве «дети»). Мой вопрос: как мне рекурсивно относиться к детям? Я действительно совершенно не уверен, с чего начать.

 public FractalEllipse( int depth, Point p, int w, int h )
 {
    setFrame( p.x, p.y, w, h );

    if ( depth < numDepth )
    {
        children = new FractalEllipse[numChildren];
        for ( int i = 0; i < numChildren; i++ )
        { 
            int height = ( int )( h * sizeRatio );
            int width = ( int ) ( w * sizeRatio );
            int centerX = ( int ) ( this.getCenterX( ) - ( width / 2 ) );
            int centerY = ( int ) ( this.getCenterY( ) - ( height / 2 ) );
            double radX = Math.toRadians( ( 360 / numChildren ) * i );
            double radY = Math.toRadians( ( 360 / numChildren ) * i );


            int x = ( int ) ( centerX + ( ( w / 2 ) ) *  Math.cos( radX ) );
            int y = ( int ) ( centerY + ( ( h / 2 ) ) *  Math.sin( radY ) );

            FractalEllipse child = new FractalEllipse( depth + 1,
                              new Point( x, y ), width, height ); 

            children[i] = child;

        } 
    } else
    {

    }
}

Извините, вот полный метод рисования:

public void draw( Graphics2D context ) 
{
    Color saveColor = context.getColor();

    Color myColor = Color.MAGENTA;
    context.setColor( myColor );

    // draw myself
    if ( fill )        
        context.fill( this );
    else
        context.draw( this );

    context.setColor( Color.CYAN );

    for ( int i = 0; i < children.length; i++ )
    {
            context.fill( children[i] ); 
    }
}
0
Wilson Everett 8 Мар 2015 в 08:10
Кто вызывает context.fill в корневом эллипсе (тот, который не является потомком чего-либо еще)? Или вы не хотите, чтобы заполнить тот?
 – 
ajb
8 Мар 2015 в 08:32
Извиняюсь! Отредактировано, чтобы добавить метод полного рисования
 – 
Wilson Everett
8 Мар 2015 в 09:54

2 ответа

Поскольку метод draw заставляет фрактальный эллипс либо рисовать, либо заполнять себя, родителю не нужно вызывать context.draw или context.fill для дочерних элементов. Вместо этого, если вы вызовете дочерний метод draw рекурсивно, они вызовут context.draw или context.fill для себя. Потом они сделают то же самое для своих детей.

Следовательно, цикл в методе draw должен выглядеть примерно так:

for ( int i = 0; i < children.length; i++ )
{
        children[i].draw(); 
}

Или, используя расширенный цикл for Java:

for (FractalEllipse child : children) {
    child.draw();
}

Единственное, что не ясно, это переменная fill. Вы использовали это в методе draw, но не показали, как оно определено или как установлено. Предполагая, что вы хотите, чтобы родитель и все потомки либо имели свои контуры, либо были заполнены таким же образом: если fill является полем в FractalEllipse, вам нужно убедиться, что Поле fill задается в дочерних элементах так же, как и в родительском. Если поле получено откуда-то еще, вам может потребоваться добавить его в качестве параметра в метод draw и убедиться, что draw включает параметр, когда он рекурсивно вызывает себя для своих дочерних элементов. Я не знаю, какой правильный ответ из-за отсутствия информации, но, скорее всего, вам нужна одна из этих двух идиом.

0
ajb 9 Мар 2015 в 01:52

Если есть какие-либо дети, вам нужно вызвать цикл draw детей конкретно, либо до, либо после context.fill(..).

После того, как вы включили ветвление через дочерние элементы, вернитесь к основному draw, вы должны проверить, существует ли дочерний массив. В случае, если вы не инициализируете его, как только достигнете определенной глубины.

-1
Robert Altena 8 Мар 2015 в 15:51