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

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

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 06.05.2015, 17:31
Alex626 вне форума Посмотреть профиль Отправить личное сообщение для Alex626 Найти все сообщения от Alex626
  № 1  
Ответить с цитированием
Alex626

Регистрация: Sep 2010
Сообщений: 167
По умолчанию Отрисовка кривой со стрелочкой на конце

Добрый день!

У меня возникла необходимость отрисовывать в программе кривые линии методом curveTo, и нужно чтобы на конце каждая такая линия оканчивалась стрелочкой. Как в иллюстраторе. С прямыми линиями lineTo всё было проще - можно узнать градус наклона линии, и соответственно, отрисовать на конце стрелку под определённым углом. А вот с кривыми проблема - контрольная точка вносит неясность, и непонятно, как определять угол касательной на конце этой кривой. А нужно очень точно определять, чтобы работало с любым искривлением.

Есть материал, но он для прямых линий: http://stackoverflow.com/questions/8...ing-line-slope

Вопрос: можно ли как-то математически вычислить этот угол наклона, и как это сделать? Можно ли придумать какой-то иной способ для реализации задуманного?

Спасибо большое за внимание!

Старый 06.05.2015, 18:04
undefined вне форума Посмотреть профиль Отправить личное сообщение для undefined Найти все сообщения от undefined
  № 2  
Ответить с цитированием
undefined

Регистрация: Oct 2006
Сообщений: 2,282
Глядя сюда,можно предположить что можно использовать алгоритм рисования стрелочки для прямой.Только в качестве прямой будет касательная в конце курвы(от controlX;controlY до anchorX;anchorY)


Последний раз редактировалось undefined; 06.05.2015 в 20:18.
Старый 06.05.2015, 18:57
OlmerDale вне форума Посмотреть профиль Отправить личное сообщение для OlmerDale Найти все сообщения от OlmerDale
  № 3  
Ответить с цитированием
OlmerDale

Регистрация: Jan 2015
Сообщений: 113
Цитата:
Глядя сюда можно предположить что можно использовать алгоритм рисования стрелочки для прямой.
Смотря какие требования к точности. Правильную стрелку можно нарисовать отложив точку на кривой образующую прямую (равную длине стрелки) с конечной точкой кривой. И вот от этой точки отложить две перпендикулярные прямые равные половине основания стрелки.
Если так не сделать, то будет ощущение, что кривая не в центр входит.

Старый 06.05.2015, 19:38
undefined вне форума Посмотреть профиль Отправить личное сообщение для undefined Найти все сообщения от undefined
  № 4  
Ответить с цитированием
undefined

Регистрация: Oct 2006
Сообщений: 2,282
Насколько я понял проблема не в том как нарисовать стрелку,а в том,как найти угол,на который надо повернуть изображение стрелки.
Цитата:
Если так не сделать, то будет ощущение, что кривая не в центр входит.
ничего не будет направление стрелки должно совпадать с касательной на конце


Последний раз редактировалось dimarik; 06.05.2015 в 22:09. Причина: Поправил тег цитирования. Круто было бы еще пробелы проставлять после знаков препинания
Старый 06.05.2015, 19:39
OlmerDale вне форума Посмотреть профиль Отправить личное сообщение для OlmerDale Найти все сообщения от OlmerDale
  № 5  
Ответить с цитированием
OlmerDale

Регистрация: Jan 2015
Сообщений: 113
Ну так откладываемый на кривой отрезок и будет угол относительно точки конца..

Я вот о чем, F это опорная точка -

Хотя так тоже некрасиво. Лучше искать ещё одну точку и саму стрелку изгибать относительно кривой.
Изображения
 


Последний раз редактировалось dimarik; 06.05.2015 в 22:36.
Старый 06.05.2015, 21:43
Wolsh вне форума Посмотреть профиль Отправить личное сообщение для Wolsh Найти все сообщения от Wolsh
  № 6  
Ответить с цитированием
Wolsh
Нуб нубам
 
Аватар для Wolsh

модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
В направлении контрольной точки рисуете прямой штришок на длину стрелки (корень стрелки) и кривую приводите к нему. Тоесть рисуете короткую прямую стрелку и присоединяете к ней кривую.
__________________
Reality.getBounds(this);

Старый 06.05.2015, 23:16
Alex626 вне форума Посмотреть профиль Отправить личное сообщение для Alex626 Найти все сообщения от Alex626
  № 7  
Ответить с цитированием
Alex626

Регистрация: Sep 2010
Сообщений: 167
Цитата:
Сообщение от Wolsh Посмотреть сообщение
В направлении контрольной точки рисуете прямой штришок на длину стрелки (корень стрелки) и кривую приводите к нему. Тоесть рисуете короткую прямую стрелку и присоединяете к ней кривую.
Я пробовал, но это выглядит не так надёжно. К тому же, если контрольная точка находится близко к краю, и у кривой сильный изгиб в конце, то это не будет работать.

Цитата:
Сообщение от OlmerDale Посмотреть сообщение
Лучше искать ещё одну точку и саму стрелку изгибать относительно кривой.
Как это сделать в коде? Я имею в виду, какую именно точку - как её найти?

Старый 07.05.2015, 15:43
OlmerDale вне форума Посмотреть профиль Отправить личное сообщение для OlmerDale Найти все сообщения от OlmerDale
  № 8  
Ответить с цитированием
OlmerDale

