crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

2 страниц V   1 2 >  
Тема закрытаНачать новую тему
> Проблема с рекурсией
FladeX
  опции профиля:
сообщение 24.2.2009, 17:00
Сообщение #1


Студент
*

Группа: Участник
Сообщений: 67
Регистрация: 20.2.2009
Пользователь №: 564

Спасибо сказали: 0 раз(а)




Репутация:   0  


Функция:
void cDrawField::triangleDraw(double tmpx1, double tmpy1, double tmpx2, double tmpy2, double tmpx3, double tmpy3)
{
    double tmpx4, tmpy4, tmpx5, tmpy5, tmpx6, tmpy6;
    double sqt; // площадь
    double a, b, c, p; // стороны и полупериметр

    painter.drawLine(tmpx1, tmpy1, tmpx2, tmpy2);
    painter.drawLine(tmpx2, tmpy2, tmpx3, tmpy3);
    painter.drawLine(tmpx3, tmpy3, tmpx1, tmpy1);

    tmpx4 = (tmpx1 + tmpx2) / 2;
    tmpy4 = (tmpy1 + tmpy1) / 2;
    tmpx5 = (tmpx2 + tmpx3) / 2;
    tmpy5 = (tmpy2 + tmpy3) / 2;
    tmpx6 = (tmpx1 + tmpx3) / 2;
    tmpy6 = (tmpy1 + tmpy3) / 2;

    a = sqrt(((tmpx4 - tmpx5) * (tmpx4 - tmpx5)) + ((tmpy4 - tmpy5) * (tmpy4 - tmpy5)));
    b = sqrt(((tmpx5 - tmpx6) * (tmpx5 - tmpx6)) + ((tmpy5 - tmpy6) * (tmpy5 - tmpy6)));
    c = sqrt(((tmpx6 - tmpx4) * (tmpx6 - tmpx4)) + ((tmpy6 - tmpy4) * (tmpy6 - tmpy4)));
    p = (a + b + c) / 2;
    sqt = sqrt((p - a) * (p - b) * (p - c));

    if (sqt > 100)
    {
        triangleDraw(tmpx1, tmpy1, tmpx4, tmpy4, tmpx5, tmpy5);
        triangleDraw(tmpx2, tmpy2, tmpx4, tmpy4, tmpx6, tmpy6);
        triangleDraw(tmpx3, tmpy3, tmpx5, tmpy5, tmpx6, tmpy6);
        triangleDraw(tmpx4, tmpy4, tmpx5, tmpy5, tmpx6, tmpy6);
    }
}

Как видно, там происходит рекурсия. Однако она идет не так как надо - походу учитывается лишь первый вызов функции. Такой же код на javascript (с учетом синтаксиса конечно) отрабатывается верно.
В чем моя ошибка?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kuler
  опции профиля:
сообщение 24.2.2009, 17:25
Сообщение #2


Танцор диско
***

Группа: Участник
Сообщений: 441
Регистрация: 11.9.2008
Из: Москва
Пользователь №: 289

Спасибо сказали: 6 раз(а)




Репутация:   -1  


ну видимо sqt не становится меньше 100 :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 24.2.2009, 17:48
Сообщение #3


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9656
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(FladeX @ 24.2.2009, 20:00) *
Однако она идет не так как надо - походу учитывается лишь первый вызов функции.
непонятно, а что должно было быть и что имеем. (высказана только догадка, а не причина приведшая к догадке.)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
FladeX
  опции профиля:
сообщение 24.2.2009, 18:42
Сообщение #4


Студент
*

Группа: Участник
Сообщений: 67
Регистрация: 20.2.2009
Пользователь №: 564

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(kuler @ 24.2.2009, 17:25) *
ну видимо sqt не становится меньше 100 :)

Становится. Можно и другое значение поставить для верности - это не суть важно, главное что рекурсия не так работает(

Функция получает исходный треугольник, и разбивает его на более мелкие треугольники до тех пор, пока их площадь не станет меньше какого-либо значения (в данном конкретном случае я поставил 100).
Чтобы было нагляднее, привожу скриншот результата работы такой функции в JavaScript и то, что у меня получается в Qt.
Эскизы прикрепленных изображений
Прикрепленное изображение
Прикрепленное изображение
 
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kuler
  опции профиля:
сообщение 24.2.2009, 19:17
Сообщение #5


Танцор диско
***

Группа: Участник
Сообщений: 441
Регистрация: 11.9.2008
Из: Москва
Пользователь №: 289

Спасибо сказали: 6 раз(а)




Репутация:   -1  


вообще код написан по татарски. Надо разбить на модель представление, то есть сначала рассчитать точки, а потом уже отобразить. А так сиди, разбирайся

почему то мне сдается что перед drawLine неплохо было бы курсор установить в нужное место, но это всего лишь мысль
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
FladeX
  опции профиля:
сообщение 24.2.2009, 19:47
Сообщение #6


Студент
*

Группа: Участник
Сообщений: 67
Регистрация: 20.2.2009
Пользователь №: 564

Спасибо сказали: 0 раз(а)




Репутация:   0  


Да вроде порядок кода нормальный, по-другому уже не то будет... Да и разбивать там особо-то нечего, ~10 строк всего.
А установка курсора что даст? Ведь drawLine проводит линию по полученным координатам, поэтому установка курсора здесь ничего не изменит (имхо).
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 24.2.2009, 20:20
Сообщение #7


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Цитата(FladeX @ 24.2.2009, 19:47) *
Да вроде порядок кода нормальный, по-другому уже не то будет... Да и разбивать там особо-то нечего, ~10 строк всего.
А установка курсора что даст? Ведь drawLine проводит линию по полученным координатам, поэтому установка курсора здесь ничего не изменит (имхо).

Сдаемся, выкладывай javascript ;)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
FladeX
  опции профиля:
