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

LEXAlForpostl

Мой дом здесь!
Регистрация
21 Май 2008
Сообщения
766
Реакции
228
Здравствуйте, уважаемые форумчане.
Есть набор данных [0;1].
Необходимо отрисовать схему следующего вида:
a24dc023e693.jpg

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

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

P.S.
Формат входных данных может быть любым, как Вам удобно.
 
6. Может быть такое, что у одного элемента будет два пути, причем один из них может быть тупиковым, не сразу, а через несколько элементов
что является причиной для начала ветвления и остановки?
 
Ладно... перефразирую... каким образом скрипту будет сообщено, что в данном конкретном месте необходимо сделать n-ное количество ответвлений с n-параметрами... Что это будет? Многомерный массив, определенное число, специфическая последовательность чисел или ещё какая-то метка?
 
Думал, сделать это как многомерный массив. Но можно сделать в таком виде, как удобно Вам. Мне не принципиально.
 
Ну могу пока предложить следующее:
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'], 255, 255, 255); //цвет фона поля для рисунка
$k['textcolor'] = imagecolorallocate($k['img'], 0, 0, 0); // цвет рисунка
$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']==1 && ($k['start_x']+$k['lengt']+$k['krug'])<$h_w ){ // если движемся вправо и следующий пункт не выйдет за пределы поля
$k=h_right($k);
}
elseif($k['napr']==2 && ($k['start_x']-$k['lengt']-$k['krug'])>0){// если движемся влево и следующий пункт не выйдет за пределы поля
$k=h_left($k);
}
elseif(($k['napr']==1 && ($k['start_x']+$k['lengt']+$k['krug'])>=$h_w ) or ($k['napr']==2 && ($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.1, 0.8, 0.03, 0.05,......);
foreach($mass as  $k['data'] ){
$k['lengt']=100-$k['data']*100+30; // длинна линии
.........
ну или ещё каким либо образом инициировать...
результат работы данного кода:
Для просмотра ссылки Войди или Зарегистрируйся
Пункт с ответвлениями здесь пока не решен в силу ряда причин, самая основная из которых - как физически расположить ответвление и при этом не пересечься с другими ветками.
Кроме того больше одного ответвления выполнить из одной точки также не представляется возможным, по причине того, что свободной в момент построения рисунка является только одна сторона - нижняя, которая в свою очередь уже занята одним ответвлением...
 
Назад
Сверху