Показать сообщение отдельно
Старый 25.06.2013, 16:21
maincode вне форума Посмотреть профиль Отправить личное сообщение для maincode Посетить домашнюю страницу maincode Найти все сообщения от maincode
  № 2  
Ответить с цитированием
maincode

Регистрация: Feb 2010
Адрес: Город суеты
Сообщений: 191
Пример testRect.swf.
Алгоритм:
Проходим циклом по всем вершинам(точнее по двум соседним) красного прямоугольника, и опускаем перпендикуляр до ближайшего ребра фиолетового прямоугольника. Длина этого перпендикуляра - это та разница на которую надо увеличить соседнее(!!!) ребро фиолетового прямоугольника, так, что бы фиолетовый прямоугольник прошел через проверяемую вершину красного. Далее находим максимальный scale и применяем его к фиолетовому прямоугольнику.

Вот как выглядит код:
Код 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 testRect extends Sprite
	{
		private var redRect:Sprite;
		private var purpleRect:Sprite;
		private var grayRect:Sprite;
		private var polygonRed:FPGPolygon2d;
		private var polygonPurp:FPGPolygon2d;
		public function testRect()
		{
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			//
			var cx:Number = 300;
			var cy:Number = 300;
			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(-wRed/2, -hRed/2, wRed, hRed);
			redRect.graphics.endFill();
			this.addChild(redRect);
			redRect.x = cx;
			redRect.y = cy;
			//
			purpleRect = new Sprite();
			purpleRect.graphics.lineStyle(1, 0xff00ff, 1);
			purpleRect.graphics.drawRect(-wPur/2, -hPur/2, wPur, hPur);
			purpleRect.graphics.endFill();
			this.addChild(purpleRect);
			purpleRect.x = cx;
			purpleRect.y = cy;
			//
			grayRect = new Sprite();
			grayRect.graphics.lineStyle(1, 0x999999, 1);
			grayRect.graphics.drawRect(-wPur/2, -hPur/2, wPur, hPur);
			grayRect.graphics.endFill();
			this.addChild(grayRect);
			grayRect.x = cx;
			grayRect.y = cy;
			//
			var redPoints:Vector.<FPGPoint2d> = new Vector.<FPGPoint2d>();
			redPoints.push(new FPGPoint2d(cx-wRed/2, cy-hRed/2));
			redPoints.push(new FPGPoint2d(cx+wRed/2, cy-hRed/2));
			redPoints.push(new FPGPoint2d(cx+wRed/2, cy+hRed/2));
			redPoints.push(new FPGPoint2d(cx-wRed/2, cy+hRed/2));
			polygonRed = new FPGPolygon2d(redPoints);
			//
			var purpPoints:Vector.<FPGPoint2d> = new Vector.<FPGPoint2d>();
			purpPoints.push(new FPGPoint2d(cx-wPur/2, cy-hPur/2));
			purpPoints.push(new FPGPoint2d(cx+wPur/2, cy-hPur/2));
			purpPoints.push(new FPGPoint2d(cx+wPur/2, cy+hPur/2));
			purpPoints.push(new FPGPoint2d(cx-wPur/2, cy+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
		{
			grayRect.rotation = purpleRect.rotation = radians*180/Math.PI;
			polygonPurp.rotation(radians-oldRotate, new FPGPoint2d(purpleRect.x, purpleRect.y));
			oldRotate = radians;
		}
 
		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 = leftPoint.leftEdge;
					maxScale = Math.max(maxScale, (leftEdge.length+heightLine.length*2)/leftEdge.length);
				}
			}
			grayRect.scaleX = grayRect.scaleY = maxScale;
		}
	}
}
Для математических расчетов на плоскости использовал библиотеку FPGeometry2d.swc
__________________
FlashPress.ru | Blog


Последний раз редактировалось maincode; 25.06.2013 в 16:42.