сообщение 24.2.2009, 20:24
Сообщение #8


Студент
*

Группа: Участник
Сообщений: 67
Регистрация: 20.2.2009
Пользователь №: 564

Спасибо сказали: 0 раз(а)




Репутация:   0  


вот функция:
function triangle_make(x1, y1, x2, y2, x3, y3, trid, trlevel) {
    trlevel++;
    // временно
    //var eps = 10;
    // объявляем объект для хранения данных о треугольнике
    triangle = new Object();
    //var triangle = new Object(); // переменная задана как глобальная, не объявляем локальную
    // заполняем данными
    triangle.id = trid; // должна быть переменная-счетчик вместо 1
    triangle.level = trlevel; // должна быть переменная-счетчик вместо 1
    triangle.x1 = x1;
    triangle.y1 = y1;
    triangle.x2 = x2;
    triangle.y2 = y2;
    triangle.x3 = x3;
    triangle.y3 = y3;
    // задаем массив для хранения данных о треугольниках
    // var delta = new Array(); // массив задан как глобальный, не переопределяем локальный массив

    // вносим данные о новом треугольнике
    delta[trnumber] = triangle;
    //alert('trid=' + trnumber + 'trlevel=' + trlevel);
    // теперь обновим id
    
    // строим главный треугольник
    triangle_draw(x1, y1, x2, y2, x3, y3, 'triangle000');
    // еще 3 вершины для следующего уровня
    x1 = x1 * 1;
    y1 = y1 * 1;
    x2 = x2 * 1;
    y2 = y2 * 1;
    x3 = x3 * 1;
    y3 = y3 * 1;
    var x4 = (x1 + x2) / 2;
    var y4 = (y1 + y2) / 2;
    var x5 = (x1 + x3) / 2;
    var y5 = (y1 + y3) / 2;
    var x6 = (x2 + x3) / 2;
    var y6 = (y2 + y3) / 2;
    trnumber = trnumber + 1;
    //alert('x5=' + x5);
    //triangle_draw(x4, y4, x5, y5, x6, y6, 'triangle000');
    // проверяем на площадь
    if (triangle_square(x4, y4, x5, y5, x6, y6) > eps) {
        triangle_make(x1, y1, x4, y4, x5, y5, trnumber, trlevel);
        triangle_make(x2, y2, x4, y4, x6, y6, trnumber, trlevel);
        triangle_make(x3, y3, x5, y5, x6, y6, trnumber, trlevel);
        triangle_make(x4, y4, x5, y5, x6, y6, trnumber, trlevel);
    //} else {
        // делаем раскрывающийся список со всеми треугольниками
        //triangleselect(trnumber);
    }
}

Или полностью весь код надо? (1000 строк)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 24.2.2009, 20:35
Сообщение #9


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


У меня есть подозрение, что проблема в смешивании операций целочисленных типов данных с плавающей запятой. Там где 2, лучше сделать 2.0, где 100 - 100.0. Т.к. в некоторых случаях компилятор может считать 2 - 1.999..., 100 -99.999....
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
FladeX
  опции профиля:
сообщение 24.2.2009, 20:39
Сообщение #10


Студент
*

Группа: Участник
Сообщений: 67
Регистрация: 20.2.2009
Пользователь №: 564

Спасибо сказали: 0 раз(а)




Репутация:   0  


Попробовал так.. Тоже не помогло.
Там суть в том, что рекурсия идет, но не по всем вызовам.
Конкретно ошибка в этом участке
    if (sqt > 100)
    {
        triangleDraw(tmpx1, tmpy1, tmpx4, tmpy4, tmpx5, tmpy5);
        triangleDraw(tmpx2, tmpy2, tmpx4, tmpy4, tmpx6, tmpy6);
        triangleDraw(tmpx3, tmpy3, tmpx5, tmpy5, tmpx6, tmpy6);
        triangleDraw(tmpx4, tmpy4, tmpx5, tmpy5, tmpx6, tmpy6);
    }

Такое ощущение, что учитывается только первый вызов из условия, а остальные не учитываются. Даже на рисунке видно, что идет только одна ветка рекурсии, хотя должно быть на n-ом шаге 4*n вызовов.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

2 страниц V   1 2 >
Тема закрытаНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 2.6.2020, 11:56