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

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

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

Регистрация: May 2013
Сообщений: 6
Question Как стереть часть линии

Делаю простейший редактор для рисования. В котором можно рисовать только линиями. Возникла проблема в реализации стерки. Так и не смог сам побороть (
Подскажите как можно стереть/удалить часть нарисованной линии?
Маски и растр использовать нельзя, нужно именно в векторе удалять.

Первое что приходит на ум рисовать поверх спрайт и удалять его, поидее он должен затирать то что под ним, но он как отдельный обьект просто с верху ложиться (что не удивительно) и ничего не происходит/ (Во Flash IDE, похоже, что сделано именно так, спрайтом поверх)

Второе это юзать Vector.<IGraphicsData> считывать обьект и удалять точки по которым строятся линии, но это как то слишклм сложно... может есть попроще решение?


Последний раз редактировалось studentsimf; 09.05.2013 в 16:32.
Старый 09.05.2013, 03:38
Idon'tKnow вне форума Посмотреть профиль Отправить личное сообщение для Idon'tKnow Найти все сообщения от Idon'tKnow
  № 2  
Ответить с цитированием
Idon'tKnow

Регистрация: Apr 2013
Сообщений: 77
Вот есть идея. Просто перерисовывать линию белую, если нужно стереть. Не подходит такой вариант?

Код AS3:
package 
{
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.display.Graphics;
	import flash.events.MouseEvent;
 
	/**
	 * ...
	 */
	public class Main extends Sprite 
	{
	private var container:Sprite;	
	private var simpleRect:Shape;
		public function Main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
			container = new Sprite();
			simpleRect = new Shape();
			simpleRect.graphics.beginFill(0xFAAAFA);
			simpleRect.graphics.lineStyle(1);
			simpleRect.graphics.drawRect(100, 100, 300, 500);
			container.addChild(simpleRect);
			container.addEventListener(MouseEvent.MOUSE_OUT,  containerMouseLeftListener);
			container.addEventListener(MouseEvent.MOUSE_OVER, containerAddListenerCleaner);
			addChild(container);
			simpleRect.graphics.lineStyle(20, 0xFFFFFF);
		}
 
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// entry point
		}
 
		private function containerCleanerListener(e:MouseEvent):void {
			simpleRect.graphics.lineTo(e.target.mouseX, e.target.mouseY);
			simpleRect.graphics.moveTo(e.target.mouseX, e.target.mouseY);
		}
 
		private function containerAddListenerCleaner(e:MouseEvent):void {
			simpleRect.graphics.moveTo(e.target.mouseX, e.target.mouseY);
			e.currentTarget.addEventListener(MouseEvent.MOUSE_MOVE, containerCleanerListener);
		}
 
		private function containerMouseLeftListener(e:MouseEvent):void {
		e.currentTarget.removeEventListener(MouseEvent.MOUSE_MOVE, containerCleanerListener);		
		}
 
	}
 
}

Старый 09.05.2013, 03:51
studentsimf вне форума Посмотреть профиль Отправить личное сообщение для studentsimf Найти все сообщения от studentsimf
  № 3  
Ответить с цитированием
studentsimf

Регистрация: May 2013
Сообщений: 6
Цитата:
Сообщение от Idon'tKnow Посмотреть сообщение
Вот есть идея. Просто перерисовывать линию белую, если нужно стереть. Не подходит такой вариант?
Не, белая линия тоже не подходит т.к. у меня не белый фон а прозрачный.
Надо именно резать векторную линию и удалять фрагмент ее.

Сейчас пробую пробегаться по векторному массиву... и удалять точки которые попадаются под руку)) но такое это кривое решение)))

Код AS1/AS2:
var v:Vector.<IGraphicsData>;
v = conrainerPaint.graphics.readGraphicsData(true);
 
for (var i : int = 0; i < v.length; i++) 
{
        if (String(v[i]) ==  "[object GraphicsPath]")
	{ 
		if (GraphicsPath(v[i]).data.indexOf(int(conrainerPaint.mouseX)) != -1 && GraphicsPath(v[i]).data.indexOf(int(conrainerPaint.mouseY)) != -1)
		{
			 v.splice(i, 1);
			 conrainerPaint.graphics.clear();
			 conrainerPaint.graphics.drawGraphicsData(v); 
			 return;
		}	
	}	
}

Старый 09.05.2013, 11:51
expl вне форума Посмотреть профиль Отправить личное сообщение для expl Найти все сообщения от expl
  № 4  
Ответить с цитированием
expl

блогер
Регистрация: Feb 2006
Сообщений: 1,474
Записей в блоге: 3
Вспомните, как происходит стирание в векторных редакторах - в том же Flash IDE. Там изменяется вектор, по которому проходят стиралкой.
И убрать точки здесь не достаточно - здесь надо искать точки пересечения области стиралки с линиями, дробить линию на куски, удалять куски, попавшие в область стирания.
А если у Вас не просто линии, а ещё и области заливки - задача становится ещё интереснее - придётся использовать хитрые алгоритмы по работе с контурами.

Но такого редактора я на flash не видел. Переходите на растр и не выпендривайтесь
... или рисуйте поверх закрашенные цветом фона контуры.

Старый 09.05.2013, 16:26
studentsimf вне форума Посмотреть профиль Отправить личное сообщение для studentsimf Найти все сообщения от studentsimf
  № 5  
Ответить с цитированием
studentsimf

Регистрация: May 2013
Сообщений: 6
Цитата:
Сообщение от expl Посмотреть сообщение
А если у Вас не просто линии, а ещё и области заливки - задача становится ещё интереснее
Нет ТОЛЬКО линии!

