|
|
|||||
[+4 06.05.14]
|
диаграмма секторов
Решил сделать такую штучку ради интереса, с математикой не силен, поэтому рассуждал логически.
ВОобщем задача такая - на вход подается кол-во элементов ( секторов ) и их процентная ставка, от чего собственно зависит высота сектора ( это потом, не важно ) , - на выходе получаем диаграмму этих секторов, распределенных по кругу. http://stackoverflow.com/questions/1...-like-this-one По ссылке выше пример того, что хочу получить, только без черной сетки и всегда с дугой. Вот собственно так начал решать эту задачку : 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; } То есть по итогу, сектора должны занимать весь круг...
__________________
Марк Tween |
|
|||||
Нуб нубам
модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
|
1. С каких это пор curveTo стала рисовать дугу окружности?
2. Вы предлагаете нам самим писать тестовый проект, чтобы узнать, в чем именно у Вас "получается лажа"?
__________________
Reality.getBounds(this); |
|
|||||
Регистрация: Jun 2011
Сообщений: 60
|
Формулы - полный бред на вид. Где ты их выкопал?
Вот, например, это: Ширину считают, поделив градусы на количество 0_о |
|
|||||
Нуб нубам
модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
|
Циферки можно менять/удалять/добавлять новые:
drawDiagram.as 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); } } } 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); } } }
__________________
Reality.getBounds(this); |
|
|||||
[+1 25.10.13]
[+4 18.03.14] |
in4core, если у вас много свободного времени могу подкинуть задачку на тему Трансформ менеджеров.
На сцене есть три спрайта, вложенных друг в друга и так же на сцене есть трансформ менеджер. Требуется корректно драгать им каждый из трех спрайтов. |
|
|||||
Регистрация: Jun 2008
Сообщений: 204
|
На что надеялся ТС ? Наверное на то что дадут ссылку на готовове решение....
|
|
|||||
[+4 06.05.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 |
|
|||||
[+1 25.10.13]
[+4 18.03.14] |
А то я про эти библиотеки ничего не знаю...
|
|
|||||
Нуб нубам
модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
|
Что такое "ширина сектора"?
У сектора есть угол (в нашем случае тот же 360 / numSectors). Есть две прямые линии — радиус сектора, и дуга этого радиуса. Дуга это не любая кривая, и уж точно не кривая второго порядка, а часть окружности. Ее не нарисовать за один проход curveTo(). Будет.. кривая Кривая. Для 200-360 секторов это не будет заметно, но два будут выглядеть яйцами. Чтобы кривая была похожа на часть окружности, надо рисовать ее фрагментиками градусов по 15-30 (зависит от длины дуги конечно, но в среднем так). Поэтому угол сектора делится на фрагменты и во внутреннем цикле рисуются эти короткие кривые не более 18 градусов. Нельзя посчитать "высоту дуги" один раз для всех секторов — она у всех разная, потому что радиус дуги разный (из values). Однако поскольку все фрагменты одного сектора имеют один радиус и одинаковый угол дуги, длина луча к контрольным точкам кривых тоже одинаковая и считается один раз для сектора. Я не рисую все сектора "от ноля" с последующим поворотом спрайта. Мне так не нравится. Я рисую сектор там где он должен быть, поэтому первая точка дуги тоже ищется тригонометрически (можно через Point.polar()). Для меня фраза "понятно, что любую задачу можно решить разными способами" приемлема только в том контексте, в котором задача действительно решается. Рисование окружности одним проходом curveTo извините, не решается никак. Какую бы "высоту дуги" Вы не посчитали. Можно еще треугольные маски накладывать на красивые окружности от drawCircle(). Маску можно без дуги рисовать, обычный прямоугольный треугольник — посчитать проще, тем более если от нулевой оси.
__________________
Reality.getBounds(this); |
|
|||||
[+4 06.05.14]
|
Цитата:
__________________
Марк Tween |
Часовой пояс GMT +4, время: 09:18. |
|
« Предыдущая тема | Следующая тема » |
Опции темы | |
Опции просмотра | |
|
|