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

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

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

Регистрация: Mar 2015
Сообщений: 23
Question Вращение рукоятки (количество оборотов)

Доброго времени суток!
Стала задача сделать многооборотную рукоятку, которую можно вращать мышкой (вокруг своей оси).
Саму по себе рукоятку сделал, вращается, но чтот никак не могу понять, как считать обороты, наткнулся на такой подводный камень:
- во время вращения, угол вращения (в моем случае это значение Т4) перескакивает хаотично, бывают повторы одного и того же угла - в зависимости от того, на сколько плавно вести мышкой. Следовательно невозможно отследить точный угол (значение Т4), при котором программа поймет, что произошел полный оборот. Например, я указал, что если значение == 100, то оборот ++, но можно так вращать, что значение 100 проскочит, да еще и если повращать по-диджейски, т.е. туда-сюда с небольшим углом, то счетчик поворотов будет считать лишь переходы с 99 на 100 и с 0 на 100, что не катит
Подскажите, как организовать что бы при вращении вне зависимости от скорости и плавности моя переменная T4 принимала все целые значения угла полного оборота.
архив с флешкой и исходником encoder.rar

Код AS3:
stop();
 
encoder.addEventListener(MouseEvent.MOUSE_DOWN, down_mouse); //слушаем нажатие мышкой на рукоятку
encoder.addEventListener(MouseEvent.MOUSE_UP, up_mouse); //слушаем отпускание мышки над рукояткой
encoder.addEventListener(MouseEvent.MOUSE_OUT, out_mouse); //слушаем уведения мышки с рукоятки
 
var angle: Number;
var start_angle: Number;
var oborot: Number = -1;
 
oborot_scr.text = "0";
 
function down_mouse(event: MouseEvent) {
	encoder.addEventListener(MouseEvent.MOUSE_MOVE, moveHandler);
	var ex: Number = mouseX - encoder.x;
	var ey: Number = mouseY - encoder.y;
	start_angle = Math.atan2(ey, ex) * 180 / Math.PI;
}
 
function up_mouse(event: MouseEvent) {
	encoder.removeEventListener(MouseEvent.MOUSE_MOVE, moveHandler);
}
 
function out_mouse(event: MouseEvent) {
	encoder.removeEventListener(MouseEvent.MOUSE_MOVE, moveHandler);
}
 
function moveHandler(event: MouseEvent) {
 
	var dx: Number = mouseX - encoder.x;
	var dy: Number = mouseY - encoder.y;
 
	angle = (Math.atan2(dy, dx)) * 180 / Math.PI;
	encoder.rotation += (angle - start_angle);
 
	var T2: Number = encoder.rotation;
	var T3: Number = Math.floor(T2);
 
	//обратный ход
	if (T3 <= 0) {
		T3 = 180 + (180 + T3);
	}
 
	//делитель числа полного оборота
	var T4: Number = Math.floor(100 * (T3 / 360));
 
	// проход круга
	if (T4 == 0) {
		oborot++;
		oborot_scr.text = "" + oborot;
	}
	deg_scr.text = "" + T4;
 
	// коррекция угла для следующего хвата, что бы не прыгало
	start_angle = angle;
}

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

блогер
Регистрация: Jul 2013
Адрес: Север
Сообщений: 1,922
Записей в блоге: 23
Отправить сообщение для ZackMercury с помощью ICQ Отправить сообщение для ZackMercury с помощью Skype™
Просто в счётчик поворотов пишите градусы/радианы, прибавляйте дельту каждый кадр.
А потом если надо /=360 или /=Math.PI*2 и будет количество оборотов и даже в какую сторону.
__________________
There is no thing in this world that is not simple.

Старый 10.03.2015, 11:16
zslavman вне форума Посмотреть профиль Отправить личное сообщение для zslavman Найти все сообщения от zslavman
  № 3  
Ответить с цитированием
zslavman

Регистрация: Mar 2015
Сообщений: 23
Цитата:
Сообщение от ZackMercury Посмотреть сообщение
Просто в счётчик поворотов пишите градусы/радианы, прибавляйте дельту каждый кадр.
А потом если надо /=360 или /=Math.PI*2 и будет количество оборотов и даже в какую сторону.
а не важно что считает счетчик, градусы/радианы или нормированное значение, проскоки всё равно есть, причем, чем больше размерность оборота, тем больше проскоков. Не знаю каким образом прибавлять дельту каждый кадр, если основополагающее значение прыгает... а вот по поводу кадров, попробую повысить частоту кадров, возможно в этом и дело

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

блогер
Регистрация: Jul 2013
Адрес: Север
Сообщений: 1,922
Записей в блоге: 23
Отправить сообщение для ZackMercury с помощью ICQ Отправить сообщение для ZackMercury с помощью Skype™
Дельта = разница между предыдущим положением и текущим.
Фактически, это так: delta = current - previous.
Вам нужно хранить предыдущее значение, и отнимать от него текущее(всё это в радианах или градусах - неважно).
И эту дельту прибавлять к счётчику.

P.S. Никоим боком этот рассчёт не должен касаться rotation свойства(засранец переводит градус в систему вращения флеша, т.е. -180 - 0 - 180)
__________________
There is no thing in this world that is not simple.


