Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Алгоритм рисования пунктирной линии (http://www.flasher.ru/forum/showthread.php?t=207999)

PrincessRoma 26.05.2014 22:19

Алгоритм рисования пунктирной линии
 
Требуется алгоритм рисования пунктирной линии ( горизонтальной или вертикальной, диагональная без надобности ). Сам накидывал что-то простенькое, но достаточно странный результат получал - линия рисуется не до конца, причем чем она длиннее, тем больше недорисованная часть. Код приведен ниже. Ваши мысли, подсказки ?)
Код AS3:

 
function dashedLine(X1,Y1,X2,Y2:Number)
                {
                        var prevX,prevY: Number;
                        var dash: Number = 20;
                        var gap: Number = 10;
                        var distance: Number = (Math.sqrt(Math.pow((X2-X1),2)+Math.pow((Y2-Y1),2)));
                        var steps: Number = Math.round(distance/(dash+gap));
                        var i:int;
 
                        trace('Distance: '+distance);
                        trace('Steps: '+steps);
                        trace('Estimated length: '+steps*30);
 
                        for (i=0;i<steps;i++)
                        {
                                prevX=i*dash;
                                prevY=0;
                                trace('Prev X = '+prevX);
                                trace('Prev Y = '+prevY);
                                this.graphics.lineTo(prevX,prevY);
                                this.graphics.moveTo(prevX+gap,prevY);
                        }
 
                }


LifeIsRhythm 27.05.2014 00:42

Можно немного покороче -
Код AS3:

public static function drawDottedLine(graphics:Graphics, start:Point, finish:Point, doteLineSize:Number = 5, gap:Number = 5):Graphics
{
        var vector:Point = new Point(finish.x - start.x, finish.y - start.y);
        var length:Number = Math.sqrt(vector.x * vector.x + vector.y * vector.y);
        var unitVector:Point = new Point(vector.x / length,  vector.y / length);
 
        var fullStep:Number = doteLineSize + gap;
 
        var iterations:int = length / fullStep;
 
        var roulette:Number = 0
 
        for (var i:int = 0; i < iterations; i++)
        {
                graphics.moveTo(start.x + roulette * unitVector.x, start.y + roulette * unitVector.y);
                roulette += doteLineSize;
                graphics.lineTo(start.x + unitVector.x * roulette, start.y + unitVector.y * roulette);
                roulette += gap;
        }
 
        return graphics;
}


ChuwY 27.05.2014 11:40

Вот и предложили вариант посимпатичнее.
Разве что, для вычисления длины вектора я бы использовал Point:length.

ZackMercury 27.05.2014 12:43

А оптимальней было бы вообще не создавать экземпляр Point'а, а сделать все вычисления без него.

LifeIsRhythm 27.05.2014 13:03

Цитата:

Разве что, для вычисления длины вектора я бы использовал Point:length.
А можно поинтересоваться, почему?

ChuwY 27.05.2014 13:39

Потому что у нас уже есть vector.
К чему плодить лишний код.

caseyryan 27.05.2014 13:43

Можно через битмапу пунктирную линию организовать
Код AS3:

package  {
 
        import flash.display.BitmapData;
        import flash.display.Sprite;
 
        public class TestClass extends Sprite {
 
                private var _gap:int = 3;
                private var _lineWidth:int = 1;
 
                public function TestClass() {
                        drawLine();
                }
 
                private function drawLine():void {
                        var white:BitmapData = new BitmapData(_gap * 2, _lineWidth, false, 0xFFFFFF);
                        var black:BitmapData = new BitmapData(_gap, _lineWidth, false, 0x000000);
                        white.draw(black);
                        black.dispose();
                        graphics.lineStyle(_lineWidth);
                        graphics.lineBitmapStyle(white, null, true, true);
                        graphics.moveTo(100, 100);
                        graphics.lineTo(450, 300);
                        graphics.lineTo(600, 300);
                }
        }
}


LifeIsRhythm 27.05.2014 13:58

Цитата:

Потому что у нас уже есть vector.
К чему плодить лишний код.
Вы наверное об этом? Да, так на строчку короче! Но эта разница достойна того, кто вообще не пользуется фраймворками, которые содержат чересчур много излишеств :) А ещё и нативный метод на 40% медленнее, а Point я использовал только для того, чтобы ТС было понятней.
Код AS3:

public static function drawDottedLine(graphics:Graphics, start:Point, finish:Point, doteLineSize:Number = 5, gap:Number = 5):Graphics
{
        var vector:Point = new Point(finish.x - start.x, finish.y - start.y);
        var unitVector:Point = new Point(vector.x / length,  vector.y / length);
 
        var fullStep:Number = doteLineSize + gap;
 
        var iterations:int = vector.length / fullStep;
 
        var roulette:Number = 0
 
        for (var i:int = 0; i < iterations; i++)
        {
                graphics.moveTo(start.x + roulette * unitVector.x, start.y + roulette * unitVector.y);
                roulette += doteLineSize;
                graphics.lineTo(start.x + unitVector.x * roulette, start.y + unitVector.y * roulette);
                roulette += gap;
        }
 
        return graphics;
}


caseyryan 27.05.2014 14:12

Цитата:

Но эта разница достойна того, кто вообще не пользуется фраймворками
То есть мазохиста :D

ChuwY 27.05.2014 14:23

А вообще, если не хочется придумывать велосипед, есть совершенно замечательно решение.

PrincessRoma 27.05.2014 18:38

Огромное всем спасибо, очень помогли )) В итоге воспользовался решением от LifeIsRhythm. :)


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

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