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

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

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

Регистрация: Mar 2009
Сообщений: 4,219
Записей в блоге: 14
По умолчанию диаграмма секторов

Решил сделать такую штучку ради интереса, с математикой не силен, поэтому рассуждал логически.
ВОобщем задача такая - на вход подается кол-во элементов ( секторов ) и их процентная ставка, от чего собственно зависит высота сектора ( это потом, не важно ) , - на выходе получаем диаграмму этих секторов, распределенных по кругу.
http://stackoverflow.com/questions/1...-like-this-one
По ссылке выше пример того, что хочу получить, только без черной сетки и всегда с дугой.
Вот собственно так начал решать эту задачку :

Код AS3:
public function drawDiagram(sectors:int , radius:Number , values:Array, triangulate:Boolean = false):void
		{
			var diameter:Number = radius * 2;
			var sectorMaxWidth:Number = 360 / sectors;
			var angleRotation:Number = 360 / sectors;
			var currentAngle:Number = angleRotation;
			var arcHeight:Number = radius - Math.sqrt(Math.abs(((Math.pow(radius,2) - Math.pow(sectorMaxWidth / 2, 2)))));
 
			var circle:Shape = new Shape();
			circle.graphics.beginFill(0);
			circle.graphics.drawCircle(0, 0, radius);
			addChild(circle)
 
			for (var i:int = 0; i < sectors; i++)
			{
				var firstSector:Shape = new Shape();
				firstSector.graphics.beginFill(randomColor);
				firstSector.graphics.lineStyle(1,0xFFFFFF)
				firstSector.graphics.lineTo( -sectorMaxWidth  , -radius + arcHeight);
				firstSector.graphics.curveTo( 0, -radius - arcHeight, sectorMaxWidth, -radius + arcHeight);
				firstSector.graphics.lineTo(0, 0);
 
				firstSector.rotation = currentAngle;
				addChild(firstSector);
 
				currentAngle += angleRotation;
 
			}
 
		}
 
		private function get randomColor():int
		{
			return Math.random()*0xFFFFFF;
		}
Собственно получается лажа, не могу понять именно в чем косяк, arcHeight ( взял формулу с нета ). Остальное собственно своими невеликими силами.
То есть по итогу, сектора должны занимать весь круг...
__________________
Марк Tween

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

модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
1. С каких это пор curveTo стала рисовать дугу окружности?
2. Вы предлагаете нам самим писать тестовый проект, чтобы узнать, в чем именно у Вас "получается лажа"?
__________________
Reality.getBounds(this);

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

Регистрация: Jun 2011
Сообщений: 60
Формулы - полный бред на вид. Где ты их выкопал?
Вот, например, это:
Код AS3:
var sectorMaxWidth:Number = 360 / sectors;
Ширину считают, поделив градусы на количество 0_о

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

модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
Циферки можно менять/удалять/добавлять новые:
SectorDiagram.swf   (2.2 Кб)

