Отрисовка схемы

Тема в разделе "Как сделать...", создана пользователем LEXAlForpostl, 24 фев 2012.

  1. LEXAlForpostl

    LEXAlForpostl

    Регистр.:
    21 май 2008
    Сообщения:
    739
    Симпатии:
    226
    Здравствуйте, уважаемые форумчане.
    Есть набор данных [0;1].
    Необходимо отрисовать схему следующего вида:
    [​IMG]
    1. У схемы должен быть определенный формат ширины.
    2. Каждое число должно быть в кружочке.
    3. Расстояние между кружочками должно составляться по правилу:
    чем последующее число больше, тем расстояние меньше. Отсюда => мин расстояние, если следующая цифра 1; макс расстояние, если 0. Мин расстояние должно быть полсантиметра - сантиметр, макс - сантиметра два с половиной - три.
    4. Кружочки должны быть соединены линиями.
    5. Если ширина "листа" уже закончена, значит следующий элемент опускаем вниз, и затем уже слева направо ведется рисование, потом опять вниз и наборот.
    6. Может быть такое, что у одного элемента будет два пути, причем один из них может быть тупиковым, не сразу, а через несколько элементов.

    Помогите, пожалуйста. Желательно по пунктам.
    Если кто-то видит всю картину сразу - пишите код, с меня WMR :)

    P.S.
    Формат входных данных может быть любым, как Вам удобно.
     
    Iwashka нравится это.
  2. dino

    dino

    Регистр.:
    28 май 2009
    Сообщения:
    550
    Симпатии:
    204
    что является причиной для начала ветвления и остановки?
     
    Iwashka нравится это.
  3. LEXAlForpostl

    LEXAlForpostl

    Регистр.:
    21 май 2008
    Сообщения:
    739
    Симпатии:
    226
    Исходные данные.
     
    Iwashka нравится это.
  4. dino

    dino

    Регистр.:
    28 май 2009
    Сообщения:
    550
    Симпатии:
    204
    Ладно... перефразирую... каким образом скрипту будет сообщено, что в данном конкретном месте необходимо сделать n-ное количество ответвлений с n-параметрами... Что это будет? Многомерный массив, определенное число, специфическая последовательность чисел или ещё какая-то метка?
     
    Iwashka нравится это.
  5. LEXAlForpostl

    LEXAlForpostl

    Регистр.:
    21 май 2008
    Сообщения:
    739
    Симпатии:
    226
    Думал, сделать это как многомерный массив. Но можно сделать в таком виде, как удобно Вам. Мне не принципиально.
     
    Iwashka нравится это.
  6. dino

    dino

    Регистр.:
    28 май 2009
    Сообщения:
    550
    Симпатии:
    204
    Ну могу пока предложить следующее:
    PHP:
    <?php
     
    header 
    ("Content-type: image/png");
    function 
    h_right($hr){ // отрисовка горизонтального этапа справа на лево
    for($i=1$i<=$hr['lengt']; $i++){
    $hr['sx']=$hr['start_x']+$i;
    imagesetpixel($hr['img'],$hr['sx'],$hr['sy'],$hr['textcolor']);
    }
    imageellipse($hr['img'],$hr['sx']+$hr['krug']/2,$hr['sy'],$hr['krug'],$hr['krug'], $hr['textcolor']);
    imagestring($hr['img'], $hr['font_s'], $hr['sx']+$hr['font_s'], $hr['sy']-$hr['font_s']*1.5$hr['data'], $hr['textcolor']);
    $hr['start_x']=$hr['sx']+$hr['krug'];
    return 
    $hr;
    }
     
    function 
    h_left($hl){ // отрисовка горизонтального этапа слева направо
    for($i=1$i<=$hl['lengt']; $i++){
    $hl['sx']=$hl['start_x']-$i;
    imagesetpixel($hl['img'],$hl['sx'],$hl['sy'],$hl['textcolor']);
    }
    imageellipse($hl['img'],$hl['sx']-$hl['krug']/2,$hl['sy'],$hl['krug'],$hl['krug'], $hl['textcolor']);
    imagestring($hl['img'], $hl['font_s'], $hl['sx']-$hl['krug']+$hl['font_s'], $hl['sy']-$hl['font_s']*1.5$hl['data'], $hl['textcolor']);
    $hl['start_x']=$hl['sx']-$hl['krug'];
    return 
    $hl;
    }
     
    function 
    v_down($vd){ // отрисовка вертикального этапа
    for($i=1$i<=$vd['lengt']; $i++){
    $vd['sy']=$vd['start_y']+$i;
    imagesetpixel($vd['img'],$vd['sx'],$vd['sy'],$vd['textcolor']);
    }
    imageellipse($vd['img'],$vd['sx'],$vd['sy']+$vd['krug']/2,$vd['krug'],$vd['krug'], $vd['textcolor']);
    imagestring($vd['img'], $vd['font_s'], $vd['sx']-$vd['krug']/2+$vd['font_s'], $vd['sy']+$vd['krug']/2.5$vd['data'], $vd['textcolor']);
    $vd['start_y']=$vd['sy']+$vd['krug'];
    return 
    $vd;
    }
     
    $h_w=800//горизонтальный размер поля рисунка
    $v_w=600//вертикальный размер поля рисунка
    $k['img'] = imagecreate($h_w$v_w); // создание поля для рисунка
    $k['ink'] = imagecolorallocate($k['img'], 255255255); //цвет фона поля для рисунка
    $k['textcolor'] = imagecolorallocate($k['img'], 000); // цвет рисунка
    $k['font_s']=3// размер шрифта
    $k['krug']=40;  // диаметр круга
    $k['start_x']=50// стартовая позиция рисунка по горизонтали
    $k['start_y']=25// стартовая позиция рисунка по вертикали
    $k['napr']=1//направление рисунка: 1- справа на лево, 2-слева на право
    $k['sx']=$k['start_x']; //стартовая позиция по горизонтали очередного этапа
    $k['sy']=$k['start_y']; //стартовая позиция по вертикали очередного этапа
    for($r=1$r<=45$r++){
    $k['data']=rand(0,100);  // исходные данные
    $k['lengt']=100-$k['data']+30// длинна линии
    $k['data']/=100;
    if(
    $k['napr']==&& ($k['start_x']+$k['lengt']+$k['krug'])<$h_w ){ // если движемся вправо и следующий пункт не выйдет за пределы поля
    $k=h_right($k);
    }
    elseif(
    $k['napr']==&& ($k['start_x']-$k['lengt']-$k['krug'])>0){// если движемся влево и следующий пункт не выйдет за пределы поля
    $k=h_left($k);
    }
    elseif((
    $k['napr']==&& ($k['start_x']+$k['lengt']+$k['krug'])>=$h_w ) or ($k['napr']==&& ($k['start_x']-$k['lengt']-$k['krug'])<=0)){ // движемся вниз
    // задаем смещение элементов для корректного отображения вертикальной составляющей
    if($k['napr']==1){
    $k['napr']=2;
    $k['sx']+=$k['krug']/2;
    $k['start_y']+=$k['krug']/2;
    }
    else{
    $k['napr']=1;
    $k['sx']-=$k['krug']/2;
    $k['start_y']-=$k['krug']/2;
    }
    // отрисовка вертикального этапа
    $k=v_down($k);
    // задаем смещение элементов для корректного отображения горизонтальной составляющей
    if($k['napr']==1){
    $k['start_x']+=$k['krug'];
    $k['sy']+=$k['krug']/2;
    $k['start_y']-=$k['krug']/2;
    }
    else{
    $k['start_x']-=$k['krug'];
    $k['sy']+=$k['krug']/2;
    $k['start_y']+=$k['krug']/2;
    }
    }
    }
    imagepng($k['img']);
    imagedestroy($k['img']);
    ?>
    Данный код генерит n-раз случайное число от 0 до 100
    PHP:
    for($r=1$r<=45$r++){
    $k['data']=rand(0,100); )
    $k['lengt']=100-$k['data']+30// длинна линии
    $k['data']/=100;
    .........
    При необходимости данный участок кода можно заменить массивом данных и циклом перебора их, например:
    PHP:
    $mass=array(0.10.80.030.05,......);
    foreach(
    $mass as  $k['data'] ){
    $k['lengt']=100-$k['data']*100+30// длинна линии
    .........
    ну или ещё каким либо образом инициировать...
    результат работы данного кода:
    [​IMG]
    Пункт с ответвлениями здесь пока не решен в силу ряда причин, самая основная из которых - как физически расположить ответвление и при этом не пересечься с другими ветками.
    Кроме того больше одного ответвления выполнить из одной точки также не представляется возможным, по причине того, что свободной в момент построения рисунка является только одна сторона - нижняя, которая в свою очередь уже занята одним ответвлением...
     
    Iwashka и LEXAlForpostl нравится это.