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

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

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

Регистрация: Jul 2007
Адрес: Россия, Москва
Сообщений: 522
Question Разрывы в рисование с помощью Bitmap

Здравствуйте.

Передо мной была поставлена задача сделать «рисовалку» на AS3. По нескольким причинам я решил делать программное рисование не через graphic.lineTo, а через BtimapData и draw. Основными причинами к этому были:

1) Нестандартные «кисти» с размытыми краями.
2) Возможность «стирать» нарисованное.

За саму часть рисования у меня отвечает следующий код:
Код AS3:
function onMouseMove(event:MouseEvent) {
	if (this.instrument_mc) {
		this.instrument_mc.x = Main.stage.mouseX;
		this.instrument_mc.y = Main.stage.mouseY;
		//
		if (event.buttonDown) {
			this.toDraw();
		}
	}
}
function onMouseDown(event:MouseEvent) {
	this.toDraw();
}
Блок:
Код AS3:
if (this.instrument_mc) {
Проверяет наличие инструмента для рисования «в руке».

А блок с:
Код AS3:
if (event.buttonDown) {
Проверяет нажата ли кнопка мышки. Если все условия выполняются, то запускается функция toDraw(), в которой и реализован механизм рисования. Механизм примерно такой:

Код AS3:
this.matrix.tx = toX;
this.matrix.ty = toY;
this.bitmap.draw(_mc, this.matrix, this.colorTransform, instrumentBlendMode);
_mc — это клип, которым рисуем, то есть, те самые «кисточки».
instrumentBlendMode — бывает BlendMode.NORMAL и BlendMode.ERASE, что позволяет либо рисовать, либо стирать нарисованное.

Но это всё было отступлением, проблема заключается в том, что если быстро вести мышкой при зажатой кнопке, то линия получается обрывистой, что видно на следующем скриншоте:



На картинке, быстрее всего была проведена верхняя линия, две линии ниже идут по уменьшению скорости.

Вот и вопрос, есть ли способ с этим как-то бороться, или же стоит смотреть в сторону graphic.lineTo и можно ли там (graphioc.lineTo) как-то добиться размытости кистей?

Как всё работает «в живую» можно посмотреть тут (65кб, прелодера нет): http://flashist.ru/files/azat/school/index.html

P.S.:
updateAfterEvent() пробовал, не помогло. Может быть я как-то не так пробовал?
Так же пробовал, при нажатии на кнопку мыши, запускать таймер который бы вызывался 200 раз в секунду и рисовал Btimap, а при отпускании кнопки мышки таймер бы приостанавливался. Тоже не помогло. Может быть опять как-то не так пробовал?

UPD.:
Изменять количество FPS до максимальных 120 тоже пробовал, тоже не помогло =(


Последний раз редактировалось koIIImarik; 16.03.2009 в 02:38.
Старый 16.03.2009, 00:05
serenkiy вне форума Посмотреть профиль Отправить личное сообщение для serenkiy Найти все сообщения от serenkiy
  № 2  
Ответить с цитированием
serenkiy
 
Аватар для serenkiy

Регистрация: Jan 2009
Сообщений: 60
Отправить сообщение для serenkiy с помощью ICQ
Тут все просто - MOUSE_MOVE срабатывает аналогично ENTER_FRAME - тобишь каждый кадр. Из-за этого отрисовка потворяется <кол-во кадров в секунду> раз в секунду и наблюдаются разрывы. В Вашем случае необходимо будет воспользоваться идеологией метода lineTo/moveTo - Т.е. вам придется написать функцию подобно lineTo, только с Вашими потребностями (метод Draw(), размытые кисти и т.п.).


Последний раз редактировалось serenkiy; 16.03.2009 в 00:13.
Старый 16.03.2009, 00:16
koIIImarik вне форума Посмотреть профиль Отправить личное сообщение для koIIImarik Посетить домашнюю страницу koIIImarik Найти все сообщения от koIIImarik
  № 3  
Ответить с цитированием
koIIImarik
 
Аватар для koIIImarik

Регистрация: Jul 2007
Адрес: Россия, Москва
Сообщений: 522
Сейчас обновил пост, написал о том, что пробовал увеличивать до максимального количество FPS, но это тоже не помогло.

Цитата:
придется написать функцию подобно lineTo, только с Вашими потребностями (метод Draw(), размытые кисти и т.п.).
Можете натолкнуть/подсказать логику такой функции? «Запоминание» при каждом onMouseMove положения мышки и потом через цикл «заполнять» промежуток, разбив «точки» на равные отрезки? (не уверен, что все поймут, что я имел тут ввиду)

Просто я тоже думал о таком принципе, но мне кажется, что должно быть более изящное решение проблемы.

Старый 16.03.2009, 00:22
serenkiy вне форума Посмотреть профиль Отправить личное сообщение для serenkiy Найти все сообщения от serenkiy
  № 4  
Ответить с цитированием
serenkiy
 
Аватар для serenkiy

Регистрация: Jan 2009
Сообщений: 60
Отправить сообщение для serenkiy с помощью ICQ
Я Вас прекрасно понял, Вы совершенно правы: кликаем на холст - запоминаем точку - двигаем мышь - рисуем линию от запомненной точки до текущего положения мыши. Отрисовку "от точки до точки" делать с помощью цикла. Это один из вариантов решения проблемы. Тут так же можно использовать кривые безье для сглаживания линий, но это чуть сложнее.
Второе что пришло мне в голову - рисовать изначально через lineTo/moveTo с примененным фильтром blur (или glow), а при MOUSE_UP отрисовывать через draw() на холсте.

Старый 16.03.2009, 00:57
koIIImarik вне форума Посмотреть профиль Отправить личное сообщение для koIIImarik Посетить домашнюю страницу koIIImarik Найти все сообщения от koIIImarik
  № 5  
Ответить с цитированием
koIIImarik
 
Аватар для koIIImarik

Регистрация: Jul 2007
Адрес: Россия, Москва
Сообщений: 522
Спасибо за советы, но это всё как-то через «жопу», хотелось бы более изящного и простого решения (что-то типо lineTo для Bitmap).

Посмотрим, может кто-то из других форумчан подскажет такое более «изящное» решение.

Старый 16.03.2009, 02:31
serenkiy вне форума Посмотреть профиль Отправить личное сообщение для serenkiy Найти все сообщения от serenkiy
  № 6  
Ответить с цитированием
serenkiy
 
Аватар для serenkiy

Регистрация: Jan 2009
Сообщений: 60
Отправить сообщение для serenkiy с помощью ICQ
Ну насчет более изящного решения - вместо отрисовки в событии MOUSE_MOVE, создаем таймер и рисуем в событии TimerEvent.TIMER. Тем самым мы можем указать интервал таймера вплоть до миллисекунды, что сократит разрывы.

Старый 16.03.2009, 02:35
koIIImarik вне форума Посмотреть профиль Отправить личное сообщение для koIIImarik Посетить домашнюю страницу koIIImarik Найти все сообщения от koIIImarik
  № 7  
Ответить с цитированием
koIIImarik
 
Аватар для koIIImarik

Регистрация: Jul 2007
Адрес: Россия, Москва
Сообщений: 522
Я пробовал и этот вариант, к сожалению, он тоже не дал желаемых результатов =(

Скорее всего, остановлюсь на циклах «дорисовки», просто хотелось бы узнать мнения у чуть большего количества людей, все ли считают, что больше подходящих решений нет.

Спасибо вам ещё раз, за то, что пытаетесь мне помочь советом =)

Старый 16.03.2009, 04:32
iflamberg вне форума Посмотреть профиль Отправить личное сообщение для iflamberg Найти все сообщения от iflamberg
  № 8  
Ответить с цитированием
iflamberg
 
Аватар для iflamberg

Регистрация: Jan 2009
Сообщений: 1,651
это не через жопу, это именно правильный вариант. Если бы у вас был планшет, то вы бы знали, что если быстро вести кривую линию на планшете, то она получается ломанной, а не гладкой именно по причине работы того самого алгоритма. Если хотите заморочиться, то можете запрограммировать, чтобы алгоритм сглаживал быструю линию пользуясь информациях о предыдущих поставленных точках.
Да, кстати, не забывает event.updateAfterEvent() в слушателе.

Старый 16.03.2009, 08:59
Arif flasher вне форума Посмотреть профиль Отправить личное сообщение для Arif flasher Посетить домашнюю страницу Arif flasher Найти все сообщения от Arif flasher
  № 9  
Ответить с цитированием
Arif flasher
[+4 14.03.09]
 
Аватар для Arif flasher

Регистрация: Mar 2009
Адрес: Баку, город ветров
Сообщений: 51
Отправить сообщение для Arif flasher с помощью ICQ Отправить сообщение для Arif flasher с помощью MSN Отправить сообщение для Arif flasher с помощью Skype™
при быстром движении курсор мышки начинает "прыгать" поэтому он пропускает промежутки. Проверить это можно так: нарисуйте круг (рад: 30 пикс), его в символ и эвент слушатель на Маус_Овер и соответственно Трейс("что-то") чтобы узнать был ли маус_овер, и быстро проведите мышкой над обьектом, вы увидете что иногда даже если мышка проходит над обьектом Трейс не работает.
Поэтому я тоже считаю lineTo это правильный вариант.

Старый 16.03.2009, 12:02
flash33 вне форума Посмотреть профиль Отправить личное сообщение для flash33 Найти все сообщения от flash33
  № 10  
Ответить с цитированием
flash33
 
Аватар для flash33

Регистрация: Nov 2005
Сообщений: 1,155
Все серьезные графические программы используют интерполяцию промежуточных точек при движении курсора. Имейте так же в виду что операция draw очень дорогая, поэтому одно ее выполнение притормаживат всю систему, а значит и отслеживание системой позиции курсора, таким образом линия движения мыши получается ломаной в любом случае. Сделайте простой эксперимент
Код AS3:
function onMouseMove(event){
  trace(this.mouseX, this.mouseY)
}
Как видите, соседние координаты даже при безобидном умеренном движении мыши расположены далеко друг от друга, это без прорисовки.
Выход для вас либо использовать lineTo на клипе с фильтром блюр (самый простой выход для размытия линий, самый примитивный) - либо использовать быстрые операции с растром copyPixels, либо более медленные draw c интерполяцией промежуточных точек - ищите литературу как это делать, на этом форуме я когда то уже обсуждал эту тему. Говорю это как человек, съевший на рисовалках собаку, кошку, корову и лошадь со сбруей.

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

Теги
bitmap , рисование

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

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


 


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


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