Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Поиск рулит! Сообщения за день Все разделы прочитаны
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему  
Старый 25.06.2013, 18:20
maincode вне форума Посмотреть профиль Отправить личное сообщение для maincode Посетить домашнюю страницу maincode Найти все сообщения от maincode
  № 4  
Ответить с цитированием
maincode

Регистрация: Feb 2010
Адрес: Город суеты
Сообщений: 191
Последняя версия (ru.flashpress.geom.FPAbout.VERSION = 0.1) лежит здесь http://flashpress.ru/blog/libs/ .
Если точка регистрации будет лежать не в центре, то мой пример работать не будет, надо поэкспериментировать, как будет время - допишу

Добавлено через 21 час 53 минуты
Дописал код так, что бы можно было вертеть объекты с точкой регистрации в левом верхнем углу:
Код AS3:
package
{
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.MouseEvent;
 
	import ru.flashpress.geom.line.FPGLine2d;
	import ru.flashpress.geom.line.math.FPGLineToPoint2dMath;
	import ru.flashpress.geom.point.FPGPoint2d;
	import ru.flashpress.geom.polygon.FPGEdge2d;
	import ru.flashpress.geom.polygon.FPGPolygon2d;
	import ru.flashpress.geom.polygon.FPGVertex2d;
 
	[SWF(width="600", height="600")]
	public class testRect2 extends Sprite
	{
		private static const CENTER_X:Number = 300;
		private static const CENTER_Y:Number = 300;
		//
		private var redRect:Sprite;
		private var purpleRect:Sprite;
		private var grayRect:Sprite;
		private var polygonRed:FPGPolygon2d;
		private var polygonPurp:FPGPolygon2d;
		public function testRect2()
		{
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			//
			var wRed:Number = 100;
			var hRed:Number = 200;
			var wPur:Number = 100;
			var hPur:Number = 150;
			//
			redRect = new Sprite();
			redRect.graphics.lineStyle(1, 0xff0000, 1);
			redRect.graphics.drawRect(0, 0, wRed, hRed);
			redRect.graphics.endFill();
			this.addChild(redRect);
			redRect.x = CENTER_X-wRed/2;
			redRect.y = CENTER_Y-hRed/2;
			//
			purpleRect = new Sprite();
			purpleRect.graphics.lineStyle(1, 0xff00ff, 1);
			purpleRect.graphics.drawRect(0, 0, wPur, hPur);
			purpleRect.graphics.endFill();
			this.addChild(purpleRect);
			purpleRect.x = redRect.x + (redRect.width-purpleRect.width)/2;
			purpleRect.y = redRect.y + (redRect.height-purpleRect.height)/2;
			//
			grayRect = new Sprite();
			grayRect.graphics.lineStyle(1, 0x999999, 1);
			grayRect.graphics.drawRect(0, 0, wPur, hPur);
			grayRect.graphics.endFill();
			this.addChild(grayRect);
			//
			// создаем полигон красного прямоугольника
			var redPoints:Vector.<FPGPoint2d> = new Vector.<FPGPoint2d>();
			redPoints.push(new FPGPoint2d(CENTER_X-wRed/2, CENTER_Y-hRed/2));
			redPoints.push(new FPGPoint2d(CENTER_X+wRed/2, CENTER_Y-hRed/2));
			redPoints.push(new FPGPoint2d(CENTER_X+wRed/2, CENTER_Y+hRed/2));
			redPoints.push(new FPGPoint2d(CENTER_X-wRed/2, CENTER_Y+hRed/2));
			polygonRed = new FPGPolygon2d(redPoints);
			//
			// создаем полигон фиолетового прямоугольника
			var purpPoints:Vector.<FPGPoint2d> = new Vector.<FPGPoint2d>();
			purpPoints.push(new FPGPoint2d(CENTER_X-wPur/2, CENTER_Y-hPur/2));
			purpPoints.push(new FPGPoint2d(CENTER_X+wPur/2, CENTER_Y-hPur/2));
			purpPoints.push(new FPGPoint2d(CENTER_X+wPur/2, CENTER_Y+hPur/2));
			purpPoints.push(new FPGPoint2d(CENTER_X-wPur/2, CENTER_Y+hPur/2));
			polygonPurp = new FPGPolygon2d(purpPoints);
			//
			this.stage.addEventListener(MouseEvent.MOUSE_MOVE, moveHandler);
			rotate(0);
			calculate();
		}
 
 
		private function moveHandler(event:MouseEvent):void
		{
			event.updateAfterEvent();
			var dx:Number = this.mouseX-purpleRect.x;
			var dy:Number = this.mouseY-purpleRect.y;
			var radians:Number = Math.atan2(dy, dx);
			rotate(radians);
			calculate();
		}
 
		private var oldRotate:Number = 0;
		private function rotate(radians:Number):void
		{
			// поворачиваем филотетовый полигон относительно центральной точки CENTER_X-CENTER_Y
			// на угол равный разнице между текущим значением и предыдущим
			polygonPurp.rotation(radians-oldRotate, new FPGPoint2d(CENTER_X, CENTER_Y));
			oldRotate = radians;
			//
			//
			// поворачиваем Displayobject-ы
			grayRect.rotation = purpleRect.rotation = radians*180/Math.PI;
			// задаем фиолетовому спрайту координаты смещения
			purpleRect.x = polygonPurp.vertexes[0].x;
			purpleRect.y = polygonPurp.vertexes[0].y;
		}
 
		private function calculate():void
		{
			var i:int;
			var j:int;
			var vertex:FPGVertex2d;
			var edge:FPGEdge2d;
			var heightLine:FPGLine2d;
			//
			var leftPoint:FPGVertex2d;
			var leftEdge:FPGEdge2d;
			var maxScale:Number = 1;
			for (i=0; i<polygonRed.vertexes.length; i++) {
				// текущая вершина красного полигона
				vertex = polygonRed.vertexes[i];
				for (j=0; j<polygonPurp.edges.length; j++) {
					// текущее ребро фиолетового полигона
					edge = polygonPurp.edges[j];
					// если вершина лежит "слева" от ребра, то пропускаем проверку
					// в случае прямоугольников если вершина лежит "слева" -
					// это значит что данное ребро не является наиближайщим к данной вершине
					if (edge.valueFromPoint(vertex) <= 0) continue;
					// получаем отрезок прямой опущенной из вершины на ребро 
					heightLine = FPGLineToPoint2dMath.lineHeight(edge, vertex);
					//
					// определяем левую вершину ребра
					leftPoint = edge.p1 as FPGVertex2d;
					// определяем левое ребро
					// в итоге leftEdge будет ссылаться на ребро соседнее с edge
					leftEdge = leftPoint.leftEdge;
					// определяем максимальный scale
					// длина перпендикуляра heightLine умноженная на 2 - это то значение,
					// на которое надо увеличить соседнее ребро,
					// что бы фиолетовый прямоугольник прошел через текущую вершину
					maxScale = Math.max(maxScale, (leftEdge.length+heightLine.length*2)/leftEdge.length);
				}
			}
			//
			grayRect.scaleX = grayRect.scaleY = maxScale;
			// создаем копию фиолетового полигона
			var polygonClone:FPGPolygon2d = polygonPurp.clone();
			// применяем к этому полигону scale относительно центральной точки
			polygonClone.scale(maxScale, maxScale, new FPGPoint2d(CENTER_X, CENTER_Y));
			// и задаем увеличенному спрайту координаты смещения
			grayRect.x = polygonClone.vertexes[0].x;
			grayRect.y = polygonClone.vertexes[0].y;
		}
	}
}
Дописал библиотеку FPGeometry2d - обновил метод scale(sx, sy) так, что бы можно было передать в него точку, относительно которой происходит растяжение (Текущая версия ru.flashpress.geom.FPAbout.VERSION = 0.1.1)
__________________
FlashPress.ru | Blog

Создать новую тему   Часовой пояс GMT +4, время: 22:47.
Быстрый переход
  « Предыдущая тема | Следующая тема »  
Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 22:47.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.