Последний раз редактировалось ZackMercury; 10.03.2015 в 11:42.
Старый 10.03.2015, 12:09
undefined вне форума Посмотреть профиль Отправить личное сообщение для undefined Найти все сообщения от undefined
  № 5  
Ответить с цитированием
undefined

Регистрация: Oct 2006
Сообщений: 2,283
а я бы как раз и на rotation смотрел, как только он прыгнул в 0/180/-180 - значит есть оборот

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

блогер
Регистрация: Jul 2013
Адрес: Север
Сообщений: 1,922
Записей в блоге: 23
Отправить сообщение для ZackMercury с помощью ICQ Отправить сообщение для ZackMercury с помощью Skype™
undefined, нит. Если можно тащить (вращать) мышей - то можно несколько раз протащить, туда-обратно. А с учётом дельты будет накручиваться ровно столько, сколько протащили, протащили туда - +20 градусов, протащили обратно - -20.

Добавлено через 1 минуту
Вот только стык 360 и 0 нужно предусмотреть.
__________________
There is no thing in this world that is not simple.

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

Регистрация: Oct 2006
Сообщений: 2,283
угу, каюсь, не подумал

Старый 10.03.2015, 19:31
zslavman вне форума Посмотреть профиль Отправить личное сообщение для zslavman Найти все сообщения от zslavman
  № 8  
Ответить с цитированием
zslavman

Регистрация: Mar 2015
Сообщений: 23
угу, ребятки, всё верно, система вращения во флеше построена от 0 до +/-180, немного хреновенько
пробовал повысить FPS - появляются повторение, т.е. current = previous, (что наблюдалось и раньше, но реже, по сей причине не получиться вычитать, как предлагал ZackMercury ). Теперь заданную точку полного оборота не проскакивает, а наоборот по несколько раз ее дублирует при прохождении - тоже получается лажа
вопрос остается открытым...

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

блогер
Регистрация: Mar 2008
Адрес: Днепропетровск
Сообщений: 1,783
Записей в блоге: 3
Вдруг поможет

Rotatevolume.swf   (33.2 Кб)


Код AS3:
package
{
	import flash.display.Bitmap;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
 
	/**
	 * ...
	 * @author samana
	 */
	public class Regulator extends Sprite
	{
 
		[Embed(source="../images/image2.jpg")]
		private var ImageClass:Class;
 
		private var _bm:Bitmap;
		private var _rotationValue:Number = 0;
 
		public function Regulator()
		{
			_bm = new ImageClass();
			_bm.x -= _bm.width / 2;
			_bm.y -= _bm.height / 2;
			_bm.smoothing = true;
 
			addChild(_bm);
 
			addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
 
		}
 
		private function mouseDown(e:MouseEvent):void
		{
			stage.addEventListener(MouseEvent.MOUSE_MOVE, stage_mouseMove);
			stage.addEventListener(MouseEvent.MOUSE_UP, stage_middleMouseUp);
		}
 
		private function stage_middleMouseUp(e:MouseEvent):void
		{
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, stage_mouseMove);
			stage.removeEventListener(MouseEvent.MOUSE_UP, stage_middleMouseUp);
		}
 
		private function stage_mouseMove(e:MouseEvent):void
		{
			var oldAng:Number = rotation;
 
			var dx:Number = e.stageX - x;
			var dy:Number = e.stageY - y;
			rotation = Math.atan2(dy, dx) * 180 / Math.PI;
 
			_rotationValue += diffAngles(oldAng, rotation, false);
		}
 
		/**
		 * Вернуть разницу между углами в радианах или грудусах. Приоритет в меньшую сторону круга.
		 * Сколько нужно добавить или отнять у угла ang1 чтобы он стал равен ang2
		 * @param	ang1 первый угол
		 * @param	ang2 второй угол
		 * @param 	inRadian переданные углы и возвращаемое значение в радианах, иначе в градусах
		 * @return	возвращает разницу
		 */
		private function diffAngles(ang1:Number, ang2:Number, inRadian:Boolean = true):Number
		{
			var diff:Number;
 
			if (inRadian)
			{
				//convert to  0 - Math.PI*2
				// 3.141592653589793 = Math.PI;
				// 6.283185307179586 = Math.PI*2;
				if (ang1 < 0)
					ang1 = 6.283185307179586 - (ang1 * -1); //to abs
				if (ang2 < 0)
					ang2 = 6.283185307179586 - (ang2 * -1); //to abs
 
				diff = ang2 - ang1;
 
				if (diff > 3.141592653589793)
					diff -= 6.283185307179586;
				else if (diff < -3.141592653589793)
					diff += 6.283185307179586;
			}
			else
			{
				//convert to  0-360
				if (ang1 < 0)
					ang1 = 360 - (ang1 * -1); //to abs
				if (ang2 < 0)
					ang2 = 360 - (ang2 * -1); //to abs
 
				diff = ang2 - ang1;
 
				if (diff > 180)
					diff -= 360;
				if (diff < -180)
					diff += 360;
			}
 
			return diff;
		}
 
 
		public function get rotationValue():int 
		{
			return _rotationValue;
		}
 
 
 
	}
 
}
Вложения
Тип файла: swf Rotatevolume.swf (33.2 Кб, 164 просмотров)

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

Регистрация: Mar 2015
Сообщений: 23
samana, благодарю, использую вашу идею в свой код

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

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

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


 


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


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