drawDiagram.as
Код AS3:
package  
{
	import flash.display.DisplayObjectContainer;
	import flash.display.Graphics;
	import flash.display.Sprite;
	/**
	 * ...
	 * @author wolsh
	 */
	public function drawDiagram (container:DisplayObjectContainer, radius:Number, values:Array):void
	{
		var k:Number = radius / Math.max.apply(null, values);
		var sectors:uint = values.length;
		var sectorAngle:Number = 2 * Math.PI / sectors;
 
		for (var i:uint = 0; i < sectors; i++)
		{
			var color:uint = 0x808080 + Math.random() * 0x404040;
			var startAngle:Number = i * sectorAngle;
			var sectorRadius:Number = values[i] * k;
			var sector:Sprite = new Sprite();
			container.addChild(sector);
 
			// calculate fragments (18 gradians max at one step for cute round curve)
			var frags:Number = Math.abs( Math.ceil(sectorAngle * 10 / Math.PI) ); 
			if (sectorAngle < 0) frags += 1;
			var fragAngle:Number = sectorAngle / frags;
			// control points radius
			var controlOutRadius:Number = sectorRadius / Math.cos( -fragAngle / 2);
			// start drawings
			var g:Graphics = sector.graphics;
			g.lineStyle(1, 0xFFFFFF)
			g.beginFill(color);
			g.moveTo(0, 0);
			var startX:Number = sectorRadius * Math.cos(startAngle);
			var startY:Number = sectorRadius * Math.sin(startAngle);
			g.lineTo(startX, startY);
			// arc
			for (var j:uint = 1; j < frags + 1; j++) 
			{
				var aA:Number = startAngle + fragAngle * j;
				var aX:Number = sectorRadius * Math.cos(aA);
				var aY:Number = sectorRadius * Math.sin(aA);
				var cA:Number = aA - fragAngle / 2;
				var cX:Number = controlOutRadius * Math.cos(cA);
				var cY:Number = controlOutRadius * Math.sin(cA);
				g.curveTo(cX, cY, aX, aY);
			}
			g.lineTo(0, 0);
		}
	}
}
Main.as
Код AS3:
package 
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.text.TextField;
	import flash.text.TextFormat;
 
	/**
	 * ...
	 * @author wolsh
	 */
	public class Main extends Sprite 
	{
		private var _txt:TextField;
		private var _diagram:Sprite;
 
		public function Main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
 
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// entry point
			_diagram = new Sprite();
			addChild(_diagram);
			_diagram.x = _diagram.y = 220;
			var data:Array = [300, 250, 320, 115, 234, 52, 186, 256, 370];
			drawDiagram(_diagram, 200, data);
			_txt = new TextField();
			_txt.defaultTextFormat = new TextFormat("Arial", 18, 0x808080);
			_txt.wordWrap = true;
			_txt.type = "input";
			_txt.background = true;
			_txt.backgroundColor = 0x505050;
			addChild(_txt);
			_txt.x = 440;
			_txt.y = 180;
			_txt.width = 310;
			_txt.height = 100;
			_txt.text = data.toString();
			_txt.addEventListener(Event.CHANGE, handlerChange);
		}
 
		private function handlerChange(event:Event):void 
		{
			var data:Array = _txt.text.split(',');
			_diagram.removeChildren();
			drawDiagram(_diagram, 200, data);
		}
 
	}
 
}
Вложения
Тип файла: swf SectorDiagram.swf (2.2 Кб, 165 просмотров)
__________________
Reality.getBounds(this);

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

Регистрация: Jan 2006
Адрес: Москва, Зеленоград
Сообщений: 653
Отправить сообщение для Babylon с помощью ICQ
in4core, если у вас много свободного времени могу подкинуть задачку на тему Трансформ менеджеров.
На сцене есть три спрайта, вложенных друг в друга и так же на сцене есть трансформ менеджер. Требуется корректно драгать им каждый из трех спрайтов.

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

Регистрация: Jun 2008
Сообщений: 204
На что надеялся ТС ? Наверное на то что дадут ссылку на готовове решение....

Старый 21.04.2013, 15:54
in4core вне форума Посмотреть профиль Отправить личное сообщение для in4core Найти все сообщения от in4core
  № 7  
Ответить с цитированием
in4core
 
Аватар для in4core

Регистрация: Mar 2009
Сообщений: 4,219
Записей в блоге: 14
Wolsh - круто, спасибо, все таки заинтересовала тебя задача. Но тебе видишь все понятно и просто, а я почитав код половину не понимаю. Если тебе не лень давай порассуждаем : какие реально данные нам нужны?
1. Ширина сектора ( расстояние между 2мя конечными точками )
2. Высота дуги сектора.
3. Угол поворота

