|
|
|||||
Регистрация: Oct 2010
Сообщений: 85
|
Добавление поинтов на отрезок
Для примера, есть некий отрезок, не линия, а ректангл. У отрезка есть марекры(поинты) начала и конца, за которые, если тянуть, то отрезок будет вращаться за мышью меняя при этом свою длину.
Задача в том, чтобы добавить на отрезок в произвольное место дополнительные маркеры. При перемещении маркеров было бы что-то вроде этого. Я делаю так. При нажатии в место, где должен быть маркер, создаю еще один отрезок с длиной относительно положении мыши на первом отрезке, записываю его в массив и так далее ос всеми отрезками. Но сейчас я слабо представляю, как потянув за маркер получить то, что на картинке, ведь теперь, при перемещении маркера нужно чтобы за ним тянулись сразу несколько отрезков. Возможно у меня подход вообще не правильный, подскажите, кто что думает. |
|
|||||
Если вам нужен результат именно такой как на картинках, то вы можете вместо прямоугольников использовать просто одну широкую линию, а чтобы у неё были углы в местах сгибов, то установить для линии CapsStyle.NONE и JointStyle.MITER И при движении точек, просто перерисовывайте эту линию.
Лучше на примере. Класс точки. Просто рисует круг, который можно таскать мышкой, при перетаскивании диспатчит событие MOVED. MovePoint package { import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; public class MovePoint extends Sprite { static public const MOVED:String = "pointMoved"; public function MovePoint(xPos:int = 0, yPos:int = 0) { graphics.lineStyle(0.1); graphics.beginFill(0xFFFFFF); graphics.drawCircle(0, 0, 5); graphics.endFill(); x = xPos; y = yPos; buttonMode = true; addEventListener(MouseEvent.MOUSE_DOWN, mouseDown); } private function mouseDown(e:MouseEvent):void { stage.addEventListener(MouseEvent.MOUSE_MOVE, stage_mouseMove); stage.addEventListener(MouseEvent.MOUSE_UP, stage_mouseUp); } private function stage_mouseUp(e:MouseEvent):void { stage.removeEventListener(MouseEvent.MOUSE_MOVE, stage_mouseMove); stage.removeEventListener(MouseEvent.MOUSE_UP, stage_mouseUp); } private function stage_mouseMove(e:MouseEvent):void { x = e.stageX; y = e.stageY; dispatchEvent(new Event(MOVED, true)); } } } Main package { import flash.display.CapsStyle; import flash.display.JointStyle; import flash.display.Sprite; import flash.events.Event; import flash.geom.Point; /** * ... * @author samana */ public class Main extends Sprite { private var _points:Array = []; public function Main():void { for (var i:int = 0; i < 8; i++) { var p:MovePoint = new MovePoint(80 + i * 50, 50 + Math.random() * 100); addChild(p); _points[i] = p; } moved(); addEventListener(MovePoint.MOVED, moved); } private function moved(e:Event=null):void { graphics.clear(); graphics.lineStyle(20, 0xCCCCCC, 1, false, "normal", CapsStyle.NONE, JointStyle.MITER); graphics.moveTo(_points[0].x, _points[0].y); for (var i:int = 1; i < _points.length; i++) { graphics.lineTo(_points[i].x, _points[i].y); } } } } Последний раз редактировалось samana; 21.07.2014 в 14:13. Причина: добавлена информация |
|
|||||
Регистрация: Oct 2010
Сообщений: 85
|
Это очень здорово, но все таки должна быть не линия, а полноценный примитив. Это необходимо чтобы была возможность получить расположение точек
координаты которых будут использоваться для расположения вертексов по которым будет строиться геометрия стены. Вообще вот к этому есть стремление, но там нереально круто это сделано. http://realaxy.com/plans/new |
|
|||||
вот осталось от одной похожей темы
за универсальность\надежность не поручусь, но может сгодится на что package { import flash.display.Graphics; import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.Event; import flash.geom.Point; public class Main extends Sprite { private var markers:Vector.<Marker>; public function Main():void { stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_LEFT; markers = Vector.<Marker>([ new Marker(100, 100, this), new Marker(200, 100, this), new Marker(300, 100, this), new Marker(400, 100, this), new Marker(500, 100, this) ]); addEventListener(Event.ENTER_FRAME, this_enterFrame); } private function this_enterFrame(e:Event):void { graphics.clear(); var points:Vector.<Point> = new Vector.<Point>(); for (var i:int = 0; i < markers.length; i++) { //var j:int = markers.length - 1 - i; points.push(markers[i].location); } graphics.beginFill(0x0, 0.25); graphics.lineStyle(0, 0xFF0000); filledLine(graphics, points, 40 ); } public static function filledLine(g:Graphics, points:Vector.<Point>, thickness:Number, miterLimit:Number = 3):void { var s2:Point; var s1:Point; var n2:Point; var n1:Point; var p:Point; var a1:Number; var a2:Number; var d1:Point; var d2:Point; var dP:Point; var dir:Number; var arm:Number; var i:int; var arr1:Array = []; var arr2:Array = []; var arr:Array = []; var l:int = points.length; var maxDist:Number = miterLimit ? miterLimit * thickness : Number.MAX_VALUE; // winding var angle1:Number = 0; var angle2:Number = 0; for (i = 0; i < l; i++) { var dp1:Point = points[(i + 1) % points.length].subtract(points[(i + 0) % points.length]); var dp2:Point = points[(i + 1) % points.length].subtract(points[(i + 2) % points.length]); var aa1:Number = Math.atan2(dp1.y, dp1.x); var aa2:Number = Math.atan2(dp2.y, dp2.x); var da1:Number = aa1 - aa2; var da2:Number = aa2 - aa1; if (da1 < 0) da1 += Math.PI * 2; if (da2 < 0) da2 += Math.PI * 2; angle1 += da1; angle2 += da2; } if (angle2 < angle1) { var tmp:Vector.<Point> = new Vector.<Point>(); for (i = 0; i < points.length; i++) { tmp[i] = points[l - i - 1]; } points = tmp; } // крайняя dP = points[1].subtract(points[0]); arm = 0.5 * thickness; dir = Math.atan2(dP.y, dP.x) - Math.PI * 0.5; dP = Point.polar(arm, dir); arr.push(points[0].subtract(dP), points[0].add(dP)); // промежуточные for (i = 1; i < l - 1; i++) { d1 = points[i].subtract(points[i - 1]); d2 = points[i].subtract(points[i + 1]); a1 = Math.atan2(d1.y, d1.x); a2 = Math.atan2(d2.y, d2.x); arm = 0.5 * thickness / Math.sin(0.5 * (a1 - a2)); dir = 0.5 * (a1 + a2); //dir += Math.PI; dP = Point.polar(arm, dir); if (Math.abs(arm) > maxDist) { n1 = Point.polar(0.5 * thickness, a1 + 1.5 * Math.PI); n2 = Point.polar(0.5 * thickness, a2 + 0.5 * Math.PI); s1 = Point.polar(maxDist, a1); s2 = Point.polar(maxDist, a2); arr.push(points[i].add(n1.add(s1))); arr.push(points[i].add(n2.add(s2))); } else { arr.push(points[i].add(dP)); } arr2.push(points[i].subtract(dP)); // внутренняя } // крайняя dP = points[l - 2].subtract(points[l - 1]); arm = 0.5 * thickness; dir = Math.atan2(dP.y, dP.x) - Math.PI * 0.5; dP = Point.polar(arm, dir); arr.push(points[l - 1].subtract(dP), points[l - 1].add(dP)); // внутренний контур while (arr2.length) { arr.push(arr2.pop()); } g.moveTo(arr[arr.length - 1].x, arr[arr.length - 1].y); for (i = 0; i < arr.length; i++) { g.lineTo(arr[i].x, arr[i].y); } } } } ///////////////// import flash.display.DisplayObjectContainer; import flash.display.Sprite; import flash.events.MouseEvent; import flash.geom.Point; class Marker extends Sprite { private var mX:Number; private var mY:Number; public function Marker(x:Number = 0, y:Number = 0, parent:DisplayObjectContainer = null) { this.x = x; this.y = y; graphics.beginFill(0x000000, 0.5); graphics.drawCircle(0, 0, 10); if (parent) { parent.addChild(this); } addEventListener(MouseEvent.MOUSE_DOWN, mouseDown); buttonMode = true; } public function get location():Point { return new Point(x, y); } private function mouseDown(e:MouseEvent):void { stage.addEventListener(MouseEvent.MOUSE_MOVE, stage_mouseMove); stage.addEventListener(MouseEvent.MOUSE_UP, stage_mouseUp); mX = stage.mouseX; mY = stage.mouseY; } private function stage_mouseUp(e:MouseEvent):void { stage.removeEventListener(MouseEvent.MOUSE_UP, stage_mouseUp); stage.removeEventListener(MouseEvent.MOUSE_MOVE, stage_mouseMove); } private function stage_mouseMove(e:MouseEvent):void { x += stage.mouseX - mX; y += stage.mouseY - mY; mX = stage.mouseX; mY = stage.mouseY; } } |
Часовой пояс GMT +4, время: 18:04. |
|
« Предыдущая тема | Следующая тема » |
Опции темы | |
Опции просмотра | |
|
|