Как нарисовать «волнистую линию» с помощью курсора / мыши - PullRequest
2 голосов
/ 10 декабря 2011

Клиент попросил меня нарисовать волнистую линию курсором / мышью, например:

Волнистая линия http://www.endeavoursportsgroup.com/images/WavyLine.png

У меня есть следующий код, который рисует линию курсором / мышью, но я застрял на том, как сделать линию "волнистой". Это на самом деле модифицированный код, нарисованный пунктирной линией, над которой я работал ранее, так что может быть какой-то оставшийся код из того, который я удалю позже.

Может ли кто-нибудь помочь мне достичь Волнистой линии, которую меня попросили создать с помощью приведенного ниже кода, или предложить другой способ достижения этой цели?

Заранее спасибо!

package
{
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.net.FileReference;
import flash.utils.ByteArray;

import mx.core.UIComponent;
import mx.events.FlexEvent;
import mx.graphics.codec.PNGEncoder;

public class DrawingArea extends UIComponent
{
    private var isDrawing:Boolean = false;
    private var x1:int;
    private var y1:int;
    private var x2:int;
    private var y2:int;
    private var LastX:int = 0;
    private var LastY:int = 0;

    public var drawColor:uint = 0x0000FF;

    public function DrawingArea()
    {
        super();

        var p1:Point = new Point();
        var p2:Point = new Point();

        p1.x = 0;
        p1.y = 0;
        p2.x = 200;
        p2.y = 200;

        addEventListener(FlexEvent.CREATION_COMPLETE, function(event:FlexEvent):void {
            graphics.clear();

            graphics.beginFill(0xffffff, 0.00001);
            graphics.drawRect(0, 0, width, height);
            graphics.endFill();
        });

        addEventListener( MouseEvent.MOUSE_DOWN, mouseDown );
        addEventListener( MouseEvent.MOUSE_MOVE, mouseMove );
        addEventListener( MouseEvent.MOUSE_UP, mouseUp);
    }
    private function mouseDown(event:MouseEvent):void {
        x1 = mouseX;
        y1 = mouseY;
        isDrawing = true;
    }
    private function mouseMove(event:MouseEvent):void {
        if (!event.buttonDown)
        {
            isDrawing = false;
        }

        x2 = mouseX;
        y2 = mouseY;
        if (isDrawing )
        {
            var p1:Point = new Point();
            var p2:Point = new Point();
            p1.x = x1;
            p1.y = y1;
            p2.x = x2;
            p2.y = y2;

            graphics.lineStyle(2,0x00FF00,2);
            graphics.lineStyle(1, drawColor);
            graphics.moveTo(x1, y1);
            graphics.lineTo(x2, y2);
            x1 = x2;
            y1 = y2;
            LastX = x2;
            LastY = y2;
        }
    }
    private function mouseUp(event:MouseEvent):void {
        isDrawing = false;
    }
}
}

Ответы [ 3 ]

1 голос
/ 12 декабря 2011

Пожалуйста, попробуйте следующий код. Это не идеально, но, вероятно, может дать вам некоторое представление.