Регистрация: Jan 2015
Сообщений: 113
Цитата:
Как это сделать в коде? Я имею в виду, какую именно точку - как её найти?
Найти нужно точку G, а как это сделать, знаю лишь приблизительно, опробовать время нет.
Но на словах - найти длину кривой и узнать процентное соотношение длины наконечника к кривой.
А дальше с помощью аппроксимации найти координаты этой точки. И так наверное даже лучше будет,
так как если сильно загнуть и приблизить опорную точку к концу кривой, то сама стрелка будет визуально немного меньше из-за того, что нахождение описанное выше предполагает, что искомый отрезок в точности совпадает с кривой.

Старый 07.05.2015, 20:54
OlmerDale вне форума Посмотреть профиль Отправить личное сообщение для OlmerDale Найти все сообщения от OlmerDale
  № 9  
Ответить с цитированием
OlmerDale

Регистрация: Jan 2015
Сообщений: 113
Качаете bezier. которая Вам покажет и координаты точки и угол наклона в этой точке и длину все кривой. Этой информации хватит чтобы любую стрелку отрисовать.
Код AS3:
package
{
	import flash.display.DisplayObject;
	import flash.display.Graphics;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Bezier;
	import flash.geom.Point;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
 
 
	public class Main extends Sprite 
	{
		private var _allCircles:Vector.<DisplayObject> = new Vector.<DisplayObject>();
 
		private var _currentPivotPoint:DisplayObject;
		private var _bezier:Bezier;
		private var _map:Object;
		private var _pivot:DisplayObject;
		private var _textField:TextField;
 
		public function Main() 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
 
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
 
			stage.color = 0x232323;
 
			_textField = new TextField();
			_textField.textColor = 0x595959;
			_textField.autoSize = TextFieldAutoSize.LEFT;
			super.addChild(_textField);
 
			var start:Point = new Point(100, 100);
			var end:Point = new Point(300, 100);
			var control:Point = new Point(200, 50);
 
			_bezier = new Bezier(start, control, end);
 
			var a:DisplayObject = this.createCircle();
			var b:DisplayObject = this.createCircle();
			var c:DisplayObject = this.createCircle();
 
			a.name = 'start';
			b.name = 'end';
			c.name = 'control';
 
			_map = { };
			_map[a.name] = _bezier.start;
			_map[b.name] = _bezier.end;
			_map[c.name] = _bezier.control;
 
			this._allCircles.push(a);
			this._allCircles.push(b);
			this._allCircles.push(c);
 
			a.x = start.x;
			a.y = start.y;
 
			b.x = end.x;
			b.y = end.y;
 
			c.x = control.x;
			c.y = control.y;
 
			super.addChild(a);
			super.addChild(b);
			super.addChild(c);
 
			_pivot = this.createCircle(1, 0xEB0101);
 
			super.addChild(_pivot);
 
			this.drawCurve();
 
			stage.addEventListener(MouseEvent.MOUSE_DOWN, stage_mouseDownHandler);
			stage.addEventListener(MouseEvent.MOUSE_UP, stage_mouseUpHandler);
		}
 
		private function stage_mouseUpHandler(event:MouseEvent):void 
		{
			super.removeEventListener(Event.ENTER_FRAME, super_enterFrameHandler);
		}
 
		private function stage_mouseDownHandler(event:MouseEvent):void 
		{
			if (this._allCircles.length == 3)
			{
				var length:int = this._allCircles.length;
 
				while (length-- > 0)
				{
					if (this._allCircles[length].hitTestPoint(event.stageX, event.stageY, true))
					{
						this._currentPivotPoint = this._allCircles[length];
						super.addEventListener(Event.ENTER_FRAME, super_enterFrameHandler);
					}
				}
			}
		}
 
		private function super_enterFrameHandler(event:Event):void 
		{
			var point:Point = this._map[this._currentPivotPoint.name];
 
			point.x = this._currentPivotPoint.x = super.stage.mouseX
			point.y = this._currentPivotPoint.y = super.stage.mouseY;
 
			this.drawCurve();
		}
 
		private function createCircle(radius:Number = 4, color:uint = 0x67CDD6, lineSize:Number = 1, lineColor:uint = 0xFFFFFF):DisplayObject
		{
			var circle:Shape = new Shape();
			var graphics:Graphics = circle.graphics;
 
			graphics.beginFill(color);
			graphics.lineStyle(lineSize, lineColor);
			graphics.drawCircle(0, 0, radius);
			graphics.endFill();
 
			return circle;
		}
 
		private function drawCurve():void
		{
			var point:Point =  _bezier.getPoint(.9);
 
			this._textField.text = 'point x: ' + point.x + '\n' + 'point y: ' + point.y + '\n' + 'angle: ' + _bezier.getTangentAngle(.9) + '\n' + 'length: ' + _bezier.length;
 
			trace(point, _bezier.getTangentAngle(.9));
			_pivot.x = point.x;
			_pivot.y = point.y;
 
			super.graphics.clear();
			super.graphics.lineStyle(1);
			super.graphics.moveTo(this._bezier.start.x, this._bezier.start.y);
			super.graphics.curveTo(this._bezier.control.x, this._bezier.control.y, this._bezier.end.x, this._bezier.end.y);
		}
 
	}
 
}

Голосуем за редактор! Если Вы уже голосовали, то голосуйте ещё раз, при смене ip это становится возможным!
Не дадим haxe одержать победу на as3.

bezier.swf   (19.5 Кб)
Вложения
Тип файла: swf bezier.swf (19.5 Кб, 124 просмотров)

Старый 07.05.2015, 20:58
Alex626 вне форума Посмотреть профиль Отправить личное сообщение для Alex626 Найти все сообщения от Alex626
  № 10  
Ответить с цитированием
Alex626

Регистрация: Sep 2010
Сообщений: 167
Просто великолепно! Спасибо огромное!

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

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

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


 


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


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