Тема: Алгоритмы Как построить дерево?
Показать сообщение отдельно
Старый 11.04.2015, 03:20
GBee вне форума Посмотреть профиль Отправить личное сообщение для GBee Найти все сообщения от GBee
  № 9  
Ответить с цитированием
GBee
 
Аватар для GBee

Регистрация: Jan 2009
Сообщений: 3,067
Записей в блоге: 3
Отправить сообщение для GBee с помощью Skype™
Я потыркался, вроде и получается, но есть исключения и мне их уже лень думать сегодня. Если хоть как-то
приблизит вас к решению, буду рад. Справа кнопка рефреша. Комменты напишу и баги поправлю потом, если будет нужда. Общая идея - уходим до листиков, рисуем их, потом по усредненному Y рисуем их веточку, веточки дают среднюю Y для ветки их и так далее. Но гд-то явно прогибы есть, голова уже не варит, но задача прикольная.

tree2.swf   (1.9 Кб)



Код AS3:
package 
{
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.geom.Point;
 
	/**
	 * ...
	 * @author gbee
	 */
	public class TreeTest extends Sprite 
	{
 		private static const VGAP:int = 15;
		private static const HGAP:int = 50;
		private var _levelsOffset:Array;
 
		private var _g:Graphics;
		public function TreeTest() 
		{
			super();
 
			var spr:Sprite = new Sprite();
			spr.graphics.beginFill(0, 0.4);
			spr.graphics.drawRect(800, 0, 100, 40);
			spr.addEventListener(MouseEvent.CLICK, refresh);
			addChild(spr);
			refresh();
		}
 
		private function refresh(event:MouseEvent = null):void
		{
			_g = graphics;
			_g.clear();
			_g.beginFill(0x008800);
			_g.lineStyle(1, 0x004400);
			_levelsOffset = [0, 0, 0, 0, 0, 0, 0, 0, 0];
			drawTree(generateTree(5, 3), 0);
		}
 
		private function generateTree(maxChilds:int, level:int):TreeNode
		{
			var childsCount:int = int(Math.random() * maxChilds);
			var node:TreeNode = new TreeNode();
			if (level == 0)
				return node;
 			for (var i:int = 0; i < childsCount; i++)
				node.children.push(generateTree(maxChilds, level - 1));
			node.count = childsCount;
			return node;
		}
 
 
		private function drawTree(node:TreeNode, level:int):Number
		{
			var levelY:Number = 0; 
			if (node.count)
			{
				var linesY:Array = []; //массив Y для рисования связей.
				for each(var child:TreeNode in node.children)
				{
					var cY:Number = drawTree(child, level + 1);
					levelY += cY;
					linesY.push(cY);
				}
				_levelsOffset[level + 1] += VGAP;
 
				levelY = levelY / node.count;
 
				if(levelY - _levelsOffset[level] >= VGAP)
					_levelsOffset[level] = levelY;
				else
				{
					_levelsOffset[level] += VGAP;
					levelY = _levelsOffset[level];
				}
 
				//Рисуем связи
				for each(cY in linesY)
				{
					_g.moveTo(HGAP * level, levelY);
					_g.lineTo(HGAP * (level + 1), cY);
				}
			}
			else
			{
				levelY = _levelsOffset[level]; 
				_levelsOffset[level] += VGAP;
				//Запрещаем рисовать ноды чужих детей выше себя. Но тут надо подумать в примере не запрещено.
				if(_levelsOffset[level + 1] < _levelsOffset[level])
					_levelsOffset[level + 1] = _levelsOffset[level];
			}
 
			//Рисуем ноду
			_g.drawCircle(HGAP * level, levelY, 5);
			return levelY;
		}
 
 
	}
 
}
Код AS3:
package 
{
	/**
	 * ...
	 * @author gbee
	 */
	public class TreeNode 
	{
		public var children:Array = [];
		public var count:int = 0;
		public function TreeNode() 
		{
 
		}
 
	}
 
}
Вложения
Тип файла: swf tree2.swf (1.9 Кб, 165 просмотров)
__________________
Чтобы доказать, что вы не робот, причините вред другому человеку.