Что имеем изначально : только радиус и кол-во секторов. Будем рассуждать в контексте , что все значения 1,1,1,1,1 , то есть получим круг.
И так если у нас есть радиус и кол-во, угол поворота каждого сектора 360 / numSectors . Думаю тут ошибок нет.
Ширина сектора ? - вот тут нам нужна формула , какая ?
http://www.mathopenref.com/arclength.html - вот что я вижу. Где C = 360 / numSectors. Но как я понимаю, здесь нужно переводить в другую систему измерения или нет?
Далее высота дуги http://www.mathopenref.com/arcradius.html так же формула, и видимо так же перевод в другую систему.
Что получается в итоге - 1 цикл, все данные инициализируются 1 раз до цикла. Я так вижу решение этой задачи, у тебя же получается в 10 раз больше данных , формул и т.п. Вообщем понятно, что любую задачу можно решить разными способами, мне хочется именно моим попробовать, вопрос лишь в том, что я не понимаю, и где не так рассуждаю, прошу пояснить, если не сложно!

Добавлено через 2 минуты
Babylon
Твоя задача давно решена, есть готовая библиотека TransformTool найдешь в нете, другой вопрос , что она очень косячная , и мне было оч тяжело переписывать ее под себя в одном из проектов, ну ниче справился
__________________
Марк Tween

Старый 21.04.2013, 16:36
Babylon вне форума Посмотреть профиль Отправить личное сообщение для Babylon Посетить домашнюю страницу Babylon Найти все сообщения от Babylon
  № 8  
Ответить с цитированием
Babylon
 
Аватар для Babylon

Регистрация: Jan 2006
Адрес: Москва, Зеленоград
Сообщений: 653
Отправить сообщение для Babylon с помощью ICQ
А то я про эти библиотеки ничего не знаю...

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

модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
Что такое "ширина сектора"?
У сектора есть угол (в нашем случае тот же 360 / numSectors).
Есть две прямые линии — радиус сектора, и дуга этого радиуса.
Дуга это не любая кривая, и уж точно не кривая второго порядка, а часть окружности. Ее не нарисовать за один проход curveTo(). Будет.. кривая Кривая. Для 200-360 секторов это не будет заметно, но два будут выглядеть яйцами. Чтобы кривая была похожа на часть окружности, надо рисовать ее фрагментиками градусов по 15-30 (зависит от длины дуги конечно, но в среднем так). Поэтому угол сектора делится на фрагменты и во внутреннем цикле рисуются эти короткие кривые не более 18 градусов.
Нельзя посчитать "высоту дуги" один раз для всех секторов — она у всех разная, потому что радиус дуги разный (из values). Однако поскольку все фрагменты одного сектора имеют один радиус и одинаковый угол дуги, длина луча к контрольным точкам кривых тоже одинаковая и считается один раз для сектора.
Я не рисую все сектора "от ноля" с последующим поворотом спрайта. Мне так не нравится. Я рисую сектор там где он должен быть, поэтому первая точка дуги тоже ищется тригонометрически (можно через Point.polar()).
Для меня фраза "понятно, что любую задачу можно решить разными способами" приемлема только в том контексте, в котором задача действительно решается. Рисование окружности одним проходом curveTo извините, не решается никак. Какую бы "высоту дуги" Вы не посчитали.

Можно еще треугольные маски накладывать на красивые окружности от drawCircle(). Маску можно без дуги рисовать, обычный прямоугольный треугольник — посчитать проще, тем более если от нулевой оси.
__________________
Reality.getBounds(this);

Старый 22.04.2013, 13:49
iNils вне форума Посмотреть профиль Отправить личное сообщение для iNils Посетить домашнюю страницу iNils Найти все сообщения от iNils
  № 10  
Ответить с цитированием
iNils
Негуру
 
Аватар для iNils

администратор
Регистрация: Jan 2000
Адрес: Кёнигсберг in Moscow
Сообщений: 21,879
Записей в блоге: 7
Цитата:
Сообщение от Wolsh Посмотреть сообщение
Для 200-360 секторов это не будет заметно, но два будут выглядеть яйцами. Чтобы кривая была похожа на часть окружности, надо рисовать ее фрагментиками градусов по 15-30 (зависит от длины дуги конечно, но в среднем так). Поэтому угол сектора делится на фрагменты и во внутреннем цикле рисуются эти короткие кривые не более 18 градусов.
В 11 плеере есть cubicCurveTo (), им можно сразу 90 градусов рисовать.
__________________
(и)Нильс.ru | Плагины для FlashDevelop

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

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

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


 


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


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