Цитата:
Сообщение от expl Посмотреть сообщение
Но такого редактора я на flash не видел. Переходите на растр и не выпендривайтесь
... или рисуйте поверх закрашенные цветом фона контуры.
Нет растр не подходит, так как итоговая картинка может быть любого размера хоть 50000 пикселей по ширине, пустой файл 5000Х5000 px в растре весит 45Mb, а в векторе ничего не весит, поэтому мне нужен именно вектор.

Кстати во флеше стирание линии происходит, видимо, наложением другого шейпа (белого) поверх линии, и последующего его удаления! Как бы сделать так же!
Проблема в том что я "програмист" с натяжкой, поэтому прошу помощи!


Последний раз редактировалось studentsimf; 09.05.2013 в 17:16.
Старый 09.05.2013, 12:58
mikhailk вне форума Посмотреть профиль Отправить личное сообщение для mikhailk Найти все сообщения от mikhailk
  № 6  
Ответить с цитированием
mikhailk
 
Аватар для mikhailk

Регистрация: Nov 2009
Адрес: СПб
Сообщений: 2,236
Цитата:
Делаю простейший редактор для рисования. В котором можно рисовать только линиями. Возникла проблема в реализации стерки.
Вот сколько я видел редакторов на флеше для сборки чего-либо из векторных примитивов (напр, поздравительных открыток), никогда не видел там стерки. Только удаление примитивов целиком.

Однако.
Есть известный факт - все, что можно сделать во FlashIDE, можно сделать напрямую на AS. Если посмотреть, как реализована стерка во FlashIDE, то мне кажется она сделана так:

1. Векторный объект представляется как растровый
2. Стерка работает с растровым
3. После завершения стирания векторный объект корректируется с учетом того, что осталось от растрового.

Последняя операция хорошо видна, потому что после того, как заканчиваешь стирать, фигуры и линии немного изменяются (результат не идеально соответствует тому, что осталось от растрового объекта).

Старый 09.05.2013, 13:17
expl вне форума Посмотреть профиль Отправить личное сообщение для expl Найти все сообщения от expl
  № 7  
Ответить с цитированием
expl

блогер
Регистрация: Feb 2006
Сообщений: 1,474
Записей в блоге: 3
Если посмотреть, насколько криво работает векторизатор растра в том же флеше, то с трудом в это верится.
Тем более - сложение/вычитание векторных контуров выглядит более оптимальным (и в boost-е реализовано). Оно и в poligonal(as3/haXe) реализовано, но щас эту либу нагуглить не могу.

Цитата:
Последняя операция хорошо видна, потому что после того, как заканчиваешь стирать, фигуры и линии немного изменяются (результат не идеально соответствует тому, что осталось от растрового объекта).
Да просто оптимизатором проходятся - избыток точек убирают, ИМХО.

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

Регистрация: Jun 2011
Сообщений: 60
Можно ж просто режим смешивания ERASE пользовать для стерки

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

блогер
Регистрация: Feb 2006
Сообщений: 1,474
Записей в блоге: 3
Нормальное решение:
1 При проведении стиралкой при каждом смещении мыши запоминаем положение курсора - получаем список точек.
2 При каждом смещении мыши в процессе ведения перерисовываем по этим точкам (зная размеры и форму стиралки) область цветом фона
3 После отпускания мыши строим по этому списку точек (зная размеры и форму стиралки) контур (просто список точек этого контура по/против часовой стрелке скорее всего)
4 Усиленно и люто гуглим алгоритмы обрезания прямых контуром
5 Берём список всех нарисованных прямых и режем каждую этим контуром, удаляя попавшие в контур и добавляя обрезки, не попавшие в контур.
6 перерисовываем все прямые по новым данным.

Примечание:
Ещё можно не искать контур, а сделать N разрезов - сколько было перемещений мыши простым квадратом (если стиралка квадратная). Может даже сразу при перемещении резать. Но это не так гладко будет смотреться. (Чтобы разрезать линию квадратом школьной математики то должно хватить, хотя попотеть придётся, там в условиях главное не запутаться)

Решение попроще:
1, 2 То же, что и в нормальном решении
3 Оставляем этот закрашенный контур как есть, не удаляя его с экрана (или перерисовываем на тот же слой, где линии)

Решение попроще с возможностью менять цвет фона потом:
Похоже на решение попроще, но теперь надо
Цитата:
смешивания ERASE пользовать для стерки
А это значит, что придётся организовать хитрую вложенность спрайтов, чтобы через стёртую область просвечивал фон.

Старый 10.05.2013, 04:15
studentsimf вне форума Посмотреть профиль Отправить личное сообщение для studentsimf Найти все сообщения от studentsimf
  № 10  
Ответить с цитированием
studentsimf

Регистрация: May 2013
Сообщений: 6
Цитата:
Сообщение от expl Посмотреть сообщение
Нормальное решение:
Спасибо, это очевидное решение, мне бы реализацию геденить подсмотреть... самому велосипед нехочется придумывать, да и не осилю скорее всего.

Реально НИКТО в мире не заморачивался стиранием линий? я весь интернет перерыл уже...

Если уж не линии то хотя бы удаление отдельно взятого пути, при наведении на него стеркой, к примеру.
Это как оказалось тоже не простая задача, хиттест не повесиш. Сделал вариант смотрю точки из GraphicsPath.data и если совпадают с мышиной координатой то удаляю весь путь. Но все очень плохо с этим методом(

Монстры кода! Помогите! Мозг кипит уже!

нашел что то отдаленно напоминающее http://wonderfl.net/c/1NKA

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

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

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


 


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


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