Показать сообщение отдельно
Старый 31.01.2016, 14:36
Tails вне форума Посмотреть профиль Отправить личное сообщение для Tails Найти все сообщения от Tails
  № 9  
Ответить с цитированием
Tails
 
Аватар для Tails

блогер
Регистрация: Dec 2008
Адрес: г. Чебоксары
Сообщений: 2,259
Записей в блоге: 6
Вообщем, что то такое я набросал, вариант правда далёк от завершения.
Думаю, сперва лучше забить всё поле квадратами, а затем для каждой из сторон искать свободную площадь. В примере ищется площадь для верхней стороны квадратов.

Клик мышки - обновить:
Test.swf   (1.5 Кб)


Код:
Код AS3:
package
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
 
 
	/**
	 * Тест.
	 * @author Tails
	 */
	public class Main extends Sprite {
 
		// Приват
		private var _quadsTotal:uint;						// Количество квадратов.
		private var _space:Rectangle;						// Размер мира.
		private var _sprite:Sprite;							// Рисунок результата.
		private var _quads:Vector.<Rectangle>;				// Рассекающие квадраты.
		private var _result:Vector.<Rectangle>;				// Полученные области.
 
 
		public function Main() {
			if (stage === null)
				addEventListener(Event.ADDED_TO_STAGE, init);
			else
				init();
		}
		private function init(e:Event = null):void {
			removeEventListener(Event.ADDED_TO_STAGE, init);
 
			_sprite				= new Sprite;
			addChild(_sprite);
 
 
			stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
			onMouseDown();
		}
		private function onMouseDown(e:MouseEvent = null):void {
			var i:uint;
			var quad:Rectangle;
 
 
			// ГЕНЕРАЦИЯ МИРА
			// Общие параметры и свойства:
			_quadsTotal			= 5;
			_space				= new Rectangle(100, 100, 400, 300);
			_quads				= new Vector.<Rectangle>;
			_result				= new Vector.<Rectangle>;
 
			// Создаём рассекающие квадраты:
			i					= 0;
			while (i < _quadsTotal) {
				_quads[i]		= createRandomQuad();
				i ++;
			}
 
			//_quads.push(new Rectangle(200, 10, 10, 200));
			//_quads.push(new Rectangle(300, 150, 50, 30));
 
			// АЛГОРИТМ
			// Обходим каждую сторону получившегося квадрата, 
			// формируя прямоугольник свободного пространства:
			i					= _quadsTotal;
			while (i--) {
 
				// Получаем область для каждой стороны. (Может быть null, если области не существует)
				// Верхняя сторона:
				quad			= getFreeSpaceForTop(_quads[i]);
				if (quad !== null)
					_result.push(quad);
			}
 
 
			// РЕНДЕР.
			// Рисунок:
			_sprite.graphics.clear();
			_sprite.x			= _space.x;
			_sprite.y			= _space.y;
			addChild(_sprite);
 
			// Мир:
			_sprite.graphics.lineStyle(1, 0x999999);
			_sprite.graphics.drawRect(0, 0, _space.width, _space.height);
 
			// Результат:
			i					= _result.length;
			while (i--) {
				quad			= _result[i];
				_sprite.graphics.lineStyle(1, Math.random() * 0xcccccc);
				_sprite.graphics.drawRect(quad.x, quad.y, quad.width, quad.height);
			}
 
			// Квадраты:
			i					= _quadsTotal;
			_sprite.graphics.lineStyle(1, 0x0);
			_sprite.graphics.beginFill(0, 1);
			while (i--) {
				quad			= _quads[i];
				_sprite.graphics.drawRect(quad.x, quad.y, quad.width, quad.height);
			}
		}
 
 
		// ПРИВАТ
		private function createRandomQuad():Rectangle {
			const minSize:uint				= 10;		// Минимальный размер стороны квадрата.
			const maxSize:uint				= 50;		// Максимальный.
			const quad:Rectangle			= new Rectangle();
 
			quad.width			= Math.round(Math.random() * (maxSize - minSize) + minSize);
			quad.height			= Math.round(Math.random() * (maxSize - minSize) + minSize);
			quad.x				= Math.round(Math.random() * (_space.width - quad.width));
			quad.y				= Math.round(Math.random() * (_space.height - quad.height));
 
			return quad;
		}
		private function getFreeSpaceForTop(currentQuad:Rectangle):Rectangle {
			var i:uint;
			var quad:Rectangle;
			var free:Rectangle;
			var value:Number;
			var dx:Number;
			var dy:Number;
 
 
			// Получаем свободную область для верхней стороны.
			// Получаем будущий прямоугольник области:
			free				= new Rectangle(0, 0, _space.width, _space.height - (_space.height - currentQuad.y));
 
			// Обходим все имеющиеся прямоугольники:
			i					= _quadsTotal;
			while (i--) {
				quad			= _quads[i];
 
				// Проверка сама с собою пропускается:
				if (quad === currentQuad)
					continue;
 
				// Пересечение свободной области с квадратом.
				// Глубина пересечения по X:
				if (quad.x > free.x)
					dx			= free.x - quad.x + free.width;
				else
					dx			= quad.x - free.x + quad.width;
 
				// Глубина пересечения по Y:
				if (quad.y > free.y)
					dy			= free.y - quad.y + free.height;
				else
					dy			= quad.y - free.y + quad.height;
 
				// Обрезание по Y:
				if (dy > 0) {
					if (dx > 0) {
 
						// Есть пересечение.
						// Проверка типа пересечения, оно может быть частичным или сквозным:
						if (dy < free.height) {
 
							// Частичное пересечение.
							// Выбираем способ обрезания:
							if (quad.y > free.y) {
 
								// Блок ниже нас.
								// В зависимости от его расположения, обрезаемся справа или cлева:
								if (quad.x > currentQuad.x) {
									free.width			-= dx;
								}
								else {
									value				= quad.x + quad.width;
									if (value > free.x) {
										free.x			= value;
										free.width		= dx - quad.width;
									}
								}
							}
							else {
 
								// Блок выше нас.
								// Просто обрезаемся на величину пересечения:
								free.y			+= dy;
								free.height 	-= dy;
							}
						}
						else {
 
							// Сквозное пересечение.
							continue;
						}
					}
 
					// Нет пересечения по X.
					continue;
				}
 
				// Нет пересечения по Y.
				continue;
			}
 
			return free;
		}
		/*
		private function hitTest(a:Rectangle, b:Rectangle):Boolean {
			var value:Number;
 
 
			// Проверка пересечеения двух прямоугольников.
			// Приводим обоих в одну точку отсчёта, добавляя разницу к ширине и высоте.
 
			// Проверка пересечения по X:
			if (a.x > b.x)
				value			= b.x - a.x + b.width;
			else
				value			= a.x - b.x + a.width;
 
			if (value < 0)
				return false;
 
			// Проверка пересечения по Y:
			if (a.y > b.y)
				value			= b.y - a.y + b.height;
			else
				value			= a.y - b.y + a.height;
 
			if (value < 0)
				return false;
 
			// Блоки пересекаются:
			return true;
		}
		*/
	}
}
Вложения
Тип файла: swf Test.swf (1.5 Кб, 132 просмотров)
__________________
Дети не должны знать о своих родителях