package
{
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Point;

    public class CurvedLineTest extends Sprite
    {
        private static const DRAW_STEP:Number = 2;

        private var curveWidth:Number;
        private var curvePeriod:Number;
        private var smoothing:Number;

        private var prevPos:Point = new Point();
        private var curveLength:Number;
        private var smoothedN:Point = new Point();

        public function CurvedLineTest(curveWidth:Number = 10, curvePeriod:Number = 15, smoothFactor:Number = 80)
        {
            this.curveWidth = curveWidth;
            this.curvePeriod = curvePeriod;
            this.smoothing = Math.min(Math.max(smoothFactor, 0), 100) / 100;

            if( stage )
            {
                onAddedToStage();
            }
            else addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);

            // test: simulating fast mouse movements
            moveToPoint(10, 10);
            drawToPoint(15, 15);
            drawToPoint(35, 35);
            drawToPoint(60, 90);
            drawToPoint(150, 190);
            drawToPoint(350, 300);
        }

        private function onAddedToStage(e:Event = null):void
        {
            removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
            stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
            stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
            addEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage);
        }

        private function onRemovedFromStage(e:Event):void
        {
            removeEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage);
            stage.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
            stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
            addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
        }

        private function onMouseDown(e:MouseEvent):void
        {
            moveToPoint(mouseX, mouseY);
            stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
        }

        private function onMouseMove(e:MouseEvent):void
        {
            drawToPoint(mouseX, mouseY);
            e.updateAfterEvent();
        }

        private function moveToPoint(x:Number, y:Number):void
        {
            prevPos.x = x;
            prevPos.y = y;
            curveLength = 0;
            graphics.moveTo(x, y);
        }

        private function drawToPoint(x:Number, y:Number):void
        {
            // displacement vector
            var d:Point = new Point(x - prevPos.x, y - prevPos.y);

            // length of displacement vector
            var dl:Number = Math.sqrt(d.x * d.x + d.y * d.y);

            // normalized displacement vector
            var nd:Point = new Point(d.x / dl, d.y / dl);

            // normal to the displacement vector
            var cn:Point = normal(nd);

            var currentDl:Number = DRAW_STEP;
            while( currentDl <= dl )
            {
                // incrementing base curve length by the length of the step displacement
                curveLength += DRAW_STEP;

                // base curve coords of the current step
                var stepX:Number = prevPos.x + nd.x * DRAW_STEP;
                var stepY:Number = prevPos.y + nd.y * DRAW_STEP;

                // smoothing the normal to prevent ragged lines
                smoothedN.x = smoothing * smoothedN.x + (1 - smoothing) * cn.x;
                smoothedN.y = smoothing * smoothedN.y + (1 - smoothing) * cn.y;

                // wave form
                var wave:Number = curveWidth * Math.sin(Math.PI * curveLength / curvePeriod);

                // adding normal component to the current point of base curve
                var wavedX:Number = stepX + wave * smoothedN.x;
                var wavedY:Number = stepY + wave * smoothedN.y;

                // drawing waved curve
                graphics.lineStyle(1.5, 0);
                graphics.lineTo(wavedX, wavedY);

                // drawing base curve
                graphics.lineStyle(0, 0xBB2233, 0.5);
                graphics.moveTo(prevPos.x, prevPos.y);
                graphics.lineTo(stepX, stepY);

                // drawing normal
                graphics.lineStyle(0, 0x3322BB, 0.2);
                graphics.moveTo(prevPos.x, prevPos.y);
                graphics.lineTo(stepX + wave * smoothedN.x, stepY + wave * smoothedN.y);

                graphics.moveTo(wavedX, wavedY);

                // remembering current base curve point
                prevPos.x = stepX;
                prevPos.y = stepY;

                currentDl += DRAW_STEP;
            }
        }

        /**
         * Calculates normal to the given vector (in clockwise direction).
         */
        private function normal(vec:Point):Point
        {
            var d:Number = Math.sqrt(vec.x * vec.x + vec.y * vec.y);
            return new Point(-vec.y / d, vec.x / d);
        }

        private function onMouseUp(e:MouseEvent):void
        {
            graphics.clear();
            stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
        }
    }
}
0 голосов
/ 10 декабря 2011

Другой возможностью будет spark.Path и шаблон с использованием QuadraticBezier. Я полагаю, что документация дает довольно подробное объяснение и примеры.

0 голосов
/ 10 декабря 2011

Это кривая греха (или коса). Изменение вашего MouseMove на это должно исправить это. Я предполагаю, что переменные Points и «Last» были старыми. Это должно сместить координату Y вверх или вниз в зависимости от того, где вы находитесь на кривой, используя координату x в качестве угла в радианах.

    private function mouseMove(event:MouseEvent):void {
    if (!event.buttonDown)
    {
        isDrawing = false;
    }

    x2 = mouseX;
    y2 = mouseY;
    if (isDrawing )
    {
        //var p1:Point = new Point();
       // var p2:Point = new Point();
       // p1.x = x1;
       // p1.y = y1;
       // p2.x = x2;
       // p2.y = y2;

    y2 = Math.Sin(x2)+y2*(HeightOfThe Curve)
        graphics.lineStyle(2,0x00FF00,2);
        graphics.lineStyle(1, drawColor);
        graphics.moveTo(x1, y1);
        graphics.lineTo(x2, y2);
        x1 = x2;
        y1 = y2;
        //LastX = x2;
       // LastY = y2;
    }
}

Отрицательные значения должны учитываться автоматически.

Опять же, я понятия не имею, как заставить его работать на изогнутой линии. Он будет работать нормально, но будет выглядеть весело, пока вы не вернетесь к горизонтальному (или, по крайней мере, в основном горизонтальному) движению.

Сейчас я не могу проверить это самостоятельно, но думаю, что это все, что вам нужно сделать, если вы уже знаете, как провести прямую линию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...