![]() |
|
||||||||||
|
|||||
|
Практически ваша задача
http://www.gamedev.ru/code/forum/?id=72507
__________________
interplanety |
|
|||||
|
если устроит не совсем элипс, а скорее овал из кривых, то с помощью безьевых утилит Дембицкого можно
package { import flash.display.Graphics; import flash.display.Shape; import flash.display.Sprite; import flash.events.MouseEvent; import flash.geom.Bezier; import flash.geom.Point; public class Main extends Sprite { private var ball:Circle = new Circle(30); private var segments:Array = []; private var cX:Number = 300; private var cY:Number = 300; private var rX:Number = 200; private var rY:Number = 100; private var mX:Number; private var mY:Number; public function Main():void { ball.x = cX; ball.y = cY; addChild(ball); graphics.lineStyle(2); // типа 'элипс' из четырех безье for (var i:int = 0; i < 4; i++) { var a:Number = Math.PI * i / 2; var sP:Point = new Point(cX + Math.cos(a) * rX, cY + Math.sin(a) * rY); a += 0.5 * Math.PI; var eP:Point = new Point(cX + Math.cos(a) * rX, cY + Math.sin(a) * rY); var cP:Point = i % 2 ? new Point(eP.x, sP.y) : new Point(sP.x, eP.y); var segm:Bezier = new Bezier(sP, cP, eP); segments.push(segm); if (!i) graphics.moveTo(sP.x, sP.y); graphics..curveTo(cP.x, cP.y, eP.x, eP.y); } ball.addEventListener(MouseEvent.MOUSE_DOWN, ball_mouseDown); } private function ball_mouseDown(e:MouseEvent):void { mX = stage.mouseX; mY = stage.mouseY; stage.addEventListener(MouseEvent.MOUSE_UP, stage_mouseUp); stage.addEventListener(MouseEvent.MOUSE_MOVE, stage_mouseMove); } 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 { // двигаем ball.x += stage.mouseX - mX; ball.y += stage.mouseY - mY; mX = stage.mouseX; mY = stage.mouseY; // проверка и коррекция var dir:Number = Math.PI + Math.atan2(cY - ball.y, cX - ball.x); var segm:Bezier = segments[Math.floor(2 * dir / Math.PI) % 4]; var t:Number = segm.getClosest(new Point(ball.x, ball.y)); var tP:Point = segm.getPoint(t); if (Point.distance(new Point(ball.x, ball.y), tP) < ball.radius) { dir = Math.atan2(tP.y - ball.y, tP.x - ball.x); ball.x = tP.x - ball.radius * Math.cos(dir); ball.y = tP.y - ball.radius * Math.sin(dir); } } } } import flash.display.Sprite; class Circle extends Sprite { public var radius:Number; public function Circle(r:Number) { super(); radius = r; graphics.beginFill(0x808080); graphics.drawCircle(0, 0, r); } } а можно и не связываться с безье, а строить просто отрезками и брать ближайший по наименьшему расстоянию, тогда и эллипс будет как эллипс package { import flash.display.Graphics; import flash.display.Shape; import flash.display.Sprite; import flash.events.MouseEvent; import flash.geom.Point; public class Main extends Sprite { private var ball:Circle = new Circle(30); private var segments:Array = []; private var cX:Number = 300; private var cY:Number = 300; private var rX:Number = 200; private var rY:Number = 100; private var mX:Number; private var mY:Number; public function Main():void { ball.x = cX; ball.y = cY; addChild(ball); graphics.lineStyle(2); // элипс из отрезков var n:Number = 60; var dA:Number = 2 * Math.PI / n; var a:Number = 0; for (var i:int = 0; i < n; i++) { var sP:Point = new Point(cX + Math.cos(a) * rX, cY + Math.sin(a) * rY); a += dA; var eP:Point = new Point(cX + Math.cos(a) * rX, cY + Math.sin(a) * rY); var mid:Point = Point.interpolate(sP, eP, 0.5); segments.push(mid); if (!i) graphics.moveTo(sP.x, sP.y); graphics.lineTo(eP.x, eP.y); } ball.addEventListener(MouseEvent.MOUSE_DOWN, ball_mouseDown); } private function ball_mouseDown(e:MouseEvent):void { mX = stage.mouseX; mY = stage.mouseY; stage.addEventListener(MouseEvent.MOUSE_UP, stage_mouseUp); stage.addEventListener(MouseEvent.MOUSE_MOVE, stage_mouseMove); } 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 { // двигаем ball.x += stage.mouseX - mX; ball.y += stage.mouseY - mY; mX = stage.mouseX; mY = stage.mouseY; // проверка и коррекция var tP:Point; var min:Number = Number.MAX_VALUE; for (var i:int = 0; i < segments.length; i++) { var d:Number = Point.distance(new Point(ball.x, ball.y), segments[i]); if ( d< min) { tP = segments[i]; min = d; } } var dir:Number = Math.PI + Math.atan2(cY - ball.y, cX - ball.x); if (Point.distance(new Point(ball.x, ball.y), tP) < ball.radius) { dir = Math.atan2(tP.y - ball.y, tP.x - ball.x); ball.x = tP.x - ball.radius * Math.cos(dir); ball.y = tP.y - ball.radius * Math.sin(dir); } } } } import flash.display.Sprite; class Circle extends Sprite { public var radius:Number; public function Circle(r:Number) { super(); radius = r; graphics.beginFill(0x808080); graphics.drawCircle(0, 0, r); } } |
|
|||||
|
Регистрация: Feb 2011
Адрес: Украина Днепропетровск
Сообщений: 106
|
Спасибо всем за вкусные ссылочки. Сейчас срочную работу кинули и не могу их оценить по достоинству, но вижу что решения в них. Как разгребусь, покажу что получилось.
|
|
|||||
|
буду краток
модератор форума
Регистрация: Sep 2003
Адрес: Ближайшее Замкадье
Сообщений: 3,110
Записей в блоге: 28
|
Цитата:
это сам придумал или есть где? по стандартной но мне очень нравится onStage_mouseMove
__________________
Отряд Котовскага |
|
|||||
|
Регистрация: Feb 2012
Сообщений: 1,540
|
Цитата:
1. Зачем "_" в названиях функций? Очень некрасиво. 2. Лишний постфикс "Handler" к каждому хендлеру? Это то же самое, что и писать: Я пишу onObjectEvent, и настроил это в FD, например: Ничего лишнего. Но это всё ИМХО. Не стоит спорить по этому поводу ![]() |
|
|||||
|
target_eventName - привычная для C#, во всяком случае VS такие генерит по умолчанию
|
|
|||||
|
Регистрация: Feb 2011
Адрес: Украина Днепропетровск
Сообщений: 106
|
Во как получилось
http://vorodis2.com/test/debagElips/ Изюминка в том что надо было искать не край а центр, эллипса меньше на радиус круга. Правда при плоских эллипсах немного круг вылазит, но для моей задачи это не критично. Кому надо, вот исходник. http://vorodis2.com/test/debagElips/debagElips.rar |
![]() |
![]() |
Часовой пояс GMT +4, время: 23:46. |
|
|
« Предыдущая тема | Следующая тема » |
|
|